diff --git a/x/auth/middleware/fee.go b/x/auth/middleware/fee.go index 7285d530cfb..4d980fb059a 100644 --- a/x/auth/middleware/fee.go +++ b/x/auth/middleware/fee.go @@ -4,12 +4,12 @@ import ( "context" "fmt" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/x/auth/types" - abci "github.com/tendermint/tendermint/abci/types" ) var _ tx.Handler = mempoolFeeTxHandler{} @@ -30,7 +30,12 @@ func MempoolFeeMiddleware(txh tx.Handler) tx.Handler { } } -// CheckTx implements tx.Handler.CheckTx. +// CheckTx implements tx.Handler.CheckTx. It is responsible for determining if a +// transaction's fees meet the required minimum of the processing node. Note, a +// node can have zero fees set as the minimum. If non-zero minimum fees are set +// and the transaction does not meet the minimum, the transaction is rejected. +// +// Recall, a transaction's fee is determined by ceil(minGasPrice * gasLimit). func (txh mempoolFeeTxHandler) CheckTx(ctx context.Context, tx sdk.Tx, req abci.RequestCheckTx) (abci.ResponseCheckTx, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) diff --git a/x/auth/middleware/middleware.go b/x/auth/middleware/middleware.go index be8af217621..365d7441ed0 100644 --- a/x/auth/middleware/middleware.go +++ b/x/auth/middleware/middleware.go @@ -89,6 +89,7 @@ func NewDefaultTxHandler(options TxHandlerOptions) (tx.Handler, error) { ValidateMemoMiddleware(options.AccountKeeper), ConsumeTxSizeGasMiddleware(options.AccountKeeper), DeductFeeMiddleware(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + TxPriorityHandler, SetPubKeyMiddleware(options.AccountKeeper), ValidateSigCountMiddleware(options.AccountKeeper), SigGasConsumeMiddleware(options.AccountKeeper, sigGasConsumer), diff --git a/x/auth/middleware/tx_priority.go b/x/auth/middleware/tx_priority.go new file mode 100644 index 00000000000..81d8d3124e7 --- /dev/null +++ b/x/auth/middleware/tx_priority.go @@ -0,0 +1,62 @@ +package middleware + +import ( + "context" + + abci "github.com/tendermint/tendermint/abci/types" + + 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 +} + +// TxPriorityHandler 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 TxPriorityHandler(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, tx sdk.Tx, req abci.RequestCheckTx) (abci.ResponseCheckTx, error) { + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return abci.ResponseCheckTx{}, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + } + + feeCoins := feeTx.GetFee() + + res, err := h.next.CheckTx(ctx, tx, req) + res.Priority = GetTxPriority(feeCoins) + + return res, err +} + +func (h txPriorityHandler) DeliverTx(ctx context.Context, tx sdk.Tx, req abci.RequestDeliverTx) (abci.ResponseDeliverTx, error) { + return h.next.DeliverTx(ctx, tx, req) +} + +func (h txPriorityHandler) SimulateTx(ctx context.Context, sdkTx sdk.Tx, req tx.RequestSimulateTx) (tx.ResponseSimulateTx, error) { + return h.next.SimulateTx(ctx, sdkTx, req) +} + +// GetTxPriority returns a naive tx priority based on the total sum of all fees +// provided in a transaction. +func GetTxPriority(fee sdk.Coins) int64 { + var priority int64 + for _, c := range fee { + priority += c.Amount.Int64() + } + + return priority +}