From d475ea5fd7b718476d1a9fa66fb1f3c0bfb2ad02 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Mon, 11 Mar 2024 16:16:54 +0800 Subject: [PATCH 1/2] Problem: native fee handler don't respect DefaultPriorityReduction Solution: - vendor fee deduct decorator - a little refactor to remove `DeductTxCostsFromUserBalance` and call the DeductFees directly next: will modify the DeductFees to provide a different impl for parallel exec Apply suggestions from code review Signed-off-by: yihuang fixes fix err --- app/ante/ante_test.go | 6 +- app/ante/eip712.go | 2 +- app/ante/eth.go | 32 +++++--- app/ante/eth_test.go | 12 +-- app/ante/fee_checker.go | 11 ++- app/ante/fee_market_test.go | 2 +- app/ante/fees_test.go | 6 +- app/ante/handler_options.go | 4 +- app/ante/interfaces.go | 2 - app/ante/nativefee.go | 135 +++++++++++++++++++++++++++++++++ app/ante/setup_test.go | 4 +- app/ante/signverify_test.go | 2 +- app/ante/sigs_test.go | 2 +- testutil/base_test_suite.go | 14 ++-- x/evm/handler_test.go | 9 ++- x/evm/keeper/benchmark_test.go | 6 +- x/evm/keeper/utils.go | 22 ------ x/evm/keeper/utils_test.go | 8 +- 18 files changed, 210 insertions(+), 69 deletions(-) create mode 100644 app/ante/nativefee.go diff --git a/app/ante/ante_test.go b/app/ante/ante_test.go index cd2740f2bd..4aa20a9634 100644 --- a/app/ante/ante_test.go +++ b/app/ante/ante_test.go @@ -56,7 +56,7 @@ func TestAnteTestSuite(t *testing.T) { }) } -func (suite AnteTestSuite) TestAnteHandler() { +func (suite *AnteTestSuite) TestAnteHandler() { var acc authtypes.AccountI addr, privKey := tests.NewAddrKey() to := tests.GenerateAddress() @@ -952,7 +952,7 @@ func (suite AnteTestSuite) TestAnteHandler() { } } -func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { +func (suite *AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { addr, privKey := tests.NewAddrKey() to := tests.GenerateAddress() @@ -1219,7 +1219,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { suite.enableLondonHF = true } -func (suite AnteTestSuite) TestAnteHandlerWithParams() { +func (suite *AnteTestSuite) TestAnteHandlerWithParams() { addr, privKey := tests.NewAddrKey() to := tests.GenerateAddress() diff --git a/app/ante/eip712.go b/app/ante/eip712.go index 7c384ec804..8ea3aa7447 100644 --- a/app/ante/eip712.go +++ b/app/ante/eip712.go @@ -66,7 +66,7 @@ func NewLegacyCosmosAnteHandlerEip712(ctx sdk.Context, options HandlerOptions, e NewMinGasPriceDecorator(options.FeeMarketKeeper, evmDenom), authante.NewValidateMemoDecorator(options.AccountKeeper), authante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), - authante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), + NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), // SetPubKeyDecorator must be called before all signature verification decorators authante.NewSetPubKeyDecorator(options.AccountKeeper), authante.NewValidateSigCountDecorator(options.AccountKeeper), diff --git a/app/ante/eth.go b/app/ante/eth.go index dfa8dc9347..eb8fd57ed4 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -24,6 +24,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ethermint "github.com/evmos/ethermint/types" "github.com/evmos/ethermint/x/evm/keeper" @@ -105,23 +108,26 @@ func (avd EthAccountVerificationDecorator) AnteHandle( // EthGasConsumeDecorator validates enough intrinsic gas for the transaction and // gas consumption. type EthGasConsumeDecorator struct { - evmKeeper EVMKeeper - maxGasWanted uint64 - ethCfg *params.ChainConfig - evmDenom string - baseFee *big.Int + accountKeeper authante.AccountKeeper + bankKeeper authtypes.BankKeeper + maxGasWanted uint64 + ethCfg *params.ChainConfig + evmDenom string + baseFee *big.Int } // NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator func NewEthGasConsumeDecorator( - evmKeeper EVMKeeper, + accountKeeper authante.AccountKeeper, + bankKeeper authtypes.BankKeeper, maxGasWanted uint64, ethCfg *params.ChainConfig, evmDenom string, baseFee *big.Int, ) EthGasConsumeDecorator { return EthGasConsumeDecorator{ - evmKeeper, + accountKeeper, + bankKeeper, maxGasWanted, ethCfg, evmDenom, @@ -195,9 +201,15 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula return ctx, errorsmod.Wrapf(err, "failed to verify the fees") } - err = egcd.evmKeeper.DeductTxCostsFromUserBalance(ctx, fees, common.BytesToAddress(msgEthTx.From)) - if err != nil { - return ctx, errorsmod.Wrapf(err, "failed to deduct transaction costs from user balance") + // fetch sender account + acc := egcd.accountKeeper.GetAccount(ctx, msgEthTx.From) + if acc == nil { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", common.BytesToAddress(msgEthTx.From)) + } + + // deduct the full gas cost from the user balance + if err := DeductFees(egcd.bankKeeper, ctx, acc, fees); err != nil { + return ctx, errorsmod.Wrapf(err, "failed to deduct full gas cost %s from the user %s balance", fees, msgEthTx.From) } events = append(events, diff --git a/app/ante/eth_test.go b/app/ante/eth_test.go index 1c87e34ad8..0db8882215 100644 --- a/app/ante/eth_test.go +++ b/app/ante/eth_test.go @@ -16,7 +16,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" ) -func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() { +func (suite *AnteTestSuite) TestNewEthAccountVerificationDecorator() { dec := ante.NewEthAccountVerificationDecorator( suite.app.AccountKeeper, suite.app.EvmKeeper, evmtypes.DefaultEVMDenom, ) @@ -104,7 +104,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() { } } -func (suite AnteTestSuite) TestEthNonceVerificationDecorator() { +func (suite *AnteTestSuite) TestEthNonceVerificationDecorator() { suite.SetupTest() dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper) @@ -160,13 +160,13 @@ func (suite AnteTestSuite) TestEthNonceVerificationDecorator() { } } -func (suite AnteTestSuite) TestEthGasConsumeDecorator() { +func (suite *AnteTestSuite) TestEthGasConsumeDecorator() { evmParams := suite.app.EvmKeeper.GetParams(suite.ctx) chainID := suite.app.EvmKeeper.ChainID() chainCfg := evmParams.GetChainConfig() ethCfg := chainCfg.EthereumConfig(chainID) baseFee := suite.app.EvmKeeper.GetBaseFee(suite.ctx, ethCfg) - dec := ante.NewEthGasConsumeDecorator(suite.app.EvmKeeper, config.DefaultMaxTxGasWanted, ethCfg, evmtypes.DefaultEVMDenom, baseFee) + dec := ante.NewEthGasConsumeDecorator(suite.app.AccountKeeper, suite.app.BankKeeper, config.DefaultMaxTxGasWanted, ethCfg, evmtypes.DefaultEVMDenom, baseFee) addr := tests.GenerateAddress() @@ -319,7 +319,7 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() { } } -func (suite AnteTestSuite) TestCanTransferDecorator() { +func (suite *AnteTestSuite) TestCanTransferDecorator() { addr, privKey := tests.NewAddrKey() suite.app.FeeMarketKeeper.SetBaseFee(suite.ctx, big.NewInt(100)) @@ -407,7 +407,7 @@ func (suite AnteTestSuite) TestCanTransferDecorator() { } } -func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() { +func (suite *AnteTestSuite) TestEthIncrementSenderSequenceDecorator() { dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper) addr, privKey := tests.NewAddrKey() diff --git a/app/ante/fee_checker.go b/app/ante/fee_checker.go index facea2a8cb..f24249a31f 100644 --- a/app/ante/fee_checker.go +++ b/app/ante/fee_checker.go @@ -111,9 +111,14 @@ func NewDynamicFeeChecker(k DynamicFeeEVMKeeper) authante.TxFeeChecker { // checkTxFeeWithValidatorMinGasPrices implements the default fee logic, where the minimum price per // unit of gas is fixed and set by each validator, and the tx priority is computed from the gas price. -func checkTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.FeeTx) (sdk.Coins, int64, error) { - feeCoins := tx.GetFee() - gas := tx.GetGas() +func checkTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) { + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return nil, 0, errorsmod.Wrap(errortypes.ErrTxDecode, "Tx must be a FeeTx") + } + + feeCoins := feeTx.GetFee() + gas := feeTx.GetGas() minGasPrices := ctx.MinGasPrices() // Ensure that the provided fees meet a minimum threshold for the validator, diff --git a/app/ante/fee_market_test.go b/app/ante/fee_market_test.go index 95eafdb51c..8554e665ea 100644 --- a/app/ante/fee_market_test.go +++ b/app/ante/fee_market_test.go @@ -12,7 +12,7 @@ import ( evmtypes "github.com/evmos/ethermint/x/evm/types" ) -func (suite AnteTestSuite) TestGasWantedDecorator() { +func (suite *AnteTestSuite) TestGasWantedDecorator() { suite.enableFeemarket = true suite.SetupTest() diff --git a/app/ante/fees_test.go b/app/ante/fees_test.go index 3f62737ee2..c505dd866b 100644 --- a/app/ante/fees_test.go +++ b/app/ante/fees_test.go @@ -21,7 +21,7 @@ var execTypes = []struct { {"deliverTxSimulate", false, true}, } -func (s AnteTestSuite) TestMinGasPriceDecorator() { +func (s *AnteTestSuite) TestMinGasPriceDecorator() { denom := evmtypes.DefaultEVMDenom testMsg := banktypes.MsgSend{ FromAddress: "evmos1x8fhpj9nmhqk8z9kpgjt95ck2xwyue0ptzkucp", @@ -136,7 +136,7 @@ func (s AnteTestSuite) TestMinGasPriceDecorator() { } } -func (s AnteTestSuite) TestEthMinGasPriceDecorator() { +func (s *AnteTestSuite) TestEthMinGasPriceDecorator() { denom := evmtypes.DefaultEVMDenom from, privKey := tests.NewAddrKey() to := tests.GenerateAddress() @@ -354,6 +354,6 @@ func (s AnteTestSuite) TestEthMinGasPriceDecorator() { } } -func (suite AnteTestSuite) TestEthMempoolFeeDecorator() { +func (suite *AnteTestSuite) TestEthMempoolFeeDecorator() { // TODO: add test } diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 47e8cb62ae..d0d4a78af7 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -82,7 +82,7 @@ func newEthAnteHandler(ctx sdk.Context, options HandlerOptions, extra ...sdk.Ant NewEthSigVerificationDecorator(chainID), NewEthAccountVerificationDecorator(options.AccountKeeper, options.EvmKeeper, evmDenom), NewCanTransferDecorator(options.EvmKeeper, baseFee, &evmParams, ethCfg), - NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted, ethCfg, evmDenom, baseFee), + NewEthGasConsumeDecorator(options.AccountKeeper, options.BankKeeper, options.MaxTxGasWanted, ethCfg, evmDenom, baseFee), NewEthIncrementSenderSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator. NewGasWantedDecorator(options.FeeMarketKeeper, ethCfg), NewEthEmitEventDecorator(options.EvmKeeper), // emit eth tx hash and index at the very last ante handler. @@ -108,7 +108,7 @@ func newCosmosAnteHandler(ctx sdk.Context, options HandlerOptions, extra ...sdk. NewMinGasPriceDecorator(options.FeeMarketKeeper, evmDenom), ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), - ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), + NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewSetPubKeyDecorator(options.AccountKeeper), ante.NewValidateSigCountDecorator(options.AccountKeeper), diff --git a/app/ante/interfaces.go b/app/ante/interfaces.go index dc0c73cffa..9355cdd7fc 100644 --- a/app/ante/interfaces.go +++ b/app/ante/interfaces.go @@ -21,7 +21,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" tx "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" "github.com/evmos/ethermint/x/evm/statedb" evmtypes "github.com/evmos/ethermint/x/evm/types" @@ -40,7 +39,6 @@ type EVMKeeper interface { statedb.Keeper DynamicFeeEVMKeeper - DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error ResetTransientGasUsed(ctx sdk.Context) GetTxIndexTransient(ctx sdk.Context) uint64 } diff --git a/app/ante/nativefee.go b/app/ante/nativefee.go new file mode 100644 index 0000000000..7f11cf273f --- /dev/null +++ b/app/ante/nativefee.go @@ -0,0 +1,135 @@ +package ante + +import ( + "fmt" + + "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// DeductFeeDecorator deducts fees from the fee payer. The fee payer is the fee granter (if specified) or first signer of the tx. +// If the fee payer does not have the funds to pay for the fees, return an InsufficientFunds error. +// Call next AnteHandler if fees successfully deducted. +// CONTRACT: Tx must implement FeeTx interface to use DeductFeeDecorator +type DeductFeeDecorator struct { + accountKeeper ante.AccountKeeper + bankKeeper types.BankKeeper + feegrantKeeper ante.FeegrantKeeper + txFeeChecker ante.TxFeeChecker +} + +func NewDeductFeeDecorator(ak ante.AccountKeeper, bk types.BankKeeper, fk ante.FeegrantKeeper, tfc ante.TxFeeChecker) DeductFeeDecorator { + if tfc == nil { + tfc = checkTxFeeWithValidatorMinGasPrices + } + + return DeductFeeDecorator{ + accountKeeper: ak, + bankKeeper: bk, + feegrantKeeper: fk, + txFeeChecker: tfc, + } +} + +func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return ctx, errors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + } + + if !simulate && ctx.BlockHeight() > 0 && feeTx.GetGas() == 0 { + return ctx, errors.Wrap(sdkerrors.ErrInvalidGasLimit, "must provide positive gas") + } + + var ( + priority int64 + err error + ) + + fee := feeTx.GetFee() + if !simulate { + fee, priority, err = dfd.txFeeChecker(ctx, tx) + if err != nil { + return ctx, err + } + } + if err := dfd.checkDeductFee(ctx, tx, fee); err != nil { + return ctx, err + } + + newCtx := ctx.WithPriority(priority) + + return next(newCtx, tx, simulate) +} + +func (dfd DeductFeeDecorator) checkDeductFee(ctx sdk.Context, sdkTx sdk.Tx, fee sdk.Coins) error { + feeTx, ok := sdkTx.(sdk.FeeTx) + if !ok { + return errors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + } + + if addr := dfd.accountKeeper.GetModuleAddress(types.FeeCollectorName); addr == nil { + return fmt.Errorf("fee collector module account (%s) has not been set", types.FeeCollectorName) + } + + feePayer := feeTx.FeePayer() + feeGranter := feeTx.FeeGranter() + deductFeesFrom := feePayer + + // if feegranter set deduct fee from feegranter account. + // this works with only when feegrant enabled. + if feeGranter != nil { + if dfd.feegrantKeeper == nil { + return sdkerrors.ErrInvalidRequest.Wrap("fee grants are not enabled") + } else if !feeGranter.Equals(feePayer) { + err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, fee, sdkTx.GetMsgs()) + if err != nil { + return errors.Wrapf(err, "%s does not allow to pay fees for %s", feeGranter, feePayer) + } + } + + deductFeesFrom = feeGranter + } + + deductFeesFromAcc := dfd.accountKeeper.GetAccount(ctx, deductFeesFrom) + if deductFeesFromAcc == nil { + return sdkerrors.ErrUnknownAddress.Wrapf("fee payer address: %s does not exist", deductFeesFrom) + } + + // deduct the fees + if !fee.IsZero() { + err := DeductFees(dfd.bankKeeper, ctx, deductFeesFromAcc, fee) + if err != nil { + return err + } + } + + events := sdk.Events{ + sdk.NewEvent( + sdk.EventTypeTx, + sdk.NewAttribute(sdk.AttributeKeyFee, fee.String()), + sdk.NewAttribute(sdk.AttributeKeyFeePayer, deductFeesFrom.String()), + ), + } + ctx.EventManager().EmitEvents(events) + + return nil +} + +// DeductFees deducts fees from the given account. +func DeductFees(bankKeeper types.BankKeeper, ctx sdk.Context, acc types.AccountI, fees sdk.Coins) error { + if !fees.IsValid() { + return errors.Wrapf(sdkerrors.ErrInsufficientFee, "invalid fee amount: %s", fees) + } + + err := bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), types.FeeCollectorName, fees) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error()) + } + + return nil +} diff --git a/app/ante/setup_test.go b/app/ante/setup_test.go index db17b13c59..99e3f36673 100644 --- a/app/ante/setup_test.go +++ b/app/ante/setup_test.go @@ -11,7 +11,7 @@ import ( evmtypes "github.com/evmos/ethermint/x/evm/types" ) -func (suite AnteTestSuite) TestEthSetupContextDecorator() { +func (suite *AnteTestSuite) TestEthSetupContextDecorator() { dec := ante.NewEthSetUpContextDecorator(suite.app.EvmKeeper) tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) @@ -43,7 +43,7 @@ func (suite AnteTestSuite) TestEthSetupContextDecorator() { } } -func (suite AnteTestSuite) TestValidateBasicDecorator() { +func (suite *AnteTestSuite) TestValidateBasicDecorator() { addr, privKey := tests.NewAddrKey() signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) diff --git a/app/ante/signverify_test.go b/app/ante/signverify_test.go index 8c29ac8a6f..6306c24048 100644 --- a/app/ante/signverify_test.go +++ b/app/ante/signverify_test.go @@ -10,7 +10,7 @@ import ( evmtypes "github.com/evmos/ethermint/x/evm/types" ) -func (suite AnteTestSuite) TestEthSigVerificationDecorator() { +func (suite *AnteTestSuite) TestEthSigVerificationDecorator() { addr, privKey := tests.NewAddrKey() signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) diff --git a/app/ante/sigs_test.go b/app/ante/sigs_test.go index 3a1ff19649..83a5aa6ea7 100644 --- a/app/ante/sigs_test.go +++ b/app/ante/sigs_test.go @@ -8,7 +8,7 @@ import ( evmtypes "github.com/evmos/ethermint/x/evm/types" ) -func (suite AnteTestSuite) TestSignatures() { +func (suite *AnteTestSuite) TestSignatures() { suite.enableFeemarket = false suite.SetupTest() // reset diff --git a/testutil/base_test_suite.go b/testutil/base_test_suite.go index cf940daebc..42ca595daf 100644 --- a/testutil/base_test_suite.go +++ b/testutil/base_test_suite.go @@ -59,7 +59,7 @@ func (suite *BaseTestSuite) SetupTestWithCbAndOpts( ) { checkTx := false suite.App = app.SetupWithOpts(checkTx, patch, appOptions) - suite.Ctx = suite.App.BaseApp.NewContext(checkTx, tmproto.Header{ + suite.Ctx = suite.App.NewContext(checkTx, tmproto.Header{ Height: 1, ChainID: app.ChainID, Time: time.Now().UTC(), @@ -207,11 +207,11 @@ func (suite *BaseTestSuiteWithAccount) PrepareEthTx(msgEthereumTx *types.MsgEthe } func (suite *BaseTestSuiteWithAccount) CheckTx(tx []byte) abci.ResponseCheckTx { - return suite.App.BaseApp.CheckTx(abci.RequestCheckTx{Tx: tx}) + return suite.App.CheckTx(abci.RequestCheckTx{Tx: tx}) } func (suite *BaseTestSuiteWithAccount) DeliverTx(tx []byte) abci.ResponseDeliverTx { - return suite.App.BaseApp.DeliverTx(abci.RequestDeliverTx{Tx: tx}) + return suite.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) } // Commit and begin new block @@ -223,7 +223,7 @@ func (suite *BaseTestSuiteWithAccount) Commit() { Header: header, }) // update ctx - suite.Ctx = suite.App.BaseApp.NewContext(false, header) + suite.Ctx = suite.App.NewContext(false, header) } type evmQueryClientTrait struct { @@ -260,7 +260,7 @@ func (suite *BaseTestSuiteWithFeeMarketQueryClient) SetupTestWithCb( patch func(*app.EthermintApp, app.GenesisState) app.GenesisState, ) { suite.BaseTestSuite.SetupTestWithCb(t, patch) - suite.feemarketQueryClientTrait.Setup(&suite.BaseTestSuite) + suite.Setup(&suite.BaseTestSuite) } type EVMTestSuiteWithAccountAndQueryClient struct { @@ -277,7 +277,7 @@ func (suite *EVMTestSuiteWithAccountAndQueryClient) SetupTestWithCb( patch func(*app.EthermintApp, app.GenesisState) app.GenesisState, ) { suite.BaseTestSuiteWithAccount.SetupTestWithCb(t, patch) - suite.evmQueryClientTrait.Setup(&suite.BaseTestSuite) + suite.Setup(&suite.BaseTestSuite) } // DeployTestContract deploy a test erc20 contract and returns the contract address @@ -376,5 +376,5 @@ func (suite *FeeMarketTestSuiteWithAccountAndQueryClient) SetupTestWithCb( err = suite.App.StakingKeeper.SetValidatorByConsAddr(suite.Ctx, validator) require.NoError(t, err) suite.App.StakingKeeper.SetValidator(suite.Ctx, validator) - suite.feemarketQueryClientTrait.Setup(&suite.BaseTestSuite) + suite.Setup(&suite.BaseTestSuite) } diff --git a/x/evm/handler_test.go b/x/evm/handler_test.go index 1e9da1b20d..d424ef7dc5 100644 --- a/x/evm/handler_test.go +++ b/x/evm/handler_test.go @@ -24,6 +24,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/evmos/ethermint/app" + "github.com/evmos/ethermint/app/ante" ethermint "github.com/evmos/ethermint/types" "github.com/evmos/ethermint/x/evm" "github.com/evmos/ethermint/x/evm/types" @@ -500,7 +501,13 @@ func (suite *HandlerTestSuite) TestERC20TransferReverted() { suite.Require().NoError(err) fees, err := keeper.VerifyFee(txData, "aphoton", baseFee, true, true, true, suite.Ctx.IsCheckTx()) suite.Require().NoError(err) - err = k.DeductTxCostsFromUserBalance(suite.Ctx, fees, tx.GetSender()) + + // fetch sender account + signerAcc := suite.App.AccountKeeper.GetAccount(suite.Ctx, tx.GetSender().Bytes()) + suite.Require().NotNil(signerAcc) + + // deduct the full gas cost from the user balance + err = ante.DeductFees(suite.App.BankKeeper, suite.Ctx, signerAcc, fees) suite.Require().NoError(err) res, err := k.EthereumTx(sdk.WrapSDKContext(suite.Ctx), tx) diff --git a/x/evm/keeper/benchmark_test.go b/x/evm/keeper/benchmark_test.go index a4c5bdd542..4098ba491b 100644 --- a/x/evm/keeper/benchmark_test.go +++ b/x/evm/keeper/benchmark_test.go @@ -9,12 +9,12 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - authante "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/evmos/ethermint/app/ante" "github.com/evmos/ethermint/server/config" "github.com/evmos/ethermint/testutil" ethermint "github.com/evmos/ethermint/types" @@ -115,7 +115,7 @@ func doBenchmark(b *testing.B, txBuilder TxBuilder) { require.NoError(b, err) fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdkmath.NewIntFromBigInt(txData.Fee()))} - err = authante.DeductFees(suite.App.BankKeeper, suite.Ctx, suite.App.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) + err = ante.DeductFees(suite.App.BankKeeper, suite.Ctx, suite.App.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) require.NoError(b, err) rsp, err := suite.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg) @@ -182,7 +182,7 @@ func BenchmarkMessageCall(b *testing.B) { require.NoError(b, err) fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdkmath.NewIntFromBigInt(txData.Fee()))} - err = authante.DeductFees(suite.App.BankKeeper, suite.Ctx, suite.App.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) + err = ante.DeductFees(suite.App.BankKeeper, suite.Ctx, suite.App.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) require.NoError(b, err) rsp, err := suite.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg) diff --git a/x/evm/keeper/utils.go b/x/evm/keeper/utils.go index d90bf7f8ad..dc173ca262 100644 --- a/x/evm/keeper/utils.go +++ b/x/evm/keeper/utils.go @@ -26,7 +26,6 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - authante "github.com/cosmos/cosmos-sdk/x/auth/ante" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/evmos/ethermint/x/evm/types" @@ -55,27 +54,6 @@ func GetProposerAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) sdk.Co return proposerAddress } -// DeductTxCostsFromUserBalance deducts the fees from the user balance. Returns an -// error if the specified sender address does not exist or the account balance is not sufficient. -func (k *Keeper) DeductTxCostsFromUserBalance( - ctx sdk.Context, - fees sdk.Coins, - from common.Address, -) error { - // fetch sender account - signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, from.Bytes()) - if err != nil { - return errorsmod.Wrapf(err, "account not found for sender %s", from) - } - - // deduct the full gas cost from the user balance - if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil { - return errorsmod.Wrapf(err, "failed to deduct full gas cost %s from the user %s balance", fees, from) - } - - return nil -} - // VerifyFee is used to return the fee for the given transaction data in sdk.Coins. It checks that the // gas limit is not reached, the gas limit is higher than the intrinsic gas and that the // base fee is higher than the gas fee cap. diff --git a/x/evm/keeper/utils_test.go b/x/evm/keeper/utils_test.go index 677a073af2..59d74ca986 100644 --- a/x/evm/keeper/utils_test.go +++ b/x/evm/keeper/utils_test.go @@ -10,6 +10,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" ethparams "github.com/ethereum/go-ethereum/params" "github.com/evmos/ethermint/app" + "github.com/evmos/ethermint/app/ante" "github.com/evmos/ethermint/testutil" "github.com/evmos/ethermint/x/evm/keeper" evmtypes "github.com/evmos/ethermint/x/evm/types" @@ -531,7 +532,12 @@ func (suite *UtilsTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { suite.Require().Nil(fees, "invalid test %d passed. fees value must be nil - '%s'", i, tc.name) } - err = suite.App.EvmKeeper.DeductTxCostsFromUserBalance(suite.Ctx, fees, common.BytesToAddress(tx.From)) + // fetch sender account + acc := suite.App.AccountKeeper.GetAccount(suite.Ctx, tx.From) + suite.Require().NotNil(acc, "account not found for sender %s", tx.From) + + // deduct the full gas cost from the user balance + err = ante.DeductFees(suite.App.BankKeeper, suite.Ctx, acc, fees) if tc.expectPassDeduct { suite.Require().NoError(err, "valid test %d failed - '%s'", i, tc.name) } else { From eb67fd54199f7a806534a0b3d8d6d72514788ee7 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Mon, 11 Mar 2024 16:32:59 +0800 Subject: [PATCH 2/2] fix lint --- app/ante/eth.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/ante/eth.go b/app/ante/eth.go index eb8fd57ed4..f85944c54d 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -24,7 +24,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -204,7 +203,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula // fetch sender account acc := egcd.accountKeeper.GetAccount(ctx, msgEthTx.From) if acc == nil { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", common.BytesToAddress(msgEthTx.From)) + return ctx, errorsmod.Wrapf(errortypes.ErrUnknownAddress, "account %s does not exist", common.BytesToAddress(msgEthTx.From)) } // deduct the full gas cost from the user balance