forked from cerc-io/laconicd-deprecated
		
	tests: DynamicFeeTx (#649)
* test DynamicFeeTx against state_transition_benchmark_test * add feemarketGenesis in the app setup param * add dynamicTxFee flag to KeeperTestSuite * add feemarketGenesis.BaseFee setup * update TestAddLog * fix gasFeeCap assignment in newMsgEthereumTx * modify keeperTestSuite helper functions to support dynamicTxFee * update test cases in grpc_query_test w/ dynamicTxFee * update the evm keeper utils tests * add dynamic tx fee in the ante tests * remove duplicate type define * fix error return type * update changelog Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									2f531af3f2
								
							
						
					
					
						commit
						1076307e6b
					
				| @ -55,6 +55,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ | |||||||
| * (rpc, test) [tharsis#608](https://github.com/tharsis/ethermint/pull/608) Fix rpc test. | * (rpc, test) [tharsis#608](https://github.com/tharsis/ethermint/pull/608) Fix rpc test. | ||||||
| * (rpc) [tharsis#661](https://github.com/tharsis/ethermint/pull/661) Fix OOM bug when creating too many filters using JSON-RPC. | * (rpc) [tharsis#661](https://github.com/tharsis/ethermint/pull/661) Fix OOM bug when creating too many filters using JSON-RPC. | ||||||
| * (evm) [tharsis#660](https://github.com/tharsis/ethermint/pull/660) Fix `nil` pointer panic in `ApplyNativeMessage`. | * (evm) [tharsis#660](https://github.com/tharsis/ethermint/pull/660) Fix `nil` pointer panic in `ApplyNativeMessage`. | ||||||
|  | * (evm, test) [tharsis#649](https://github.com/tharsis/ethermint/pull/649) Test DynamicFeeTx. | ||||||
| 
 | 
 | ||||||
| ## [v0.7.0] - 2021-10-07 | ## [v0.7.0] - 2021-10-07 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,11 +6,16 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
|  | 	ethparams "github.com/ethereum/go-ethereum/params" | ||||||
| 	"github.com/tharsis/ethermint/tests" | 	"github.com/tharsis/ethermint/tests" | ||||||
| 	evmtypes "github.com/tharsis/ethermint/x/evm/types" | 	evmtypes "github.com/tharsis/ethermint/x/evm/types" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func (suite AnteTestSuite) TestAnteHandler() { | func (suite AnteTestSuite) TestAnteHandler() { | ||||||
|  | 	suite.dynamicTxFee = false | ||||||
|  | 	suite.SetupTest() // reset
 | ||||||
|  | 
 | ||||||
| 	addr, privKey := tests.NewAddrKey() | 	addr, privKey := tests.NewAddrKey() | ||||||
| 	to := tests.GenerateAddress() | 	to := tests.GenerateAddress() | ||||||
| 
 | 
 | ||||||
| @ -145,3 +150,242 @@ func (suite AnteTestSuite) TestAnteHandler() { | |||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { | ||||||
|  | 	suite.dynamicTxFee = true | ||||||
|  | 	suite.SetupTest() // reset
 | ||||||
|  | 
 | ||||||
|  | 	addr, privKey := tests.NewAddrKey() | ||||||
|  | 	to := tests.GenerateAddress() | ||||||
|  | 
 | ||||||
|  | 	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) | ||||||
|  | 	suite.Require().NoError(acc.SetSequence(1)) | ||||||
|  | 	suite.app.AccountKeeper.SetAccount(suite.ctx, acc) | ||||||
|  | 
 | ||||||
|  | 	suite.app.EvmKeeper.AddBalance(addr, big.NewInt((ethparams.InitialBaseFee+10)*100000)) | ||||||
|  | 
 | ||||||
|  | 	testCases := []struct { | ||||||
|  | 		name      string | ||||||
|  | 		txFn      func() sdk.Tx | ||||||
|  | 		checkTx   bool | ||||||
|  | 		reCheckTx bool | ||||||
|  | 		expPass   bool | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			"success - DeliverTx (contract)", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedContractTx := | ||||||
|  | 					evmtypes.NewTxContract( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						1, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedContractTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedContractTx, privKey, 1, true) | ||||||
|  | 				return tx | ||||||
|  | 			}, | ||||||
|  | 			false, false, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"success - CheckTx (contract)", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedContractTx := | ||||||
|  | 					evmtypes.NewTxContract( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						1, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedContractTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedContractTx, privKey, 1, true) | ||||||
|  | 				return tx | ||||||
|  | 			}, | ||||||
|  | 			true, false, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"success - ReCheckTx (contract)", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedContractTx := | ||||||
|  | 					evmtypes.NewTxContract( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						1, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedContractTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedContractTx, privKey, 1, true) | ||||||
|  | 				return tx | ||||||
|  | 			}, | ||||||
|  | 			false, true, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"success - DeliverTx", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedTx := | ||||||
|  | 					evmtypes.NewTx( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						1, | ||||||
|  | 						&to, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedTx, privKey, 1, true) | ||||||
|  | 				return tx | ||||||
|  | 			}, | ||||||
|  | 			false, false, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"success - CheckTx", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedTx := | ||||||
|  | 					evmtypes.NewTx( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						2, | ||||||
|  | 						&to, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedTx, privKey, 1, true) | ||||||
|  | 				return tx | ||||||
|  | 			}, | ||||||
|  | 			true, false, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"success - ReCheckTx", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedTx := | ||||||
|  | 					evmtypes.NewTx( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						3, | ||||||
|  | 						&to, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedTx, privKey, 1, true) | ||||||
|  | 				return tx | ||||||
|  | 			}, false, true, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"success - CheckTx (cosmos tx not signed)", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedTx := | ||||||
|  | 					evmtypes.NewTx( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						4, | ||||||
|  | 						&to, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				tx := suite.CreateTestTx(signedTx, privKey, 1, false) | ||||||
|  | 				return tx | ||||||
|  | 			}, false, true, true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"fail - CheckTx (cosmos tx is not valid)", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedTx := | ||||||
|  | 					evmtypes.NewTx( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						4, | ||||||
|  | 						&to, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) | ||||||
|  | 				// bigger than MaxGasWanted
 | ||||||
|  | 				txBuilder.SetGasLimit(uint64(1 << 63)) | ||||||
|  | 				return txBuilder.GetTx() | ||||||
|  | 			}, false, true, false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"fail - CheckTx (memo too long)", | ||||||
|  | 			func() sdk.Tx { | ||||||
|  | 				signedTx := | ||||||
|  | 					evmtypes.NewTx( | ||||||
|  | 						suite.app.EvmKeeper.ChainID(), | ||||||
|  | 						5, | ||||||
|  | 						&to, | ||||||
|  | 						big.NewInt(10), | ||||||
|  | 						100000, | ||||||
|  | 						nil, | ||||||
|  | 						big.NewInt(ethparams.InitialBaseFee+1), | ||||||
|  | 						big.NewInt(1), | ||||||
|  | 						nil, | ||||||
|  | 						&types.AccessList{}, | ||||||
|  | 					) | ||||||
|  | 				signedTx.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 				txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, true) | ||||||
|  | 				txBuilder.SetMemo(strings.Repeat("*", 257)) | ||||||
|  | 				return txBuilder.GetTx() | ||||||
|  | 			}, true, false, false, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tc := range testCases { | ||||||
|  | 		suite.Run(tc.name, func() { | ||||||
|  | 			suite.ctx = suite.ctx.WithIsCheckTx(tc.reCheckTx).WithIsReCheckTx(tc.reCheckTx) | ||||||
|  | 			_, err := suite.anteHandler(suite.ctx, tc.txFn(), false) | ||||||
|  | 			if tc.expPass { | ||||||
|  | 				suite.Require().NoError(err) | ||||||
|  | 			} else { | ||||||
|  | 				suite.Require().Error(err) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 	suite.dynamicTxFee = false | ||||||
|  | } | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ import ( | |||||||
| 	"github.com/tharsis/ethermint/encoding" | 	"github.com/tharsis/ethermint/encoding" | ||||||
| 	"github.com/tharsis/ethermint/tests" | 	"github.com/tharsis/ethermint/tests" | ||||||
| 	evmtypes "github.com/tharsis/ethermint/x/evm/types" | 	evmtypes "github.com/tharsis/ethermint/x/evm/types" | ||||||
|  | 	feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types" | ||||||
| 
 | 
 | ||||||
| 	tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | 	tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||||||
| ) | ) | ||||||
| @ -36,11 +37,23 @@ type AnteTestSuite struct { | |||||||
| 	clientCtx    client.Context | 	clientCtx    client.Context | ||||||
| 	anteHandler  sdk.AnteHandler | 	anteHandler  sdk.AnteHandler | ||||||
| 	ethSigner    ethtypes.Signer | 	ethSigner    ethtypes.Signer | ||||||
|  | 	dynamicTxFee bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *AnteTestSuite) SetupTest() { | func (suite *AnteTestSuite) SetupTest() { | ||||||
| 	checkTx := false | 	checkTx := false | ||||||
| 	suite.app = app.Setup(checkTx) | 
 | ||||||
|  | 	if suite.dynamicTxFee { | ||||||
|  | 		// setup feemarketGenesis params
 | ||||||
|  | 		feemarketGenesis := feemarkettypes.DefaultGenesisState() | ||||||
|  | 		feemarketGenesis.Params.EnableHeight = 1 | ||||||
|  | 		feemarketGenesis.Params.NoBaseFee = false | ||||||
|  | 		feemarketGenesis.BaseFee = sdk.NewInt(feemarketGenesis.Params.InitialBaseFee) | ||||||
|  | 		suite.app = app.Setup(checkTx, feemarketGenesis) | ||||||
|  | 	} else { | ||||||
|  | 		suite.app = app.Setup(checkTx, nil) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint_9000-1", Time: time.Now().UTC()}) | 	suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint_9000-1", Time: time.Now().UTC()}) | ||||||
| 	suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoin(evmtypes.DefaultEVMDenom, sdk.OneInt()))) | 	suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoin(evmtypes.DefaultEVMDenom, sdk.OneInt()))) | ||||||
| 	suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1000000000000000000)) | 	suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1000000000000000000)) | ||||||
|  | |||||||
| @ -12,6 +12,7 @@ import ( | |||||||
| 	tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | 	tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||||||
| 	tmtypes "github.com/tendermint/tendermint/types" | 	tmtypes "github.com/tendermint/tendermint/types" | ||||||
| 	dbm "github.com/tendermint/tm-db" | 	dbm "github.com/tendermint/tm-db" | ||||||
|  | 	feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // DefaultConsensusParams defines the default Tendermint consensus params used in
 | // DefaultConsensusParams defines the default Tendermint consensus params used in
 | ||||||
| @ -34,12 +35,22 @@ var DefaultConsensusParams = &abci.ConsensusParams{ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
 | // Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
 | ||||||
| func Setup(isCheckTx bool) *EthermintApp { | func Setup(isCheckTx bool, feemarketGenesis *feemarkettypes.GenesisState) *EthermintApp { | ||||||
| 	db := dbm.NewMemDB() | 	db := dbm.NewMemDB() | ||||||
| 	app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) | 	app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) | ||||||
| 	if !isCheckTx { | 	if !isCheckTx { | ||||||
| 		// init chain must be called to stop deliverState from being nil
 | 		// init chain must be called to stop deliverState from being nil
 | ||||||
| 		genesisState := NewDefaultGenesisState() | 		genesisState := NewDefaultGenesisState() | ||||||
|  | 
 | ||||||
|  | 		// Verify feeMarket genesis
 | ||||||
|  | 		if feemarketGenesis != nil { | ||||||
|  | 			if err := feemarketGenesis.Validate(); err != nil { | ||||||
|  | 				panic(err) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			genesisState[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		stateBytes, err := json.MarshalIndent(genesisState, "", " ") | 		stateBytes, err := json.MarshalIndent(genesisState, "", " ") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ import ( | |||||||
| 	"github.com/cosmos/cosmos-sdk/simapp" | 	"github.com/cosmos/cosmos-sdk/simapp" | ||||||
| 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||||||
| 	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" | 	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" | ||||||
|  | 	feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types" | ||||||
| 
 | 
 | ||||||
| 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
| @ -53,6 +54,8 @@ type EvmTestSuite struct { | |||||||
| 	ethSigner ethtypes.Signer | 	ethSigner ethtypes.Signer | ||||||
| 	from      common.Address | 	from      common.Address | ||||||
| 	to        sdk.AccAddress | 	to        sdk.AccAddress | ||||||
|  | 
 | ||||||
|  | 	dynamicTxFee bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// DoSetupTest setup test environment, it uses`require.TestingT` to support both `testing.T` and `testing.B`.
 | /// DoSetupTest setup test environment, it uses`require.TestingT` to support both `testing.T` and `testing.B`.
 | ||||||
| @ -70,7 +73,15 @@ func (suite *EvmTestSuite) DoSetupTest(t require.TestingT) { | |||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 	consAddress := sdk.ConsAddress(priv.PubKey().Address()) | 	consAddress := sdk.ConsAddress(priv.PubKey().Address()) | ||||||
| 
 | 
 | ||||||
| 	suite.app = app.Setup(checkTx) | 	if suite.dynamicTxFee { | ||||||
|  | 		feemarketGenesis := feemarkettypes.DefaultGenesisState() | ||||||
|  | 		feemarketGenesis.Params.EnableHeight = 1 | ||||||
|  | 		feemarketGenesis.Params.NoBaseFee = false | ||||||
|  | 		suite.app = app.Setup(checkTx, feemarketGenesis) | ||||||
|  | 	} else { | ||||||
|  | 		suite.app = app.Setup(checkTx, nil) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	coins := sdk.NewCoins(sdk.NewCoin(types.DefaultEVMDenom, sdk.NewInt(100000000000000))) | 	coins := sdk.NewCoins(sdk.NewCoin(types.DefaultEVMDenom, sdk.NewInt(100000000000000))) | ||||||
| 	genesisState := app.ModuleBasics.DefaultGenesis(suite.app.AppCodec()) | 	genesisState := app.ModuleBasics.DefaultGenesis(suite.app.AppCodec()) | ||||||
| 	b32address := sdk.MustBech32ifyAddressBytes(sdk.GetConfig().GetBech32AccountAddrPrefix(), priv.PubKey().Address().Bytes()) | 	b32address := sdk.MustBech32ifyAddressBytes(sdk.GetConfig().GetBech32AccountAddrPrefix(), priv.PubKey().Address().Bytes()) | ||||||
|  | |||||||
| @ -489,28 +489,29 @@ func (suite *KeeperTestSuite) TestEstimateGas() { | |||||||
| 		malleate     func() | 		malleate     func() | ||||||
| 		expPass      bool | 		expPass      bool | ||||||
| 		expGas       uint64 | 		expGas       uint64 | ||||||
|  | 		dynamicTxFee bool | ||||||
| 	}{ | 	}{ | ||||||
| 		// should success, because transfer value is zero
 | 		// should success, because transfer value is zero
 | ||||||
| 		{"default args", func() { | 		{"default args", func() { | ||||||
| 			args = types.TransactionArgs{To: &common.Address{}} | 			args = types.TransactionArgs{To: &common.Address{}} | ||||||
| 		}, true, 21000}, | 		}, true, 21000, false}, | ||||||
| 		// should fail, because the default From address(zero address) don't have fund
 | 		// should fail, because the default From address(zero address) don't have fund
 | ||||||
| 		{"not enough balance", func() { | 		{"not enough balance", func() { | ||||||
| 			args = types.TransactionArgs{To: &common.Address{}, Value: (*hexutil.Big)(big.NewInt(100))} | 			args = types.TransactionArgs{To: &common.Address{}, Value: (*hexutil.Big)(big.NewInt(100))} | ||||||
| 		}, false, 0}, | 		}, false, 0, false}, | ||||||
| 		// should success, enough balance now
 | 		// should success, enough balance now
 | ||||||
| 		{"enough balance", func() { | 		{"enough balance", func() { | ||||||
| 			args = types.TransactionArgs{To: &common.Address{}, From: &suite.address, Value: (*hexutil.Big)(big.NewInt(100))} | 			args = types.TransactionArgs{To: &common.Address{}, From: &suite.address, Value: (*hexutil.Big)(big.NewInt(100))} | ||||||
| 		}, false, 0}, | 		}, false, 0, false}, | ||||||
| 		// should success, because gas limit lower than 21000 is ignored
 | 		// should success, because gas limit lower than 21000 is ignored
 | ||||||
| 		{"gas exceed allowance", func() { | 		{"gas exceed allowance", func() { | ||||||
| 			args = types.TransactionArgs{To: &common.Address{}, Gas: &gasHelper} | 			args = types.TransactionArgs{To: &common.Address{}, Gas: &gasHelper} | ||||||
| 		}, true, 21000}, | 		}, true, 21000, false}, | ||||||
| 		// should fail, invalid gas cap
 | 		// should fail, invalid gas cap
 | ||||||
| 		{"gas exceed global allowance", func() { | 		{"gas exceed global allowance", func() { | ||||||
| 			args = types.TransactionArgs{To: &common.Address{}} | 			args = types.TransactionArgs{To: &common.Address{}} | ||||||
| 			gasCap = 20000 | 			gasCap = 20000 | ||||||
| 		}, false, 0}, | 		}, false, 0, false}, | ||||||
| 		// estimate gas of an erc20 contract deployment, the exact gas number is checked with geth
 | 		// estimate gas of an erc20 contract deployment, the exact gas number is checked with geth
 | ||||||
| 		{"contract deployment", func() { | 		{"contract deployment", func() { | ||||||
| 			ctorArgs, err := ContractABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | 			ctorArgs, err := ContractABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | ||||||
| @ -520,7 +521,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() { | |||||||
| 				From: &suite.address, | 				From: &suite.address, | ||||||
| 				Data: (*hexutil.Bytes)(&data), | 				Data: (*hexutil.Bytes)(&data), | ||||||
| 			} | 			} | ||||||
| 		}, true, 1186778}, | 		}, true, 1186778, false}, | ||||||
| 		// estimate gas of an erc20 transfer, the exact gas number is checked with geth
 | 		// estimate gas of an erc20 transfer, the exact gas number is checked with geth
 | ||||||
| 		{"erc20 transfer", func() { | 		{"erc20 transfer", func() { | ||||||
| 			contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | 			contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | ||||||
| @ -528,11 +529,46 @@ func (suite *KeeperTestSuite) TestEstimateGas() { | |||||||
| 			transferData, err := ContractABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000)) | 			transferData, err := ContractABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000)) | ||||||
| 			suite.Require().NoError(err) | 			suite.Require().NoError(err) | ||||||
| 			args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)} | 			args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)} | ||||||
| 		}, true, 51880}, | 		}, true, 51880, false}, | ||||||
|  | 
 | ||||||
|  | 		// repeated tests with dynamicTxFee
 | ||||||
|  | 		{"default args w/ dynamicTxFee", func() { | ||||||
|  | 			args = types.TransactionArgs{To: &common.Address{}} | ||||||
|  | 		}, true, 21000, true}, | ||||||
|  | 		{"not enough balance w/ dynamicTxFee", func() { | ||||||
|  | 			args = types.TransactionArgs{To: &common.Address{}, Value: (*hexutil.Big)(big.NewInt(100))} | ||||||
|  | 		}, false, 0, true}, | ||||||
|  | 		{"enough balance w/ dynamicTxFee", func() { | ||||||
|  | 			args = types.TransactionArgs{To: &common.Address{}, From: &suite.address, Value: (*hexutil.Big)(big.NewInt(100))} | ||||||
|  | 		}, false, 0, true}, | ||||||
|  | 		{"gas exceed allowance w/ dynamicTxFee", func() { | ||||||
|  | 			args = types.TransactionArgs{To: &common.Address{}, Gas: &gasHelper} | ||||||
|  | 		}, true, 21000, true}, | ||||||
|  | 		{"gas exceed global allowance w/ dynamicTxFee", func() { | ||||||
|  | 			args = types.TransactionArgs{To: &common.Address{}} | ||||||
|  | 			gasCap = 20000 | ||||||
|  | 		}, false, 0, true}, | ||||||
|  | 		{"contract deployment w/ dynamicTxFee", func() { | ||||||
|  | 			ctorArgs, err := ContractABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | ||||||
|  | 			suite.Require().NoError(err) | ||||||
|  | 			data := append(ContractBin, ctorArgs...) | ||||||
|  | 			args = types.TransactionArgs{ | ||||||
|  | 				From: &suite.address, | ||||||
|  | 				Data: (*hexutil.Bytes)(&data), | ||||||
|  | 			} | ||||||
|  | 		}, true, 1186778, true}, | ||||||
|  | 		{"erc20 transfer w/ dynamicTxFee", func() { | ||||||
|  | 			contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | ||||||
|  | 			suite.Commit() | ||||||
|  | 			transferData, err := ContractABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000)) | ||||||
|  | 			suite.Require().NoError(err) | ||||||
|  | 			args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)} | ||||||
|  | 		}, true, 51880, true}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { | 		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { | ||||||
|  | 			suite.dynamicTxFee = tc.dynamicTxFee | ||||||
| 			suite.SetupTest() | 			suite.SetupTest() | ||||||
| 			gasCap = 25_000_000 | 			gasCap = 25_000_000 | ||||||
| 			tc.malleate() | 			tc.malleate() | ||||||
| @ -553,6 +589,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() { | |||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  | 	suite.dynamicTxFee = false // reset flag
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *KeeperTestSuite) TestTraceTx() { | func (suite *KeeperTestSuite) TestTraceTx() { | ||||||
| @ -568,6 +605,7 @@ func (suite *KeeperTestSuite) TestTraceTx() { | |||||||
| 		malleate      func() | 		malleate      func() | ||||||
| 		expPass       bool | 		expPass       bool | ||||||
| 		traceResponse []byte | 		traceResponse []byte | ||||||
|  | 		dynamicTxFee  bool | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			msg: "default trace", | 			msg: "default trace", | ||||||
| @ -586,10 +624,30 @@ func (suite *KeeperTestSuite) TestTraceTx() { | |||||||
| 			expPass:       true, | 			expPass:       true, | ||||||
| 			traceResponse: []byte{0x5b, 0x5d}, | 			traceResponse: []byte{0x5b, 0x5d}, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			msg: "default trace with dynamicTxFee", | ||||||
|  | 			malleate: func() { | ||||||
|  | 				traceConfig = nil | ||||||
|  | 			}, | ||||||
|  | 			expPass:       true, | ||||||
|  | 			traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d}, | ||||||
|  | 			dynamicTxFee:  true, | ||||||
|  | 		}, { | ||||||
|  | 			msg: "javascript tracer with dynamicTxFee", | ||||||
|  | 			malleate: func() { | ||||||
|  | 				traceConfig = &types.TraceConfig{ | ||||||
|  | 					Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}", | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			expPass:       true, | ||||||
|  | 			traceResponse: []byte{0x5b, 0x5d}, | ||||||
|  | 			dynamicTxFee:  true, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { | 		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { | ||||||
|  | 			suite.dynamicTxFee = tc.dynamicTxFee | ||||||
| 			suite.SetupTest() | 			suite.SetupTest() | ||||||
| 			// Deploy contract
 | 			// Deploy contract
 | ||||||
| 			contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | 			contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) | ||||||
| @ -614,4 +672,6 @@ func (suite *KeeperTestSuite) TestTraceTx() { | |||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	suite.dynamicTxFee = false // reset flag
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ import ( | |||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||||||
| 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||||||
|  | 	feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types" | ||||||
| 
 | 
 | ||||||
| 	"github.com/tharsis/ethermint/app" | 	"github.com/tharsis/ethermint/app" | ||||||
| 	"github.com/tharsis/ethermint/crypto/ethsecp256k1" | 	"github.com/tharsis/ethermint/crypto/ethsecp256k1" | ||||||
| @ -79,6 +80,8 @@ type KeeperTestSuite struct { | |||||||
| 
 | 
 | ||||||
| 	appCodec codec.Codec | 	appCodec codec.Codec | ||||||
| 	signer   keyring.Signer | 	signer   keyring.Signer | ||||||
|  | 
 | ||||||
|  | 	dynamicTxFee bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// DoSetupTest setup test environment, it uses`require.TestingT` to support both `testing.T` and `testing.B`.
 | /// DoSetupTest setup test environment, it uses`require.TestingT` to support both `testing.T` and `testing.B`.
 | ||||||
| @ -96,7 +99,17 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) { | |||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 	suite.consAddress = sdk.ConsAddress(priv.PubKey().Address()) | 	suite.consAddress = sdk.ConsAddress(priv.PubKey().Address()) | ||||||
| 
 | 
 | ||||||
| 	suite.app = app.Setup(checkTx) | 	if suite.dynamicTxFee { | ||||||
|  | 		// setup feemarketGenesis params
 | ||||||
|  | 		feemarketGenesis := feemarkettypes.DefaultGenesisState() | ||||||
|  | 		feemarketGenesis.Params.EnableHeight = 1 | ||||||
|  | 		feemarketGenesis.Params.NoBaseFee = false | ||||||
|  | 		feemarketGenesis.BaseFee = sdk.NewInt(feemarketGenesis.Params.InitialBaseFee) | ||||||
|  | 		suite.app = app.Setup(checkTx, feemarketGenesis) | ||||||
|  | 	} else { | ||||||
|  | 		suite.app = app.Setup(checkTx, nil) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{ | 	suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{ | ||||||
| 		Height:          1, | 		Height:          1, | ||||||
| 		ChainID:         "ethermint_9000-1", | 		ChainID:         "ethermint_9000-1", | ||||||
| @ -197,7 +210,22 @@ func (suite *KeeperTestSuite) DeployTestContract(t require.TestingT, owner commo | |||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 	nonce := suite.app.EvmKeeper.GetNonce(suite.address) | 	nonce := suite.app.EvmKeeper.GetNonce(suite.address) | ||||||
| 	erc20DeployTx := types.NewTxContract( | 
 | ||||||
|  | 	var erc20DeployTx *types.MsgEthereumTx | ||||||
|  | 	if suite.dynamicTxFee { | ||||||
|  | 		erc20DeployTx = types.NewTxContract( | ||||||
|  | 			chainID, | ||||||
|  | 			nonce, | ||||||
|  | 			nil,     // amount
 | ||||||
|  | 			res.Gas, // gasLimit
 | ||||||
|  | 			nil,     // gasPrice
 | ||||||
|  | 			suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx), | ||||||
|  | 			big.NewInt(1), | ||||||
|  | 			data,                   // input
 | ||||||
|  | 			ðtypes.AccessList{}, // accesses
 | ||||||
|  | 		) | ||||||
|  | 	} else { | ||||||
|  | 		erc20DeployTx = types.NewTxContract( | ||||||
| 			chainID, | 			chainID, | ||||||
| 			nonce, | 			nonce, | ||||||
| 			nil,     // amount
 | 			nil,     // amount
 | ||||||
| @ -207,6 +235,8 @@ func (suite *KeeperTestSuite) DeployTestContract(t require.TestingT, owner commo | |||||||
| 			data, // input
 | 			data, // input
 | ||||||
| 			nil,  // accesses
 | 			nil,  // accesses
 | ||||||
| 		) | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	erc20DeployTx.From = suite.address.Hex() | 	erc20DeployTx.From = suite.address.Hex() | ||||||
| 	err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) | 	err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| @ -231,7 +261,23 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd | |||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 	nonce := suite.app.EvmKeeper.GetNonce(suite.address) | 	nonce := suite.app.EvmKeeper.GetNonce(suite.address) | ||||||
| 	ercTransferTx := types.NewTx( | 
 | ||||||
|  | 	var ercTransferTx *types.MsgEthereumTx | ||||||
|  | 	if suite.dynamicTxFee { | ||||||
|  | 		ercTransferTx = types.NewTx( | ||||||
|  | 			chainID, | ||||||
|  | 			nonce, | ||||||
|  | 			&contractAddr, | ||||||
|  | 			nil, | ||||||
|  | 			res.Gas, | ||||||
|  | 			nil, | ||||||
|  | 			suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx), | ||||||
|  | 			big.NewInt(1), | ||||||
|  | 			transferData, | ||||||
|  | 			ðtypes.AccessList{}, // accesses
 | ||||||
|  | 		) | ||||||
|  | 	} else { | ||||||
|  | 		ercTransferTx = types.NewTx( | ||||||
| 			chainID, | 			chainID, | ||||||
| 			nonce, | 			nonce, | ||||||
| 			&contractAddr, | 			&contractAddr, | ||||||
| @ -242,6 +288,8 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd | |||||||
| 			transferData, | 			transferData, | ||||||
| 			nil, | 			nil, | ||||||
| 		) | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	ercTransferTx.From = suite.address.Hex() | 	ercTransferTx.From = suite.address.Hex() | ||||||
| 	err = ercTransferTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) | 	err = ercTransferTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
|  | |||||||
| @ -31,6 +31,15 @@ var templateLegacyTx = ðtypes.LegacyTx{ | |||||||
| 	Data:     []byte{}, | 	Data:     []byte{}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var templateDynamicFeeTx = ðtypes.DynamicFeeTx{ | ||||||
|  | 	GasFeeCap: big.NewInt(10), | ||||||
|  | 	GasTipCap: big.NewInt(2), | ||||||
|  | 	Gas:       21000, | ||||||
|  | 	To:        &common.Address{}, | ||||||
|  | 	Value:     big.NewInt(0), | ||||||
|  | 	Data:      []byte{}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func newSignedEthTx( | func newSignedEthTx( | ||||||
| 	txData ethtypes.TxData, | 	txData ethtypes.TxData, | ||||||
| 	nonce uint64, | 	nonce uint64, | ||||||
| @ -46,6 +55,9 @@ func newSignedEthTx( | |||||||
| 	case *ethtypes.LegacyTx: | 	case *ethtypes.LegacyTx: | ||||||
| 		txData.Nonce = nonce | 		txData.Nonce = nonce | ||||||
| 		ethTx = ethtypes.NewTx(txData) | 		ethTx = ethtypes.NewTx(txData) | ||||||
|  | 	case *ethtypes.DynamicFeeTx: | ||||||
|  | 		txData.Nonce = nonce | ||||||
|  | 		ethTx = ethtypes.NewTx(txData) | ||||||
| 	default: | 	default: | ||||||
| 		return nil, errors.New("unknown transaction type!") | 		return nil, errors.New("unknown transaction type!") | ||||||
| 	} | 	} | ||||||
| @ -70,7 +82,7 @@ func newNativeMessage( | |||||||
| 	cfg *params.ChainConfig, | 	cfg *params.ChainConfig, | ||||||
| 	krSigner keyring.Signer, | 	krSigner keyring.Signer, | ||||||
| 	ethSigner ethtypes.Signer, | 	ethSigner ethtypes.Signer, | ||||||
| 	isLegacy bool, | 	txType byte, | ||||||
| ) (core.Message, error) { | ) (core.Message, error) { | ||||||
| 	msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight)) | 	msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight)) | ||||||
| 
 | 
 | ||||||
| @ -78,12 +90,20 @@ func newNativeMessage( | |||||||
| 		ethTx   *ethtypes.Transaction | 		ethTx   *ethtypes.Transaction | ||||||
| 		baseFee *big.Int | 		baseFee *big.Int | ||||||
| 	) | 	) | ||||||
| 	if isLegacy { | 
 | ||||||
|  | 	switch txType { | ||||||
|  | 	case ethtypes.LegacyTxType: | ||||||
| 		templateLegacyTx.Nonce = nonce | 		templateLegacyTx.Nonce = nonce | ||||||
| 		ethTx = ethtypes.NewTx(templateLegacyTx) | 		ethTx = ethtypes.NewTx(templateLegacyTx) | ||||||
| 	} else { | 	case ethtypes.AccessListTxType: | ||||||
| 		templateAccessListTx.Nonce = nonce | 		templateAccessListTx.Nonce = nonce | ||||||
| 		ethTx = ethtypes.NewTx(templateAccessListTx) | 		ethTx = ethtypes.NewTx(templateAccessListTx) | ||||||
|  | 	case ethtypes.DynamicFeeTxType: | ||||||
|  | 		templateDynamicFeeTx.Nonce = nonce | ||||||
|  | 		ethTx = ethtypes.NewTx(templateDynamicFeeTx) | ||||||
|  | 		baseFee = big.NewInt(3) | ||||||
|  | 	default: | ||||||
|  | 		return nil, errors.New("unsupport tx type") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	msg := &evmtypes.MsgEthereumTx{} | 	msg := &evmtypes.MsgEthereumTx{} | ||||||
| @ -94,7 +114,7 @@ func newNativeMessage( | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	m, err := msg.AsMessage(msgSigner, baseFee) // TODO: add DynamicFeeTx
 | 	m, err := msg.AsMessage(msgSigner, baseFee) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @ -156,6 +176,33 @@ func BenchmarkApplyTransactionWithLegacyTx(b *testing.B) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func BenchmarkApplyTransactionWithDynamicFeeTx(b *testing.B) { | ||||||
|  | 	suite := KeeperTestSuite{dynamicTxFee: true} | ||||||
|  | 	suite.DoSetupTest(b) | ||||||
|  | 
 | ||||||
|  | 	ethSigner := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) | ||||||
|  | 
 | ||||||
|  | 	b.ResetTimer() | ||||||
|  | 	b.ReportAllocs() | ||||||
|  | 	for i := 0; i < b.N; i++ { | ||||||
|  | 		b.StopTimer() | ||||||
|  | 		tx, err := newSignedEthTx(templateDynamicFeeTx, | ||||||
|  | 			suite.app.EvmKeeper.GetNonce(suite.address), | ||||||
|  | 			sdk.AccAddress(suite.address.Bytes()), | ||||||
|  | 			suite.signer, | ||||||
|  | 			ethSigner, | ||||||
|  | 		) | ||||||
|  | 		require.NoError(b, err) | ||||||
|  | 
 | ||||||
|  | 		b.StartTimer() | ||||||
|  | 		resp, err := suite.app.EvmKeeper.ApplyTransaction(tx) | ||||||
|  | 		b.StopTimer() | ||||||
|  | 
 | ||||||
|  | 		require.NoError(b, err) | ||||||
|  | 		require.False(b, resp.Failed()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func BenchmarkApplyNativeMessage(b *testing.B) { | func BenchmarkApplyNativeMessage(b *testing.B) { | ||||||
| 	suite := KeeperTestSuite{} | 	suite := KeeperTestSuite{} | ||||||
| 	suite.DoSetupTest(b) | 	suite.DoSetupTest(b) | ||||||
| @ -176,7 +223,7 @@ func BenchmarkApplyNativeMessage(b *testing.B) { | |||||||
| 			ethCfg, | 			ethCfg, | ||||||
| 			suite.signer, | 			suite.signer, | ||||||
| 			signer, | 			signer, | ||||||
| 			false, | 			ethtypes.AccessListTxType, | ||||||
| 		) | 		) | ||||||
| 		require.NoError(b, err) | 		require.NoError(b, err) | ||||||
| 
 | 
 | ||||||
| @ -209,7 +256,40 @@ func BenchmarkApplyNativeMessageWithLegacyTx(b *testing.B) { | |||||||
| 			ethCfg, | 			ethCfg, | ||||||
| 			suite.signer, | 			suite.signer, | ||||||
| 			signer, | 			signer, | ||||||
| 			true, | 			ethtypes.LegacyTxType, | ||||||
|  | 		) | ||||||
|  | 		require.NoError(b, err) | ||||||
|  | 
 | ||||||
|  | 		b.StartTimer() | ||||||
|  | 		resp, err := suite.app.EvmKeeper.ApplyNativeMessage(m) | ||||||
|  | 		b.StopTimer() | ||||||
|  | 
 | ||||||
|  | 		require.NoError(b, err) | ||||||
|  | 		require.False(b, resp.Failed()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func BenchmarkApplyNativeMessageWithDynamicFeeTx(b *testing.B) { | ||||||
|  | 	suite := KeeperTestSuite{dynamicTxFee: true} | ||||||
|  | 	suite.DoSetupTest(b) | ||||||
|  | 
 | ||||||
|  | 	params := suite.app.EvmKeeper.GetParams(suite.ctx) | ||||||
|  | 	ethCfg := params.ChainConfig.EthereumConfig(suite.app.EvmKeeper.ChainID()) | ||||||
|  | 	signer := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) | ||||||
|  | 
 | ||||||
|  | 	b.ResetTimer() | ||||||
|  | 	b.ReportAllocs() | ||||||
|  | 	for i := 0; i < b.N; i++ { | ||||||
|  | 		b.StopTimer() | ||||||
|  | 
 | ||||||
|  | 		m, err := newNativeMessage( | ||||||
|  | 			suite.app.EvmKeeper.GetNonce(suite.address), | ||||||
|  | 			suite.ctx.BlockHeight(), | ||||||
|  | 			suite.address, | ||||||
|  | 			ethCfg, | ||||||
|  | 			suite.signer, | ||||||
|  | 			signer, | ||||||
|  | 			ethtypes.DynamicFeeTxType, | ||||||
| 		) | 		) | ||||||
| 		require.NoError(b, err) | 		require.NoError(b, err) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -563,6 +563,20 @@ func (suite *KeeperTestSuite) TestAddLog() { | |||||||
| 	msg2, _ = tx2.GetMsgs()[0].(*types.MsgEthereumTx) | 	msg2, _ = tx2.GetMsgs()[0].(*types.MsgEthereumTx) | ||||||
| 	txHash2 := msg2.AsTransaction().Hash() | 	txHash2 := msg2.AsTransaction().Hash() | ||||||
| 
 | 
 | ||||||
|  | 	msg3 := types.NewTx(big.NewInt(1), 0, &suite.address, big.NewInt(1), 100000, nil, big.NewInt(1), big.NewInt(1), []byte("test"), nil) | ||||||
|  | 	msg3.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 	tx3 := suite.CreateTestTx(msg3, privKey) | ||||||
|  | 	msg3, _ = tx3.GetMsgs()[0].(*types.MsgEthereumTx) | ||||||
|  | 	txHash3 := msg3.AsTransaction().Hash() | ||||||
|  | 
 | ||||||
|  | 	msg4 := types.NewTx(big.NewInt(1), 1, &suite.address, big.NewInt(1), 100000, nil, big.NewInt(1), big.NewInt(1), []byte("test"), nil) | ||||||
|  | 	msg4.From = addr.Hex() | ||||||
|  | 
 | ||||||
|  | 	tx4 := suite.CreateTestTx(msg4, privKey) | ||||||
|  | 	msg4, _ = tx4.GetMsgs()[0].(*types.MsgEthereumTx) | ||||||
|  | 	txHash4 := msg4.AsTransaction().Hash() | ||||||
|  | 
 | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name        string | 		name        string | ||||||
| 		hash        common.Hash | 		hash        common.Hash | ||||||
| @ -601,6 +615,38 @@ func (suite *KeeperTestSuite) TestAddLog() { | |||||||
| 				suite.app.EvmKeeper.IncreaseTxIndexTransient() | 				suite.app.EvmKeeper.IncreaseTxIndexTransient() | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"dynamicfee tx hash from message", | ||||||
|  | 			txHash3, | ||||||
|  | 			ðtypes.Log{ | ||||||
|  | 				Address: addr, | ||||||
|  | 			}, | ||||||
|  | 			ðtypes.Log{ | ||||||
|  | 				Address: addr, | ||||||
|  | 				TxHash:  txHash3, | ||||||
|  | 			}, | ||||||
|  | 			func() {}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"log index keep increasing in new dynamicfee tx", | ||||||
|  | 			txHash4, | ||||||
|  | 			ðtypes.Log{ | ||||||
|  | 				Address: addr, | ||||||
|  | 			}, | ||||||
|  | 			ðtypes.Log{ | ||||||
|  | 				Address: addr, | ||||||
|  | 				TxHash:  txHash4, | ||||||
|  | 				TxIndex: 1, | ||||||
|  | 				Index:   1, | ||||||
|  | 			}, | ||||||
|  | 			func() { | ||||||
|  | 				suite.app.EvmKeeper.SetTxHashTransient(txHash) | ||||||
|  | 				suite.app.EvmKeeper.AddLog(ðtypes.Log{ | ||||||
|  | 					Address: addr, | ||||||
|  | 				}) | ||||||
|  | 				suite.app.EvmKeeper.IncreaseTxIndexTransient() | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
|  | |||||||
| @ -62,7 +62,12 @@ func (k Keeper) DeductTxCostsFromUserBalance( | |||||||
| 
 | 
 | ||||||
| 	if london && !feeMktParams.NoBaseFee && txData.TxType() == ethtypes.DynamicFeeTxType { | 	if london && !feeMktParams.NoBaseFee && txData.TxType() == ethtypes.DynamicFeeTxType { | ||||||
| 		baseFee := k.feeMarketKeeper.GetBaseFee(ctx) | 		baseFee := k.feeMarketKeeper.GetBaseFee(ctx) | ||||||
| 		effectiveTip = cmath.BigMin(txData.GetGasTipCap(), new(big.Int).Sub(txData.GetGasFeeCap(), baseFee)) | 		gasFeeGap := new(big.Int).Sub(txData.GetGasFeeCap(), baseFee) | ||||||
|  | 		if gasFeeGap.Sign() == -1 { | ||||||
|  | 			return nil, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "the tx gasfeecap is lower than the tx baseFee: %s (gasfeecap), %s (basefee) ", txData.GetGasFeeCap(), baseFee) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		effectiveTip = cmath.BigMin(txData.GetGasTipCap(), gasFeeGap) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	gasUsed := new(big.Int).SetUint64(txData.GetGas()) | 	gasUsed := new(big.Int).SetUint64(txData.GetGas()) | ||||||
|  | |||||||
| @ -5,7 +5,9 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | 	cmath "github.com/ethereum/go-ethereum/common/math" | ||||||
| 	ethtypes "github.com/ethereum/go-ethereum/core/types" | 	ethtypes "github.com/ethereum/go-ethereum/core/types" | ||||||
|  | 	ethparams "github.com/ethereum/go-ethereum/params" | ||||||
| 	evmkeeper "github.com/tharsis/ethermint/x/evm/keeper" | 	evmkeeper "github.com/tharsis/ethermint/x/evm/keeper" | ||||||
| 	evmtypes "github.com/tharsis/ethermint/x/evm/types" | 	evmtypes "github.com/tharsis/ethermint/x/evm/types" | ||||||
| ) | ) | ||||||
| @ -23,10 +25,13 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() { | |||||||
| 		to           string | 		to           string | ||||||
| 		gasLimit     uint64 | 		gasLimit     uint64 | ||||||
| 		gasPrice     *sdk.Int | 		gasPrice     *sdk.Int | ||||||
|  | 		gasFeeCap    *big.Int | ||||||
|  | 		gasTipCap    *big.Int | ||||||
| 		cost         *sdk.Int | 		cost         *sdk.Int | ||||||
| 		from         string | 		from         string | ||||||
| 		accessList   *ethtypes.AccessList | 		accessList   *ethtypes.AccessList | ||||||
| 		expectPass   bool | 		expectPass   bool | ||||||
|  | 		dynamicTxFee bool | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			name:       "Enough balance", | 			name:       "Enough balance", | ||||||
| @ -108,6 +113,94 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() { | |||||||
| 			accessList: ðtypes.AccessList{}, | 			accessList: ðtypes.AccessList{}, | ||||||
| 			expectPass: false, | 			expectPass: false, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Enough balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     10, | ||||||
|  | 			gasFeeCap:    big.NewInt(1), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   true, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Equal balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     99, | ||||||
|  | 			gasFeeCap:    big.NewInt(1), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   true, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "negative cost w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     1, | ||||||
|  | 			gasFeeCap:    big.NewInt(1), | ||||||
|  | 			cost:         &negInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   false, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Higher gas limit, not enough balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     100, | ||||||
|  | 			gasFeeCap:    big.NewInt(1), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   false, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Higher gas price, enough balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     10, | ||||||
|  | 			gasFeeCap:    big.NewInt(5), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   true, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Higher gas price, not enough balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     20, | ||||||
|  | 			gasFeeCap:    big.NewInt(5), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   false, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Higher cost, enough balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     10, | ||||||
|  | 			gasFeeCap:    big.NewInt(5), | ||||||
|  | 			cost:         &fiftyInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   true, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Higher cost, not enough balance w/ dynamicTxFee", | ||||||
|  | 			to:           suite.address.String(), | ||||||
|  | 			gasLimit:     10, | ||||||
|  | 			gasFeeCap:    big.NewInt(5), | ||||||
|  | 			cost:         &hundredInt, | ||||||
|  | 			from:         suite.address.String(), | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   false, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	suite.app.EvmKeeper.AddBalance(suite.address, hundredInt.BigInt()) | 	suite.app.EvmKeeper.AddBalance(suite.address, hundredInt.BigInt()) | ||||||
| @ -118,15 +211,25 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() { | |||||||
| 		suite.Run(tc.name, func() { | 		suite.Run(tc.name, func() { | ||||||
| 			to := common.HexToAddress(tc.from) | 			to := common.HexToAddress(tc.from) | ||||||
| 
 | 
 | ||||||
| 			var amount, gasPrice *big.Int | 			var amount, gasPrice, gasFeeCap, gasTipCap *big.Int | ||||||
| 			if tc.cost != nil { | 			if tc.cost != nil { | ||||||
| 				amount = tc.cost.BigInt() | 				amount = tc.cost.BigInt() | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			if tc.dynamicTxFee { | ||||||
|  | 				gasFeeCap = tc.gasFeeCap | ||||||
|  | 				if tc.gasTipCap == nil { | ||||||
|  | 					gasTipCap = oneInt.BigInt() | ||||||
|  | 				} else { | ||||||
|  | 					gasTipCap = tc.gasTipCap | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
| 				if tc.gasPrice != nil { | 				if tc.gasPrice != nil { | ||||||
| 					gasPrice = tc.gasPrice.BigInt() | 					gasPrice = tc.gasPrice.BigInt() | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 			tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &to, amount, tc.gasLimit, gasPrice, nil, nil, nil, tc.accessList) | 			tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &to, amount, tc.gasLimit, gasPrice, gasFeeCap, gasTipCap, nil, tc.accessList) | ||||||
| 			tx.From = tc.from | 			tx.From = tc.from | ||||||
| 
 | 
 | ||||||
| 			txData, _ := evmtypes.UnpackTxData(tx.Data) | 			txData, _ := evmtypes.UnpackTxData(tx.Data) | ||||||
| @ -154,14 +257,18 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() { | |||||||
| 	oneInt := sdk.NewInt(1) | 	oneInt := sdk.NewInt(1) | ||||||
| 	fiveInt := sdk.NewInt(5) | 	fiveInt := sdk.NewInt(5) | ||||||
| 	fiftyInt := sdk.NewInt(50) | 	fiftyInt := sdk.NewInt(50) | ||||||
|  | 	hundredBaseFeeInt := sdk.NewInt(ethparams.InitialBaseFee * 100) | ||||||
| 
 | 
 | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name         string | 		name         string | ||||||
| 		gasLimit     uint64 | 		gasLimit     uint64 | ||||||
| 		gasPrice     *sdk.Int | 		gasPrice     *sdk.Int | ||||||
|  | 		gasFeeCap    *big.Int | ||||||
|  | 		gasTipCap    *big.Int | ||||||
| 		cost         *sdk.Int | 		cost         *sdk.Int | ||||||
| 		accessList   *ethtypes.AccessList | 		accessList   *ethtypes.AccessList | ||||||
| 		expectPass   bool | 		expectPass   bool | ||||||
|  | 		dynamicTxFee bool | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			name:       "Enough balance", | 			name:       "Enough balance", | ||||||
| @ -213,24 +320,82 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() { | |||||||
| 			accessList: ðtypes.AccessList{}, | 			accessList: ðtypes.AccessList{}, | ||||||
| 			expectPass: true, | 			expectPass: true, | ||||||
| 		}, | 		}, | ||||||
|  | 		//  testcases with dynamicTxFee enabled.
 | ||||||
|  | 		{ | ||||||
|  | 			name:         "Invalid gasFeeCap w/ dynamicTxFee", | ||||||
|  | 			gasLimit:     10, | ||||||
|  | 			gasFeeCap:    big.NewInt(1), | ||||||
|  | 			gasTipCap:    big.NewInt(1), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   false, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		// TODO: is this case valid?
 | ||||||
|  | 		{ | ||||||
|  | 			name:         "empty fee failed to deduct", | ||||||
|  | 			gasLimit:     10, | ||||||
|  | 			gasFeeCap:    big.NewInt(ethparams.InitialBaseFee), | ||||||
|  | 			gasTipCap:    big.NewInt(1), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   false, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "effectiveTip equal to gasTipCap", | ||||||
|  | 			gasLimit:     100, | ||||||
|  | 			gasFeeCap:    big.NewInt(ethparams.InitialBaseFee + 2), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   true, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "effectiveTip equal to (gasFeeCap - baseFee)", | ||||||
|  | 			gasLimit:     105, | ||||||
|  | 			gasFeeCap:    big.NewInt(ethparams.InitialBaseFee + 1), | ||||||
|  | 			gasTipCap:    big.NewInt(2), | ||||||
|  | 			cost:         &oneInt, | ||||||
|  | 			accessList:   ðtypes.AccessList{}, | ||||||
|  | 			expectPass:   true, | ||||||
|  | 			dynamicTxFee: true, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for i, tc := range testCases { | 	for i, tc := range testCases { | ||||||
| 		suite.Run(tc.name, func() { | 		suite.Run(tc.name, func() { | ||||||
|  | 			suite.dynamicTxFee = tc.dynamicTxFee | ||||||
| 			suite.SetupTest() | 			suite.SetupTest() | ||||||
| 			suite.app.EvmKeeper.AddBalance(suite.address, hundredInt.BigInt()) |  | ||||||
| 			balance := suite.app.EvmKeeper.GetBalance(suite.address) |  | ||||||
| 			suite.Require().Equal(balance, hundredInt.BigInt()) |  | ||||||
| 
 | 
 | ||||||
| 			var amount, gasPrice *big.Int | 			var amount, gasPrice, gasFeeCap, gasTipCap *big.Int | ||||||
| 			if tc.cost != nil { | 			if tc.cost != nil { | ||||||
| 				amount = tc.cost.BigInt() | 				amount = tc.cost.BigInt() | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			if suite.dynamicTxFee { | ||||||
|  | 				if tc.gasFeeCap != nil { | ||||||
|  | 					gasFeeCap = tc.gasFeeCap | ||||||
|  | 				} | ||||||
|  | 				if tc.gasTipCap == nil { | ||||||
|  | 					gasTipCap = oneInt.BigInt() | ||||||
|  | 				} else { | ||||||
|  | 					gasTipCap = tc.gasTipCap | ||||||
|  | 				} | ||||||
|  | 				suite.app.EvmKeeper.AddBalance(suite.address, hundredBaseFeeInt.BigInt()) | ||||||
|  | 				balance := suite.app.EvmKeeper.GetBalance(suite.address) | ||||||
|  | 				suite.Require().Equal(balance, hundredBaseFeeInt.BigInt()) | ||||||
|  | 			} else { | ||||||
| 				if tc.gasPrice != nil { | 				if tc.gasPrice != nil { | ||||||
| 					gasPrice = tc.gasPrice.BigInt() | 					gasPrice = tc.gasPrice.BigInt() | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 			tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &suite.address, amount, tc.gasLimit, gasPrice, nil, nil, nil, tc.accessList) | 				suite.app.EvmKeeper.AddBalance(suite.address, hundredInt.BigInt()) | ||||||
|  | 				balance := suite.app.EvmKeeper.GetBalance(suite.address) | ||||||
|  | 				suite.Require().Equal(balance, hundredInt.BigInt()) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &suite.address, amount, tc.gasLimit, gasPrice, gasFeeCap, gasTipCap, nil, tc.accessList) | ||||||
| 			tx.From = suite.address.String() | 			tx.From = suite.address.String() | ||||||
| 
 | 
 | ||||||
| 			txData, _ := evmtypes.UnpackTxData(tx.Data) | 			txData, _ := evmtypes.UnpackTxData(tx.Data) | ||||||
| @ -242,11 +407,24 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() { | |||||||
| 				evmtypes.DefaultEVMDenom, | 				evmtypes.DefaultEVMDenom, | ||||||
| 				false, | 				false, | ||||||
| 				false, | 				false, | ||||||
| 				false, // london
 | 				suite.dynamicTxFee, // london
 | ||||||
| 			) | 			) | ||||||
| 
 | 
 | ||||||
| 			if tc.expectPass { | 			if tc.expectPass { | ||||||
| 				suite.Require().NoError(err, "valid test %d failed", i) | 				suite.Require().NoError(err, "valid test %d failed", i) | ||||||
|  | 				if tc.dynamicTxFee { | ||||||
|  | 					baseFee := suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx) | ||||||
|  | 					gasFeeGap := new(big.Int).Sub(txData.GetGasFeeCap(), baseFee) | ||||||
|  | 					effectiveTip := cmath.BigMin(txData.GetGasTipCap(), gasFeeGap) | ||||||
|  | 
 | ||||||
|  | 					suite.Require().Equal( | ||||||
|  | 						fees, | ||||||
|  | 						sdk.NewCoins( | ||||||
|  | 							sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(effectiveTip).Mul(sdk.NewIntFromUint64(tc.gasLimit))), | ||||||
|  | 						), | ||||||
|  | 						"valid test %d failed, fee value is wrong ", i, | ||||||
|  | 					) | ||||||
|  | 				} else { | ||||||
| 					suite.Require().Equal( | 					suite.Require().Equal( | ||||||
| 						fees, | 						fees, | ||||||
| 						sdk.NewCoins( | 						sdk.NewCoins( | ||||||
| @ -254,11 +432,12 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() { | |||||||
| 						), | 						), | ||||||
| 						"valid test %d failed, fee value is wrong ", i, | 						"valid test %d failed, fee value is wrong ", i, | ||||||
| 					) | 					) | ||||||
| 
 | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				suite.Require().Error(err, "invalid test %d passed", i) | 				suite.Require().Error(err, "invalid test %d passed", i) | ||||||
| 				suite.Require().Nil(fees, "invalid test %d passed. fees value must be nil", i) | 				suite.Require().Nil(fees, "invalid test %d passed. fees value must be nil", i) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  | 	suite.dynamicTxFee = false // reset flag
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -94,7 +94,7 @@ func newMsgEthereumTx( | |||||||
| 		} | 		} | ||||||
| 	case accesses != nil && gasFeeCap != nil && gasTipCap != nil: | 	case accesses != nil && gasFeeCap != nil && gasTipCap != nil: | ||||||
| 		gtc := sdk.NewIntFromBigInt(gasTipCap) | 		gtc := sdk.NewIntFromBigInt(gasTipCap) | ||||||
| 		gfc := sdk.NewIntFromBigInt(gasTipCap) | 		gfc := sdk.NewIntFromBigInt(gasFeeCap) | ||||||
| 
 | 
 | ||||||
| 		txData = &DynamicFeeTx{ | 		txData = &DynamicFeeTx{ | ||||||
| 			ChainID:   cid, | 			ChainID:   cid, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user