64 lines
1.9 KiB
Go
64 lines
1.9 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
"github.com/cosmos/cosmos-sdk/types/tx"
|
|
)
|
|
|
|
var _ tx.Handler = txPriorityHandler{}
|
|
|
|
type txPriorityHandler struct {
|
|
next tx.Handler
|
|
}
|
|
|
|
// TxPriorityMiddleware implements tx handling middleware that determines a
|
|
// transaction's priority via a naive mechanism -- the total sum of fees provided.
|
|
// It sets the Priority in ResponseCheckTx only.
|
|
func TxPriorityMiddleware(txh tx.Handler) tx.Handler {
|
|
return txPriorityHandler{next: txh}
|
|
}
|
|
|
|
// CheckTx implements tx.Handler.CheckTx. We set the Priority of the transaction
|
|
// to be ordered in the Tendermint mempool based naively on the total sum of all
|
|
// fees included. Applications that need more sophisticated mempool ordering
|
|
// should look to implement their own fee handling middleware instead of using
|
|
// TxPriorityHandler.
|
|
func (h txPriorityHandler) CheckTx(ctx context.Context, req tx.Request, checkReq tx.RequestCheckTx) (tx.Response, tx.ResponseCheckTx, error) {
|
|
feeTx, ok := req.Tx.(sdk.FeeTx)
|
|
if !ok {
|
|
return tx.Response{}, tx.ResponseCheckTx{}, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
|
|
}
|
|
|
|
feeCoins := feeTx.GetFee()
|
|
|
|
res, checkRes, err := h.next.CheckTx(ctx, req, checkReq)
|
|
checkRes.Priority = GetTxPriority(feeCoins)
|
|
|
|
return res, checkRes, err
|
|
}
|
|
|
|
func (h txPriorityHandler) DeliverTx(ctx context.Context, req tx.Request) (tx.Response, error) {
|
|
return h.next.DeliverTx(ctx, req)
|
|
}
|
|
|
|
func (h txPriorityHandler) SimulateTx(ctx context.Context, req tx.Request) (tx.Response, error) {
|
|
return h.next.SimulateTx(ctx, req)
|
|
}
|
|
|
|
// GetTxPriority returns a naive tx priority based on the amount of the smallest denomination of the fee
|
|
// provided in a transaction.
|
|
func GetTxPriority(fee sdk.Coins) int64 {
|
|
var priority int64
|
|
for _, c := range fee {
|
|
p := c.Amount.Int64()
|
|
if priority == 0 || p < priority {
|
|
priority = p
|
|
}
|
|
}
|
|
|
|
return priority
|
|
}
|