evm, rpc: disable BaseFee
for non London block (#662)
* disable basefee if not london block * add london block check in state transition * fix linter * add unit test * clean code * add changelog
This commit is contained in:
parent
c7a2fb97c7
commit
75d553674c
@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
### Features
|
||||
|
||||
* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version
|
||||
* (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
@ -359,7 +359,7 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
||||
}
|
||||
|
||||
var baseFee *big.Int
|
||||
if !feeMktParams.NoBaseFee {
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee {
|
||||
baseFee = ctd.feemarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
|
||||
@ -383,14 +383,14 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
||||
)
|
||||
}
|
||||
|
||||
if !feeMktParams.NoBaseFee && baseFee == nil {
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee == nil {
|
||||
return ctx, stacktrace.Propagate(
|
||||
sdkerrors.Wrap(evmtypes.ErrInvalidBaseFee, "base fee is supported but evm block context value is nil"),
|
||||
"address %s", coreMsg.From(),
|
||||
)
|
||||
}
|
||||
|
||||
if !feeMktParams.NoBaseFee && baseFee != nil && coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
|
||||
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee != nil && coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
|
||||
return ctx, stacktrace.Propagate(
|
||||
sdkerrors.Wrapf(evmtypes.ErrInvalidBaseFee, "max fee per gas less than block base fee (%s < %s)", coreMsg.GasFeeCap(), baseFee),
|
||||
"address %s", coreMsg.From(),
|
||||
|
@ -62,7 +62,7 @@ type Backend interface {
|
||||
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
||||
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
||||
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
||||
BaseFee() (*big.Int, error)
|
||||
BaseFee(height int64) (*big.Int, error)
|
||||
|
||||
// Filter API
|
||||
BloomStatus() (uint64, uint64)
|
||||
@ -238,7 +238,7 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
|
||||
ctx := types.ContextWithHeight(block.Height)
|
||||
|
||||
baseFee, err := e.BaseFee()
|
||||
baseFee, err := e.BaseFee(block.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -370,7 +370,7 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade
|
||||
e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
|
||||
}
|
||||
|
||||
baseFee, err := e.BaseFee()
|
||||
baseFee, err := e.BaseFee(resBlock.Block.Height)
|
||||
if err != nil {
|
||||
e.logger.Debug("HeaderByNumber BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
||||
return nil, err
|
||||
@ -398,7 +398,7 @@ func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, erro
|
||||
e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height)
|
||||
}
|
||||
|
||||
baseFee, err := e.BaseFee()
|
||||
baseFee, err := e.BaseFee(resBlock.Block.Height)
|
||||
if err != nil {
|
||||
e.logger.Debug("HeaderByHash BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
||||
return nil, err
|
||||
@ -710,7 +710,21 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
|
||||
return 0, err
|
||||
}
|
||||
|
||||
baseFee, err := e.BaseFee()
|
||||
height := blockNr.Int64()
|
||||
currentBlockNumber, _ := e.BlockNumber()
|
||||
switch blockNr {
|
||||
case types.EthLatestBlockNumber:
|
||||
if currentBlockNumber > 0 {
|
||||
height = int64(currentBlockNumber)
|
||||
}
|
||||
case types.EthPendingBlockNumber:
|
||||
if currentBlockNumber > 0 {
|
||||
height = int64(currentBlockNumber)
|
||||
}
|
||||
case types.EthEarliestBlockNumber:
|
||||
height = 1
|
||||
}
|
||||
baseFee, err := e.BaseFee(height)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -730,7 +744,7 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
|
||||
// From ContextWithHeight: if the provided height is 0,
|
||||
// it will return an empty context and the gRPC query will use
|
||||
// the latest block height for querying.
|
||||
res, err := e.queryClient.EstimateGas(types.ContextWithHeight(blockNr.Int64()), &req)
|
||||
res, err := e.queryClient.EstimateGas(types.ContextWithHeight(height), &req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -805,9 +819,14 @@ func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
|
||||
}
|
||||
|
||||
// BaseFee returns the base fee tracked by the Fee Market module. If the base fee is not enabled,
|
||||
// it returns the initial base fee amount.
|
||||
func (e *EVMBackend) BaseFee() (*big.Int, error) {
|
||||
res, err := e.queryClient.FeeMarket.BaseFee(e.ctx, &feemarkettypes.QueryBaseFeeRequest{})
|
||||
// it returns the initial base fee amount. Return nil if London is not activated.
|
||||
func (e *EVMBackend) BaseFee(height int64) (*big.Int, error) {
|
||||
cfg := e.ChainConfig()
|
||||
if !cfg.IsLondon(new(big.Int).SetInt64(height)) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
res, err := e.queryClient.FeeMarket.BaseFee(types.ContextWithHeight(height), &feemarkettypes.QueryBaseFeeRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -816,7 +835,7 @@ func (e *EVMBackend) BaseFee() (*big.Int, error) {
|
||||
return res.BaseFee.BigInt(), nil
|
||||
}
|
||||
|
||||
resParams, err := e.queryClient.FeeMarket.Params(e.ctx, &feemarkettypes.QueryParamsRequest{})
|
||||
resParams, err := e.queryClient.FeeMarket.Params(types.ContextWithHeight(height), &feemarkettypes.QueryParamsRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -587,7 +587,21 @@ func (e *PublicAPI) doCall(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseFee, err := e.backend.BaseFee()
|
||||
currentBlockNumber, _ := e.BlockNumber()
|
||||
height := blockNr.Int64()
|
||||
switch blockNr {
|
||||
case rpctypes.EthLatestBlockNumber:
|
||||
if currentBlockNumber > 0 {
|
||||
height = int64(currentBlockNumber)
|
||||
}
|
||||
case rpctypes.EthPendingBlockNumber:
|
||||
if currentBlockNumber > 0 {
|
||||
height = int64(currentBlockNumber)
|
||||
}
|
||||
case rpctypes.EthEarliestBlockNumber:
|
||||
height = 1
|
||||
}
|
||||
baseFee, err := e.backend.BaseFee(height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -680,7 +694,7 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseFee, err := e.backend.BaseFee()
|
||||
baseFee, err := e.backend.BaseFee(resBlock.Block.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -159,7 +159,10 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
|
||||
// get the latest signer according to the chain rules from the config
|
||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
var baseFee *big.Int
|
||||
if types.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||
baseFee = k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
|
||||
msg, err := tx.AsMessage(signer, baseFee)
|
||||
if err != nil {
|
||||
@ -368,7 +371,10 @@ func (k *Keeper) ApplyNativeMessage(msg core.Message) (*types.MsgEthereumTxRespo
|
||||
return nil, stacktrace.Propagate(err, "failed to obtain coinbase address")
|
||||
}
|
||||
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
var baseFee *big.Int
|
||||
if types.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||
baseFee = k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
}
|
||||
|
||||
tracer := types.NewTracer(k.tracer, msg, ethCfg, ctx.BlockHeight(), k.debug)
|
||||
evm := k.NewEVM(msg, ethCfg, params, coinbase, baseFee, tracer)
|
||||
|
@ -2,6 +2,9 @@ package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
@ -132,3 +135,8 @@ func validateChainConfig(i interface{}) error {
|
||||
|
||||
return cfg.Validate()
|
||||
}
|
||||
|
||||
func IsLondon(ethConfig *params.ChainConfig, height int64) bool {
|
||||
rules := ethConfig.Rules(big.NewInt(height))
|
||||
return rules.IsLondon
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package types
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -104,3 +106,32 @@ func TestValidateChainConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsLondon(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
height int64
|
||||
result bool
|
||||
}{
|
||||
{
|
||||
"Before london block",
|
||||
5,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"After london block",
|
||||
12_965_001,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"london block",
|
||||
12_965_000,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
ethConfig := params.MainnetChainConfig
|
||||
require.Equal(t, IsLondon(ethConfig, tc.height), tc.result)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user