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:
yihuang 2021-12-28 15:59:28 +08:00 committed by GitHub
parent d822fee5c1
commit eb17366dcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 436 additions and 335 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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()

View File

@ -8,7 +8,7 @@ import (
)
func (suite AnteTestSuite) TestSignatures() {
suite.dynamicTxFee = false
suite.enableFeemarket = false
suite.SetupTest() // reset
addr, privKey := tests.NewAddrKey()

View File

@ -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.

View File

@ -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, "", " ")

View File

@ -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())

View File

@ -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())
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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,
})
}

View File

@ -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")
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.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: &ethtypes.AccessList{},
expectPass: false,
dynamicTxFee: true,
name: "Invalid gasFeeCap w/ enableFeemarket",
gasLimit: 10,
gasFeeCap: big.NewInt(1),
gasTipCap: big.NewInt(1),
cost: &oneInt,
accessList: &ethtypes.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: &ethtypes.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: &ethtypes.AccessList{},
expectPass: true,
enableFeemarket: true,
},
{
name: "effectiveTip equal to gasTipCap",
gasLimit: 100,
gasFeeCap: big.NewInt(ethparams.InitialBaseFee + 2),
cost: &oneInt,
accessList: &ethtypes.AccessList{},
expectPass: true,
dynamicTxFee: true,
name: "effectiveTip equal to gasTipCap",
gasLimit: 100,
gasFeeCap: big.NewInt(ethparams.InitialBaseFee + 2),
cost: &oneInt,
accessList: &ethtypes.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: &ethtypes.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: &ethtypes.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
}

View File

@ -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))
}

View File

@ -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)