@@ -21,10 +21,46 @@ type MinGasPriceDecorator struct {
2121 evmKeeper EVMKeeper
2222}
2323
24+ // EthMinGasPriceDecorator will check if the transaction's fee is at least as large
25+ // as the MinGasPrices param. If fee is too low, decorator returns error and tx
26+ // is rejected. This applies to both CheckTx and DeliverTx and regardless
27+ // if London hard fork or fee market params (EIP-1559) are enabled.
28+ // If fee is high enough, then call next AnteHandler
29+ type EthMinGasPriceDecorator struct {
30+ feesKeeper FeeMarketKeeper
31+ evmKeeper EVMKeeper
32+ }
33+
34+ // EthMempoolFeeDecorator will check if the transaction's effective fee is at least as large
35+ // as the local validator's minimum gasFee (defined in validator config).
36+ // If fee is too low, decorator returns error and tx is rejected from mempool.
37+ // Note this only applies when ctx.CheckTx = true
38+ // If fee is high enough or not CheckTx, then call next AnteHandler
39+ // CONTRACT: Tx must implement FeeTx to use MempoolFeeDecorator
40+ type EthMempoolFeeDecorator struct {
41+ evmKeeper EVMKeeper
42+ }
43+
44+ // NewMinGasPriceDecorator creates a new MinGasPriceDecorator instance used only for
45+ // Cosmos transactions.
2446func NewMinGasPriceDecorator (fk FeeMarketKeeper , ek EVMKeeper ) MinGasPriceDecorator {
2547 return MinGasPriceDecorator {feesKeeper : fk , evmKeeper : ek }
2648}
2749
50+ // NewEthMinGasPriceDecorator creates a new MinGasPriceDecorator instance used only for
51+ // Ethereum transactions.
52+ func NewEthMinGasPriceDecorator (fk FeeMarketKeeper , ek EVMKeeper ) EthMinGasPriceDecorator {
53+ return EthMinGasPriceDecorator {feesKeeper : fk , evmKeeper : ek }
54+ }
55+
56+ // NewEthMempoolFeeDecorator creates a new NewEthMempoolFeeDecorator instance used only for
57+ // Ethereum transactions.
58+ func NewEthMempoolFeeDecorator (ek EVMKeeper ) EthMempoolFeeDecorator {
59+ return EthMempoolFeeDecorator {
60+ evmKeeper : ek ,
61+ }
62+ }
63+
2864func (mpd MinGasPriceDecorator ) AnteHandle (ctx sdk.Context , tx sdk.Tx , simulate bool , next sdk.AnteHandler ) (newCtx sdk.Context , err error ) {
2965 feeTx , ok := tx .(sdk.FeeTx )
3066 if ! ok {
@@ -72,20 +108,8 @@ func (mpd MinGasPriceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
72108 return next (ctx , tx , simulate )
73109}
74110
75- // EthMinGasPriceDecorator will check if the transaction's fee is at least as large
76- // as the MinGasPrices param. If fee is too low, decorator returns error and tx
77- // is rejected. This applies to both CheckTx and DeliverTx and regardless
78- // if London hard fork or fee market params (EIP-1559) are enabled.
79- // If fee is high enough, then call next AnteHandler
80- type EthMinGasPriceDecorator struct {
81- feesKeeper FeeMarketKeeper
82- evmKeeper EVMKeeper
83- }
84-
85- func NewEthMinGasPriceDecorator (fk FeeMarketKeeper , ek EVMKeeper ) EthMinGasPriceDecorator {
86- return EthMinGasPriceDecorator {feesKeeper : fk , evmKeeper : ek }
87- }
88-
111+ // AnteHandle ensures that the that the effective fee from the transaction is greater than the
112+ // minimum global fee, which is defined by the MinGasPrice (parameter) * GasLimit (tx argument).
89113func (empd EthMinGasPriceDecorator ) AnteHandle (ctx sdk.Context , tx sdk.Tx , simulate bool , next sdk.AnteHandler ) (newCtx sdk.Context , err error ) {
90114 minGasPrice := empd .feesKeeper .GetParams (ctx ).MinGasPrice
91115
@@ -144,3 +168,44 @@ func (empd EthMinGasPriceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
144168
145169 return next (ctx , tx , simulate )
146170}
171+
172+ // AnteHandle ensures that the provided fees meet a minimum threshold for the validator.
173+ // This check only for local mempool purposes, and thus it is only run on (Re)CheckTx.
174+ // The logic is also skipped if the London hard fork and EIP-1559 are enabled.
175+ func (mfd EthMempoolFeeDecorator ) AnteHandle (ctx sdk.Context , tx sdk.Tx , simulate bool , next sdk.AnteHandler ) (newCtx sdk.Context , err error ) {
176+ if ! ctx .IsCheckTx () || simulate {
177+ return next (ctx , tx , simulate )
178+ }
179+ chainCfg := mfd .evmKeeper .GetChainConfig (ctx )
180+ ethCfg := chainCfg .EthereumConfig (mfd .evmKeeper .ChainID ())
181+
182+ baseFee := mfd .evmKeeper .GetBaseFee (ctx , ethCfg )
183+ // skip check as the London hard fork and EIP-1559 are enabled
184+ if baseFee != nil {
185+ return next (ctx , tx , simulate )
186+ }
187+
188+ evmDenom := mfd .evmKeeper .GetEVMDenom (ctx )
189+ minGasPrice := ctx .MinGasPrices ().AmountOf (evmDenom )
190+
191+ for _ , msg := range tx .GetMsgs () {
192+ ethMsg , ok := msg .(* evmtypes.MsgEthereumTx )
193+ if ! ok {
194+ return ctx , errorsmod .Wrapf (errortypes .ErrUnknownRequest , "invalid message type %T, expected %T" , msg , (* evmtypes .MsgEthereumTx )(nil ))
195+ }
196+
197+ fee := sdk .NewDecFromBigInt (ethMsg .GetFee ())
198+ gasLimit := sdk .NewDecFromBigInt (new (big.Int ).SetUint64 (ethMsg .GetGas ()))
199+ requiredFee := minGasPrice .Mul (gasLimit )
200+
201+ if fee .LT (requiredFee ) {
202+ return ctx , errorsmod .Wrapf (
203+ errortypes .ErrInsufficientFee ,
204+ "insufficient fees; got: %s required: %s" ,
205+ fee , requiredFee ,
206+ )
207+ }
208+ }
209+
210+ return next (ctx , tx , simulate )
211+ }
0 commit comments