fix: consistent BaseFee check logic (#855)
Closes: #755 ``` if not london_hardfork { # reject DynamicFeeTx # no `baseFeePerGas` field in block response # baseFee = nil } else { # allow DynamicFeeTx # add `baseFeePerGas` field in block response if feemarketParams.NoBaseFee or height < feemarketParams.EnableHeight { # baseFee = 0 } else { # init baseFee to initBaseFee and adjust in later blocks } } ``` Update x/evm/keeper/keeper.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> add unit tests Update app/ante/utils_test.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> changelog
This commit is contained in:
parent
d822fee5c1
commit
eb17366dcc
@ -46,6 +46,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
- (evm) [tharsis#851](https://github.com/tharsis/ethermint/pull/851) fix contract address used in EVM, this issue is caused by [tharsis#808](https://github.com/tharsis/ethermint/issues/808).
|
||||
- (evm) [tharsis#N/A]() reject invalid `MsgEthereumTx` wrapping tx
|
||||
- (evm) [tharsis#N/A]() Fix SelfDestruct opcode by deleting account code and state
|
||||
- (feemarket) [tharsis#855](https://github.com/tharsis/ethermint/pull/855) consistent baseFee check logic
|
||||
|
||||
### Improvements
|
||||
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func (suite AnteTestSuite) TestAnteHandler() {
|
||||
suite.dynamicTxFee = false
|
||||
suite.enableFeemarket = false
|
||||
suite.SetupTest() // reset
|
||||
|
||||
addr, privKey := tests.NewAddrKey()
|
||||
@ -314,22 +314,16 @@ 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)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
txFn func() sdk.Tx
|
||||
checkTx bool
|
||||
reCheckTx bool
|
||||
expPass bool
|
||||
name string
|
||||
txFn func() sdk.Tx
|
||||
enableLondonHF bool
|
||||
checkTx bool
|
||||
reCheckTx bool
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"success - DeliverTx (contract)",
|
||||
@ -351,6 +345,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
false, false, true,
|
||||
},
|
||||
{
|
||||
@ -359,7 +354,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedContractTx :=
|
||||
evmtypes.NewTxContract(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
2,
|
||||
1,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
nil,
|
||||
@ -373,6 +368,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
true, false, true,
|
||||
},
|
||||
{
|
||||
@ -381,7 +377,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedContractTx :=
|
||||
evmtypes.NewTxContract(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
3,
|
||||
1,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
nil,
|
||||
@ -395,6 +391,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
false, true, true,
|
||||
},
|
||||
{
|
||||
@ -403,7 +400,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedTx :=
|
||||
evmtypes.NewTx(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
4,
|
||||
1,
|
||||
&to,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
@ -418,6 +415,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
false, false, true,
|
||||
},
|
||||
{
|
||||
@ -426,7 +424,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedTx :=
|
||||
evmtypes.NewTx(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
5,
|
||||
1,
|
||||
&to,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
@ -441,6 +439,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
true, false, true,
|
||||
},
|
||||
{
|
||||
@ -449,7 +448,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedTx :=
|
||||
evmtypes.NewTx(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
3,
|
||||
1,
|
||||
&to,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
@ -463,7 +462,9 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
|
||||
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||
return tx
|
||||
}, false, true, true,
|
||||
},
|
||||
true,
|
||||
false, true, true,
|
||||
},
|
||||
{
|
||||
"success - CheckTx (cosmos tx not signed)",
|
||||
@ -471,7 +472,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedTx :=
|
||||
evmtypes.NewTx(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
4,
|
||||
1,
|
||||
&to,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
@ -485,7 +486,9 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
|
||||
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||
return tx
|
||||
}, false, true, true,
|
||||
},
|
||||
true,
|
||||
false, true, true,
|
||||
},
|
||||
{
|
||||
"fail - CheckTx (cosmos tx is not valid)",
|
||||
@ -493,7 +496,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedTx :=
|
||||
evmtypes.NewTx(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
4,
|
||||
1,
|
||||
&to,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
@ -509,7 +512,9 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
// bigger than MaxGasWanted
|
||||
txBuilder.SetGasLimit(uint64(1 << 63))
|
||||
return txBuilder.GetTx()
|
||||
}, true, false, false,
|
||||
},
|
||||
true,
|
||||
true, false, false,
|
||||
},
|
||||
{
|
||||
"fail - CheckTx (memo too long)",
|
||||
@ -517,7 +522,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
signedTx :=
|
||||
evmtypes.NewTx(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
5,
|
||||
1,
|
||||
&to,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
@ -532,12 +537,45 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||
txBuilder.SetMemo(strings.Repeat("*", 257))
|
||||
return txBuilder.GetTx()
|
||||
}, true, false, false,
|
||||
},
|
||||
true,
|
||||
true, false, false,
|
||||
},
|
||||
{
|
||||
"fail - DynamicFeeTx without london hark fork",
|
||||
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, false)
|
||||
return tx
|
||||
},
|
||||
false,
|
||||
false, false, false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
suite.enableFeemarket = true
|
||||
suite.enableLondonHF = tc.enableLondonHF
|
||||
suite.SetupTest() // reset
|
||||
|
||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
||||
suite.Require().NoError(acc.SetSequence(1))
|
||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||
|
||||
suite.ctx = suite.ctx.WithIsCheckTx(tc.checkTx).WithIsReCheckTx(tc.reCheckTx)
|
||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt((ethparams.InitialBaseFee+10)*100000))
|
||||
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
|
||||
@ -548,5 +586,6 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||
}
|
||||
})
|
||||
}
|
||||
suite.dynamicTxFee = false
|
||||
suite.enableFeemarket = false
|
||||
suite.enableLondonHF = true
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
|
||||
@ -32,6 +33,7 @@ type EVMKeeper interface {
|
||||
DeductTxCostsFromUserBalance(
|
||||
ctx sdk.Context, msgEthTx evmtypes.MsgEthereumTx, txData evmtypes.TxData, denom string, homestead, istanbul, london bool,
|
||||
) (sdk.Coins, error)
|
||||
BaseFee(ctx sdk.Context, ethCfg *params.ChainConfig) *big.Int
|
||||
}
|
||||
|
||||
type protoTxProvider interface {
|
||||
@ -326,8 +328,6 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
||||
ctd.evmKeeper.WithContext(ctx)
|
||||
|
||||
params := ctd.evmKeeper.GetParams(ctx)
|
||||
feeMktParams := ctd.feemarketKeeper.GetParams(ctx)
|
||||
|
||||
ethCfg := params.ChainConfig.EthereumConfig(ctd.evmKeeper.ChainID())
|
||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||
|
||||
@ -337,10 +337,7 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
|
||||
}
|
||||
|
||||
var baseFee *big.Int
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee {
|
||||
baseFee = ctd.feemarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
baseFee := ctd.evmKeeper.BaseFee(ctx, ethCfg)
|
||||
|
||||
coreMsg, err := msgEthTx.AsMessage(signer, baseFee)
|
||||
if err != nil {
|
||||
@ -370,17 +367,23 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
||||
)
|
||||
}
|
||||
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee == nil {
|
||||
return ctx, sdkerrors.Wrap(evmtypes.ErrInvalidBaseFee, "base fee is supported but evm block context value is nil")
|
||||
}
|
||||
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee != nil && coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
|
||||
return ctx, sdkerrors.Wrapf(evmtypes.ErrInvalidBaseFee, "max fee per gas less than block base fee (%s < %s)", coreMsg.GasFeeCap(), baseFee)
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||
if baseFee == nil {
|
||||
return ctx, sdkerrors.Wrap(
|
||||
evmtypes.ErrInvalidBaseFee,
|
||||
"base fee is supported but evm block context value is nil",
|
||||
)
|
||||
}
|
||||
if coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
|
||||
return ctx, sdkerrors.Wrapf(
|
||||
evmtypes.ErrInvalidBaseFee,
|
||||
"max fee per gas less than block base fee (%s < %s)",
|
||||
coreMsg.GasFeeCap(), baseFee,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctd.evmKeeper.WithContext(ctx)
|
||||
|
||||
// set the original gas meter
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
@ -443,6 +446,8 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
vbd.evmKeeper.WithContext(ctx)
|
||||
|
||||
err := tx.ValidateBasic()
|
||||
// ErrNoSignatures is fine with eth tx
|
||||
if err != nil && !errors.Is(err, sdkerrors.ErrNoSignatures) {
|
||||
@ -477,7 +482,15 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
||||
if err != nil {
|
||||
return ctx, sdkerrors.Wrap(err, "failed to unpack MsgEthereumTx Data")
|
||||
}
|
||||
|
||||
params := vbd.evmKeeper.GetParams(ctx)
|
||||
chainID := vbd.evmKeeper.ChainID()
|
||||
ethCfg := params.ChainConfig.EthereumConfig(chainID)
|
||||
baseFee := vbd.evmKeeper.BaseFee(ctx, ethCfg)
|
||||
if baseFee == nil && txData.TxType() == ethtypes.DynamicFeeTxType {
|
||||
return ctx, sdkerrors.Wrap(ethtypes.ErrTxTypeNotSupported, "dynamic fee tx not supported")
|
||||
}
|
||||
|
||||
ethFeeAmount := sdk.Coins{sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))}
|
||||
|
||||
authInfo := protoTx.AuthInfo
|
||||
@ -558,13 +571,12 @@ func (mfd EthMempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulat
|
||||
|
||||
var feeAmt *big.Int
|
||||
|
||||
feeMktParams := mfd.feemarketKeeper.GetParams(ctx)
|
||||
params := mfd.evmKeeper.GetParams(ctx)
|
||||
chainID := mfd.evmKeeper.ChainID()
|
||||
ethCfg := params.ChainConfig.EthereumConfig(chainID)
|
||||
evmDenom := params.EvmDenom
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee {
|
||||
baseFee := mfd.feemarketKeeper.GetBaseFee(ctx)
|
||||
baseFee := mfd.evmKeeper.BaseFee(ctx, ethCfg)
|
||||
if baseFee != nil {
|
||||
feeAmt = msg.GetEffectiveFee(baseFee)
|
||||
} else {
|
||||
feeAmt = msg.GetFee()
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func (suite AnteTestSuite) TestSignatures() {
|
||||
suite.dynamicTxFee = false
|
||||
suite.enableFeemarket = false
|
||||
suite.SetupTest() // reset
|
||||
|
||||
addr, privKey := tests.NewAddrKey()
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ante_test
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -12,6 +13,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
@ -32,27 +34,38 @@ import (
|
||||
type AnteTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
ctx sdk.Context
|
||||
app *app.EthermintApp
|
||||
clientCtx client.Context
|
||||
anteHandler sdk.AnteHandler
|
||||
ethSigner ethtypes.Signer
|
||||
dynamicTxFee bool
|
||||
ctx sdk.Context
|
||||
app *app.EthermintApp
|
||||
clientCtx client.Context
|
||||
anteHandler sdk.AnteHandler
|
||||
ethSigner ethtypes.Signer
|
||||
enableFeemarket bool
|
||||
enableLondonHF bool
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) SetupTest() {
|
||||
checkTx := false
|
||||
|
||||
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.app = app.Setup(checkTx, func(app *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
if suite.enableFeemarket {
|
||||
// setup feemarketGenesis params
|
||||
feemarketGenesis := feemarkettypes.DefaultGenesisState()
|
||||
feemarketGenesis.Params.EnableHeight = 1
|
||||
feemarketGenesis.Params.NoBaseFee = false
|
||||
feemarketGenesis.BaseFee = sdk.NewInt(feemarketGenesis.Params.InitialBaseFee)
|
||||
// Verify feeMarket genesis
|
||||
err := feemarketGenesis.Validate()
|
||||
suite.Require().NoError(err)
|
||||
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||
}
|
||||
if !suite.enableLondonHF {
|
||||
evmGenesis := evmtypes.DefaultGenesisState()
|
||||
maxInt := sdk.NewInt(math.MaxInt64)
|
||||
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
||||
genesis[evmtypes.ModuleName] = app.AppCodec().MustMarshalJSON(evmGenesis)
|
||||
}
|
||||
return genesis
|
||||
})
|
||||
|
||||
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())))
|
||||
@ -61,7 +74,6 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
|
||||
infCtx := suite.ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||
suite.app.AccountKeeper.SetParams(infCtx, authtypes.DefaultParams())
|
||||
suite.app.EvmKeeper.SetParams(infCtx, evmtypes.DefaultParams())
|
||||
|
||||
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
||||
// We're using TestMsg amino encoding in some tests, so register it here.
|
||||
@ -78,7 +90,9 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
}
|
||||
|
||||
func TestAnteTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(AnteTestSuite))
|
||||
suite.Run(t, &AnteTestSuite{
|
||||
enableLondonHF: true,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateTestTx is a helper function to create a tx given multiple inputs.
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||
)
|
||||
|
||||
// DefaultConsensusParams defines the default Tendermint consensus params used in
|
||||
@ -35,20 +34,14 @@ var DefaultConsensusParams = &abci.ConsensusParams{
|
||||
}
|
||||
|
||||
// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
|
||||
func Setup(isCheckTx bool, feemarketGenesis *feemarkettypes.GenesisState) *EthermintApp {
|
||||
func Setup(isCheckTx bool, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState) *EthermintApp {
|
||||
db := dbm.NewMemDB()
|
||||
app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
||||
if !isCheckTx {
|
||||
// init chain must be called to stop deliverState from being nil
|
||||
genesisState := NewDefaultGenesisState()
|
||||
|
||||
// Verify feeMarket genesis
|
||||
if feemarketGenesis != nil {
|
||||
if err := feemarketGenesis.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
genesisState[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||
if patchGenesis != nil {
|
||||
genesisState = patchGenesis(app, genesisState)
|
||||
}
|
||||
|
||||
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
||||
|
@ -74,14 +74,15 @@ func (suite *EvmTestSuite) DoSetupTest(t require.TestingT) {
|
||||
require.NoError(t, err)
|
||||
consAddress := sdk.ConsAddress(priv.PubKey().Address())
|
||||
|
||||
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)
|
||||
}
|
||||
suite.app = app.Setup(checkTx, func(app *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
if suite.dynamicTxFee {
|
||||
feemarketGenesis := feemarkettypes.DefaultGenesisState()
|
||||
feemarketGenesis.Params.EnableHeight = 1
|
||||
feemarketGenesis.Params.NoBaseFee = false
|
||||
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||
}
|
||||
return genesis
|
||||
})
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewCoin(types.DefaultEVMDenom, sdk.NewInt(100000000000000)))
|
||||
genesisState := app.ModuleBasics.DefaultGenesis(suite.app.AppCodec())
|
||||
|
@ -220,20 +220,17 @@ func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.Ms
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||
|
||||
var baseFee *big.Int
|
||||
if types.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||
baseFee = k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
cfg, err := k.EVMConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
msg, err := args.ToMessage(req.GasCap, baseFee)
|
||||
msg, err := args.ToMessage(req.GasCap, cfg.BaseFee)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
res, err := k.ApplyMessage(msg, nil, false)
|
||||
res, err := k.ApplyMessageWithConfig(msg, nil, false, cfg)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
@ -292,10 +289,6 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to load evm config")
|
||||
}
|
||||
var baseFee *big.Int
|
||||
if types.IsLondon(cfg.ChainConfig, ctx.BlockHeight()) {
|
||||
baseFee = k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
|
||||
// Create a helper to check if a gas allowance results in an executable transaction
|
||||
executable := func(gas uint64) (vmerror bool, rsp *types.MsgEthereumTxResponse, err error) {
|
||||
@ -304,7 +297,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
||||
// Reset to the initial context
|
||||
k.WithContext(ctx)
|
||||
|
||||
msg, err := args.ToMessage(req.GasCap, baseFee)
|
||||
msg, err := args.ToMessage(req.GasCap, cfg.BaseFee)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@ -364,27 +357,28 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
|
||||
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
|
||||
k.WithContext(ctx)
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
cfg, err := k.EVMConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to load evm config")
|
||||
}
|
||||
signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight()))
|
||||
|
||||
for i, tx := range req.Predecessors {
|
||||
ethTx := tx.AsTransaction()
|
||||
msg, err := ethTx.AsMessage(signer, baseFee)
|
||||
msg, err := ethTx.AsMessage(signer, cfg.BaseFee)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
k.SetTxHashTransient(ethTx.Hash())
|
||||
k.SetTxIndexTransient(uint64(i))
|
||||
|
||||
if _, err := k.ApplyMessage(msg, types.NewNoOpTracer(), true); err != nil {
|
||||
if _, err := k.ApplyMessageWithConfig(msg, types.NewNoOpTracer(), true, cfg); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
tx := req.Msg.AsTransaction()
|
||||
result, err := k.traceTx(ctx, signer, req.TxIndex, ethCfg, tx, baseFee, req.TraceConfig, false)
|
||||
result, err := k.traceTx(ctx, cfg, signer, req.TxIndex, tx, req.TraceConfig, false)
|
||||
if err != nil {
|
||||
// error will be returned with detail status from traceTx
|
||||
return nil, err
|
||||
@ -418,18 +412,18 @@ func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest)
|
||||
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
|
||||
k.WithContext(ctx)
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
|
||||
cfg, err := k.EVMConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to load evm config")
|
||||
}
|
||||
signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight()))
|
||||
txsLength := len(req.Txs)
|
||||
results := make([]*types.TxTraceResult, 0, txsLength)
|
||||
|
||||
for i, tx := range req.Txs {
|
||||
result := types.TxTraceResult{}
|
||||
ethTx := tx.AsTransaction()
|
||||
traceResult, err := k.traceTx(ctx, signer, uint64(i), ethCfg, ethTx, baseFee, req.TraceConfig, true)
|
||||
traceResult, err := k.traceTx(ctx, cfg, signer, uint64(i), ethTx, req.TraceConfig, true)
|
||||
if err != nil {
|
||||
result.Error = err.Error()
|
||||
continue
|
||||
@ -450,11 +444,10 @@ func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest)
|
||||
|
||||
func (k *Keeper) traceTx(
|
||||
ctx sdk.Context,
|
||||
cfg *types.EVMConfig,
|
||||
signer ethtypes.Signer,
|
||||
txIndex uint64,
|
||||
ethCfg *ethparams.ChainConfig,
|
||||
tx *ethtypes.Transaction,
|
||||
baseFee *big.Int,
|
||||
traceConfig *types.TraceConfig,
|
||||
commitMessage bool,
|
||||
) (*interface{}, error) {
|
||||
@ -465,7 +458,7 @@ func (k *Keeper) traceTx(
|
||||
err error
|
||||
)
|
||||
|
||||
msg, err := tx.AsMessage(signer, baseFee)
|
||||
msg, err := tx.AsMessage(signer, cfg.BaseFee)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
@ -473,7 +466,7 @@ func (k *Keeper) traceTx(
|
||||
txHash := tx.Hash()
|
||||
|
||||
if traceConfig != nil && traceConfig.Overrides != nil {
|
||||
overrides = traceConfig.Overrides.EthereumConfig(ethCfg.ChainID)
|
||||
overrides = traceConfig.Overrides.EthereumConfig(cfg.ChainConfig.ChainID)
|
||||
}
|
||||
|
||||
switch {
|
||||
@ -522,13 +515,13 @@ func (k *Keeper) traceTx(
|
||||
}
|
||||
tracer = vm.NewStructLogger(&logConfig)
|
||||
default:
|
||||
tracer = types.NewTracer(types.TracerStruct, msg, ethCfg, ctx.BlockHeight())
|
||||
tracer = types.NewTracer(types.TracerStruct, msg, cfg.ChainConfig, ctx.BlockHeight())
|
||||
}
|
||||
|
||||
k.SetTxHashTransient(txHash)
|
||||
k.SetTxIndexTransient(txIndex)
|
||||
|
||||
res, err := k.ApplyMessage(msg, tracer, commitMessage)
|
||||
res, err := k.ApplyMessageWithConfig(msg, tracer, commitMessage, cfg)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
@ -485,11 +485,11 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
||||
gasCap uint64
|
||||
)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
expGas uint64
|
||||
dynamicTxFee bool
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
expGas uint64
|
||||
enableFeemarket bool
|
||||
}{
|
||||
// should success, because transfer value is zero
|
||||
{"default args", func() {
|
||||
@ -531,24 +531,24 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
||||
args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)}
|
||||
}, true, 51880, false},
|
||||
|
||||
// repeated tests with dynamicTxFee
|
||||
{"default args w/ dynamicTxFee", func() {
|
||||
// repeated tests with enableFeemarket
|
||||
{"default args w/ enableFeemarket", func() {
|
||||
args = types.TransactionArgs{To: &common.Address{}}
|
||||
}, true, 21000, true},
|
||||
{"not enough balance w/ dynamicTxFee", func() {
|
||||
{"not enough balance w/ enableFeemarket", func() {
|
||||
args = types.TransactionArgs{To: &common.Address{}, Value: (*hexutil.Big)(big.NewInt(100))}
|
||||
}, false, 0, true},
|
||||
{"enough balance w/ dynamicTxFee", func() {
|
||||
{"enough balance w/ enableFeemarket", 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() {
|
||||
{"gas exceed allowance w/ enableFeemarket", func() {
|
||||
args = types.TransactionArgs{To: &common.Address{}, Gas: &gasHelper}
|
||||
}, true, 21000, true},
|
||||
{"gas exceed global allowance w/ dynamicTxFee", func() {
|
||||
{"gas exceed global allowance w/ enableFeemarket", func() {
|
||||
args = types.TransactionArgs{To: &common.Address{}}
|
||||
gasCap = 20000
|
||||
}, false, 0, true},
|
||||
{"contract deployment w/ dynamicTxFee", func() {
|
||||
{"contract deployment w/ enableFeemarket", func() {
|
||||
ctorArgs, err := types.ERC20Contract.ABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
suite.Require().NoError(err)
|
||||
data := append(types.ERC20Contract.Bin, ctorArgs...)
|
||||
@ -557,7 +557,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
||||
Data: (*hexutil.Bytes)(&data),
|
||||
}
|
||||
}, true, 1186778, true},
|
||||
{"erc20 transfer w/ dynamicTxFee", func() {
|
||||
{"erc20 transfer w/ enableFeemarket", func() {
|
||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
suite.Commit()
|
||||
transferData, err := types.ERC20Contract.ABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
||||
@ -568,7 +568,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
suite.dynamicTxFee = tc.dynamicTxFee
|
||||
suite.enableFeemarket = tc.enableFeemarket
|
||||
suite.SetupTest()
|
||||
gasCap = 25_000_000
|
||||
tc.malleate()
|
||||
@ -589,7 +589,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
||||
}
|
||||
})
|
||||
}
|
||||
suite.dynamicTxFee = false // reset flag
|
||||
suite.enableFeemarket = false // reset flag
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
@ -602,11 +602,11 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
traceResponse []byte
|
||||
dynamicTxFee bool
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
traceResponse []byte
|
||||
enableFeemarket bool
|
||||
}{
|
||||
{
|
||||
msg: "default trace",
|
||||
@ -629,9 +629,9 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
}
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
||||
dynamicTxFee: false,
|
||||
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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
||||
enableFeemarket: false,
|
||||
},
|
||||
{
|
||||
msg: "javascript tracer",
|
||||
@ -646,7 +646,7 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
traceResponse: []byte{0x5b, 0x5d},
|
||||
},
|
||||
{
|
||||
msg: "default trace with dynamicTxFee",
|
||||
msg: "default trace with enableFeemarket",
|
||||
malleate: func() {
|
||||
txIndex = 0
|
||||
traceConfig = &types.TraceConfig{
|
||||
@ -656,12 +656,12 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
}
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
||||
dynamicTxFee: true,
|
||||
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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
||||
enableFeemarket: true,
|
||||
},
|
||||
{
|
||||
msg: "javascript tracer with dynamicTxFee",
|
||||
msg: "javascript tracer with enableFeemarket",
|
||||
malleate: func() {
|
||||
txIndex = 0
|
||||
traceConfig = &types.TraceConfig{
|
||||
@ -669,9 +669,9 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
}
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x5d},
|
||||
dynamicTxFee: true,
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x5d},
|
||||
enableFeemarket: true,
|
||||
},
|
||||
{
|
||||
msg: "default tracer with predecessors",
|
||||
@ -690,15 +690,15 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
|
||||
predecessors = append(predecessors, firstTx)
|
||||
},
|
||||
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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x31, 0x33, 0x31, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
||||
dynamicTxFee: false,
|
||||
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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x31, 0x33, 0x31, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
||||
enableFeemarket: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
suite.dynamicTxFee = tc.dynamicTxFee
|
||||
suite.enableFeemarket = tc.enableFeemarket
|
||||
suite.SetupTest()
|
||||
// Deploy contract
|
||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
@ -731,7 +731,7 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
})
|
||||
}
|
||||
|
||||
suite.dynamicTxFee = false // reset flag
|
||||
suite.enableFeemarket = false // reset flag
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
@ -741,11 +741,11 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
traceResponse []byte
|
||||
dynamicTxFee bool
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
traceResponse []byte
|
||||
enableFeemarket bool
|
||||
}{
|
||||
{
|
||||
msg: "default trace",
|
||||
@ -778,7 +778,7 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
|
||||
},
|
||||
{
|
||||
msg: "default trace with dynamicTxFee and filtered return",
|
||||
msg: "default trace with enableFeemarket and filtered return",
|
||||
malleate: func() {
|
||||
traceConfig = &types.TraceConfig{
|
||||
DisableStack: true,
|
||||
@ -786,20 +786,20 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
EnableMemory: false,
|
||||
}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
||||
dynamicTxFee: true,
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
||||
enableFeemarket: true,
|
||||
},
|
||||
{
|
||||
msg: "javascript tracer with dynamicTxFee",
|
||||
msg: "javascript tracer with enableFeemarket",
|
||||
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, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
|
||||
dynamicTxFee: true,
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
|
||||
enableFeemarket: true,
|
||||
},
|
||||
{
|
||||
msg: "tracer with multiple transactions",
|
||||
@ -816,16 +816,16 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
// overwrite txs to include only the ones on new block
|
||||
txs = append([]*types.MsgEthereumTx{}, firstTx, secondTx)
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a},
|
||||
dynamicTxFee: false,
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 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, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a},
|
||||
enableFeemarket: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
txs = []*types.MsgEthereumTx{}
|
||||
suite.dynamicTxFee = tc.dynamicTxFee
|
||||
suite.enableFeemarket = tc.enableFeemarket
|
||||
suite.SetupTest()
|
||||
// Deploy contract
|
||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
@ -857,5 +857,5 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
})
|
||||
}
|
||||
|
||||
suite.dynamicTxFee = false // reset flag
|
||||
suite.enableFeemarket = false // reset flag
|
||||
}
|
||||
|
@ -374,3 +374,19 @@ func (k *Keeper) PostTxProcessing(txHash common.Hash, logs []*ethtypes.Log) erro
|
||||
func (k Keeper) Tracer(msg core.Message, ethCfg *params.ChainConfig) vm.Tracer {
|
||||
return types.NewTracer(k.tracer, msg, ethCfg, k.Ctx().BlockHeight())
|
||||
}
|
||||
|
||||
// BaseFee returns current base fee, return values:
|
||||
// - `nil`: london hardfork not enabled.
|
||||
// - `0`: london hardfork enabled but feemarket is not enabled.
|
||||
// - `n`: both london hardfork and feemarket are enabled.
|
||||
func (k Keeper) BaseFee(ctx sdk.Context, ethCfg *params.ChainConfig) *big.Int {
|
||||
if !types.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||
return nil
|
||||
}
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
if baseFee == nil {
|
||||
// return 0 if feemarket not enabled.
|
||||
baseFee = big.NewInt(0)
|
||||
}
|
||||
return baseFee
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package keeper_test
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
@ -61,7 +62,8 @@ type KeeperTestSuite struct {
|
||||
appCodec codec.Codec
|
||||
signer keyring.Signer
|
||||
|
||||
dynamicTxFee bool
|
||||
enableFeemarket bool
|
||||
enableLondonHF bool
|
||||
mintFeeCollector bool
|
||||
}
|
||||
|
||||
@ -80,16 +82,22 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) {
|
||||
require.NoError(t, err)
|
||||
suite.consAddress = sdk.ConsAddress(priv.PubKey().Address())
|
||||
|
||||
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.app = app.Setup(checkTx, func(app *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
if suite.enableFeemarket {
|
||||
feemarketGenesis := feemarkettypes.DefaultGenesisState()
|
||||
feemarketGenesis.Params.EnableHeight = 1
|
||||
feemarketGenesis.Params.NoBaseFee = false
|
||||
feemarketGenesis.BaseFee = sdk.NewInt(feemarketGenesis.Params.InitialBaseFee)
|
||||
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||
}
|
||||
if !suite.enableLondonHF {
|
||||
evmGenesis := types.DefaultGenesisState()
|
||||
maxInt := sdk.NewInt(math.MaxInt64)
|
||||
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
||||
genesis[types.ModuleName] = app.AppCodec().MustMarshalJSON(evmGenesis)
|
||||
}
|
||||
return genesis
|
||||
})
|
||||
|
||||
if suite.mintFeeCollector {
|
||||
// mint some coin to fee collector
|
||||
@ -225,7 +233,7 @@ func (suite *KeeperTestSuite) DeployTestContract(t require.TestingT, owner commo
|
||||
require.NoError(t, err)
|
||||
|
||||
var erc20DeployTx *types.MsgEthereumTx
|
||||
if suite.dynamicTxFee {
|
||||
if suite.enableFeemarket {
|
||||
erc20DeployTx = types.NewTxContract(
|
||||
chainID,
|
||||
nonce,
|
||||
@ -276,7 +284,7 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd
|
||||
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||
|
||||
var ercTransferTx *types.MsgEthereumTx
|
||||
if suite.dynamicTxFee {
|
||||
if suite.enableFeemarket {
|
||||
ercTransferTx = types.NewTx(
|
||||
chainID,
|
||||
nonce,
|
||||
@ -333,7 +341,7 @@ func (suite *KeeperTestSuite) DeployTestMessageCall(t require.TestingT) common.A
|
||||
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||
|
||||
var erc20DeployTx *types.MsgEthereumTx
|
||||
if suite.dynamicTxFee {
|
||||
if suite.enableFeemarket {
|
||||
erc20DeployTx = types.NewTxContract(
|
||||
chainID,
|
||||
nonce,
|
||||
@ -367,6 +375,38 @@ func (suite *KeeperTestSuite) DeployTestMessageCall(t require.TestingT) common.A
|
||||
return crypto.CreateAddress(suite.address, nonce)
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(KeeperTestSuite))
|
||||
func (suite *KeeperTestSuite) TestBaseFee() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
enableLondonHF bool
|
||||
enableFeemarket bool
|
||||
expectBaseFee *big.Int
|
||||
}{
|
||||
{"not enable london HF, not enable feemarket", false, false, nil},
|
||||
{"enable london HF, not enable feemarket", true, false, big.NewInt(0)},
|
||||
{"enable london HF, enable feemarket", true, true, big.NewInt(1000000000)},
|
||||
{"not enable london HF, enable feemarket", false, true, nil},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
suite.enableFeemarket = tc.enableFeemarket
|
||||
suite.enableLondonHF = tc.enableLondonHF
|
||||
suite.SetupTest()
|
||||
suite.app.EvmKeeper.BeginBlock(suite.ctx, abci.RequestBeginBlock{})
|
||||
params := suite.app.EvmKeeper.GetParams(suite.ctx)
|
||||
ethCfg := params.ChainConfig.EthereumConfig(suite.app.EvmKeeper.ChainID())
|
||||
baseFee := suite.app.EvmKeeper.BaseFee(suite.ctx, ethCfg)
|
||||
suite.Require().Equal(tc.expectBaseFee, baseFee)
|
||||
})
|
||||
}
|
||||
suite.enableFeemarket = false
|
||||
suite.enableLondonHF = true
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
suite.Run(t, &KeeperTestSuite{
|
||||
enableFeemarket: false,
|
||||
enableLondonHF: true,
|
||||
})
|
||||
}
|
||||
|
@ -31,11 +31,7 @@ func (k *Keeper) EVMConfig(ctx sdk.Context) (*types.EVMConfig, error) {
|
||||
return nil, sdkerrors.Wrap(err, "failed to obtain coinbase address")
|
||||
}
|
||||
|
||||
var baseFee *big.Int
|
||||
if types.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||
baseFee = k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
|
||||
baseFee := k.BaseFee(ctx, ethCfg)
|
||||
return &types.EVMConfig{
|
||||
Params: params,
|
||||
ChainConfig: ethCfg,
|
||||
@ -178,15 +174,9 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
|
||||
return nil, sdkerrors.Wrap(err, "failed to load evm config")
|
||||
}
|
||||
|
||||
// get the latest signer according to the chain rules from the config
|
||||
// get the signer according to the chain rules from the config and block height
|
||||
signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight()))
|
||||
|
||||
var baseFee *big.Int
|
||||
if types.IsLondon(cfg.ChainConfig, ctx.BlockHeight()) {
|
||||
baseFee = k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
|
||||
msg, err := tx.AsMessage(signer, baseFee)
|
||||
msg, err := tx.AsMessage(signer, cfg.BaseFee)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "failed to return ethereum transaction as core message")
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ func newNativeMessage(
|
||||
}
|
||||
|
||||
func BenchmarkApplyTransaction(b *testing.B) {
|
||||
suite := KeeperTestSuite{}
|
||||
suite := KeeperTestSuite{enableLondonHF: true}
|
||||
suite.DoSetupTest(b)
|
||||
|
||||
ethSigner := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
||||
@ -169,7 +169,7 @@ func BenchmarkApplyTransaction(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkApplyTransactionWithLegacyTx(b *testing.B) {
|
||||
suite := KeeperTestSuite{}
|
||||
suite := KeeperTestSuite{enableLondonHF: true}
|
||||
suite.DoSetupTest(b)
|
||||
|
||||
ethSigner := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
||||
@ -196,7 +196,7 @@ func BenchmarkApplyTransactionWithLegacyTx(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkApplyTransactionWithDynamicFeeTx(b *testing.B) {
|
||||
suite := KeeperTestSuite{dynamicTxFee: true}
|
||||
suite := KeeperTestSuite{enableFeemarket: true, enableLondonHF: true}
|
||||
suite.DoSetupTest(b)
|
||||
|
||||
ethSigner := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
||||
@ -223,7 +223,7 @@ func BenchmarkApplyTransactionWithDynamicFeeTx(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkApplyMessage(b *testing.B) {
|
||||
suite := KeeperTestSuite{}
|
||||
suite := KeeperTestSuite{enableLondonHF: true}
|
||||
suite.DoSetupTest(b)
|
||||
|
||||
params := suite.app.EvmKeeper.GetParams(suite.ctx)
|
||||
@ -258,7 +258,7 @@ func BenchmarkApplyMessage(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkApplyMessageWithLegacyTx(b *testing.B) {
|
||||
suite := KeeperTestSuite{}
|
||||
suite := KeeperTestSuite{enableLondonHF: true}
|
||||
suite.DoSetupTest(b)
|
||||
|
||||
params := suite.app.EvmKeeper.GetParams(suite.ctx)
|
||||
@ -293,7 +293,7 @@ func BenchmarkApplyMessageWithLegacyTx(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkApplyMessageWithDynamicFeeTx(b *testing.B) {
|
||||
suite := KeeperTestSuite{dynamicTxFee: true}
|
||||
suite := KeeperTestSuite{enableFeemarket: true, enableLondonHF: true}
|
||||
suite.DoSetupTest(b)
|
||||
|
||||
params := suite.app.EvmKeeper.GetParams(suite.ctx)
|
||||
|
@ -507,7 +507,8 @@ func (suite *KeeperTestSuite) TestEVMConfig() {
|
||||
cfg, err := suite.app.EvmKeeper.EVMConfig(suite.ctx)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(types.DefaultParams(), cfg.Params)
|
||||
suite.Require().Equal((*big.Int)(nil), cfg.BaseFee)
|
||||
// london hardfork is enabled by default
|
||||
suite.Require().Equal(new(big.Int), cfg.BaseFee)
|
||||
suite.Require().Equal(suite.address, cfg.CoinBase)
|
||||
suite.Require().Equal(types.DefaultParams().ChainConfig.EthereumConfig(big.NewInt(9000)), cfg.ChainConfig)
|
||||
}
|
||||
|
@ -20,17 +20,17 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() {
|
||||
negInt := sdk.NewInt(-10)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
to string
|
||||
gasLimit uint64
|
||||
gasPrice *sdk.Int
|
||||
gasFeeCap *big.Int
|
||||
gasTipCap *big.Int
|
||||
cost *sdk.Int
|
||||
from string
|
||||
accessList *ethtypes.AccessList
|
||||
expectPass bool
|
||||
dynamicTxFee bool
|
||||
name string
|
||||
to string
|
||||
gasLimit uint64
|
||||
gasPrice *sdk.Int
|
||||
gasFeeCap *big.Int
|
||||
gasTipCap *big.Int
|
||||
cost *sdk.Int
|
||||
from string
|
||||
accessList *ethtypes.AccessList
|
||||
expectPass bool
|
||||
enableFeemarket bool
|
||||
}{
|
||||
{
|
||||
name: "Enough balance",
|
||||
@ -113,92 +113,92 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() {
|
||||
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: "Enough balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(1),
|
||||
cost: &oneInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
enableFeemarket: 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: "Equal balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 99,
|
||||
gasFeeCap: big.NewInt(1),
|
||||
cost: &oneInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
enableFeemarket: 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: "negative cost w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 1,
|
||||
gasFeeCap: big.NewInt(1),
|
||||
cost: &negInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: false,
|
||||
enableFeemarket: 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 limit, not enough balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 100,
|
||||
gasFeeCap: big.NewInt(1),
|
||||
cost: &oneInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: false,
|
||||
enableFeemarket: 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, enough balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(5),
|
||||
cost: &oneInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
enableFeemarket: 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 gas price, not enough balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 20,
|
||||
gasFeeCap: big.NewInt(5),
|
||||
cost: &oneInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: false,
|
||||
enableFeemarket: 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, enough balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(5),
|
||||
cost: &fiftyInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
enableFeemarket: 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,
|
||||
name: "Higher cost, not enough balance w/ enableFeemarket",
|
||||
to: suite.address.String(),
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(5),
|
||||
cost: &hundredInt,
|
||||
from: suite.address.String(),
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: false,
|
||||
enableFeemarket: true,
|
||||
},
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() {
|
||||
amount = tc.cost.BigInt()
|
||||
}
|
||||
|
||||
if tc.dynamicTxFee {
|
||||
if tc.enableFeemarket {
|
||||
gasFeeCap = tc.gasFeeCap
|
||||
if tc.gasTipCap == nil {
|
||||
gasTipCap = oneInt.BigInt()
|
||||
@ -261,15 +261,15 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
|
||||
initBalance := sdk.NewInt((ethparams.InitialBaseFee + 10) * 105)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
gasLimit uint64
|
||||
gasPrice *sdk.Int
|
||||
gasFeeCap *big.Int
|
||||
gasTipCap *big.Int
|
||||
cost *sdk.Int
|
||||
accessList *ethtypes.AccessList
|
||||
expectPass bool
|
||||
dynamicTxFee bool
|
||||
name string
|
||||
gasLimit uint64
|
||||
gasPrice *sdk.Int
|
||||
gasFeeCap *big.Int
|
||||
gasTipCap *big.Int
|
||||
cost *sdk.Int
|
||||
accessList *ethtypes.AccessList
|
||||
expectPass bool
|
||||
enableFeemarket bool
|
||||
}{
|
||||
{
|
||||
name: "Enough balance",
|
||||
@ -321,51 +321,51 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
},
|
||||
// testcases with dynamicTxFee enabled.
|
||||
// testcases with enableFeemarket 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,
|
||||
name: "Invalid gasFeeCap w/ enableFeemarket",
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(1),
|
||||
gasTipCap: big.NewInt(1),
|
||||
cost: &oneInt,
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: false,
|
||||
enableFeemarket: true,
|
||||
},
|
||||
{
|
||||
name: "empty tip fee is valid to deduct",
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(ethparams.InitialBaseFee),
|
||||
gasTipCap: big.NewInt(1),
|
||||
cost: &oneInt,
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
dynamicTxFee: true,
|
||||
name: "empty tip fee is valid to deduct",
|
||||
gasLimit: 10,
|
||||
gasFeeCap: big.NewInt(ethparams.InitialBaseFee),
|
||||
gasTipCap: big.NewInt(1),
|
||||
cost: &oneInt,
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
enableFeemarket: 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 gasTipCap",
|
||||
gasLimit: 100,
|
||||
gasFeeCap: big.NewInt(ethparams.InitialBaseFee + 2),
|
||||
cost: &oneInt,
|
||||
accessList: ðtypes.AccessList{},
|
||||
expectPass: true,
|
||||
enableFeemarket: 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,
|
||||
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,
|
||||
enableFeemarket: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
suite.dynamicTxFee = tc.dynamicTxFee
|
||||
suite.enableFeemarket = tc.enableFeemarket
|
||||
suite.SetupTest()
|
||||
|
||||
var amount, gasPrice, gasFeeCap, gasTipCap *big.Int
|
||||
@ -373,7 +373,7 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
|
||||
amount = tc.cost.BigInt()
|
||||
}
|
||||
|
||||
if suite.dynamicTxFee {
|
||||
if suite.enableFeemarket {
|
||||
if tc.gasFeeCap != nil {
|
||||
gasFeeCap = tc.gasFeeCap
|
||||
}
|
||||
@ -407,12 +407,12 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
|
||||
evmtypes.DefaultEVMDenom,
|
||||
false,
|
||||
false,
|
||||
suite.dynamicTxFee, // london
|
||||
suite.enableFeemarket, // london
|
||||
)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.Require().NoError(err, "valid test %d failed", i)
|
||||
if tc.dynamicTxFee {
|
||||
if tc.enableFeemarket {
|
||||
baseFee := suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx)
|
||||
suite.Require().Equal(
|
||||
fees,
|
||||
@ -436,5 +436,5 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
|
||||
}
|
||||
})
|
||||
}
|
||||
suite.dynamicTxFee = false // reset flag
|
||||
suite.enableFeemarket = false // reset flag
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ func validateChainConfig(i interface{}) error {
|
||||
return cfg.Validate()
|
||||
}
|
||||
|
||||
// IsLondon returns if london hardfork is enabled.
|
||||
func IsLondon(ethConfig *params.ChainConfig, height int64) bool {
|
||||
rules := ethConfig.Rules(big.NewInt(height))
|
||||
return rules.IsLondon
|
||||
return ethConfig.IsLondon(big.NewInt(height))
|
||||
}
|
||||
|
@ -71,7 +71,8 @@ func (k Keeper) SetBlockGasUsed(ctx sdk.Context, gas uint64) {
|
||||
// Required by EIP1559 base fee calculation.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// GetLastBaseFee returns the last base fee value from the store.
|
||||
// GetBaseFee returns the last base fee value from the store.
|
||||
// returns nil if base fee is not enabled.
|
||||
func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.KeyPrefixBaseFee)
|
||||
|
Loading…
Reference in New Issue
Block a user