forked from cerc-io/laconicd-deprecated
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
|
### Features
|
||||||
|
|
||||||
* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version
|
* (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
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
|||||||
}
|
}
|
||||||
|
|
||||||
var baseFee *big.Int
|
var baseFee *big.Int
|
||||||
if !feeMktParams.NoBaseFee {
|
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee {
|
||||||
baseFee = ctd.feemarketKeeper.GetBaseFee(ctx)
|
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(
|
return ctx, stacktrace.Propagate(
|
||||||
sdkerrors.Wrap(evmtypes.ErrInvalidBaseFee, "base fee is supported but evm block context value is nil"),
|
sdkerrors.Wrap(evmtypes.ErrInvalidBaseFee, "base fee is supported but evm block context value is nil"),
|
||||||
"address %s", coreMsg.From(),
|
"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(
|
return ctx, stacktrace.Propagate(
|
||||||
sdkerrors.Wrapf(evmtypes.ErrInvalidBaseFee, "max fee per gas less than block base fee (%s < %s)", coreMsg.GasFeeCap(), baseFee),
|
sdkerrors.Wrapf(evmtypes.ErrInvalidBaseFee, "max fee per gas less than block base fee (%s < %s)", coreMsg.GasFeeCap(), baseFee),
|
||||||
"address %s", coreMsg.From(),
|
"address %s", coreMsg.From(),
|
||||||
|
@ -62,7 +62,7 @@ type Backend interface {
|
|||||||
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
||||||
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
||||||
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
||||||
BaseFee() (*big.Int, error)
|
BaseFee(height int64) (*big.Int, error)
|
||||||
|
|
||||||
// Filter API
|
// Filter API
|
||||||
BloomStatus() (uint64, uint64)
|
BloomStatus() (uint64, uint64)
|
||||||
@ -238,7 +238,7 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
|||||||
|
|
||||||
ctx := types.ContextWithHeight(block.Height)
|
ctx := types.ContextWithHeight(block.Height)
|
||||||
|
|
||||||
baseFee, err := e.BaseFee()
|
baseFee, err := e.BaseFee(block.Height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
|
||||||
}
|
}
|
||||||
|
|
||||||
baseFee, err := e.BaseFee()
|
baseFee, err := e.BaseFee(resBlock.Block.Height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.logger.Debug("HeaderByNumber BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
e.logger.Debug("HeaderByNumber BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
||||||
return nil, err
|
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)
|
e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height)
|
||||||
}
|
}
|
||||||
|
|
||||||
baseFee, err := e.BaseFee()
|
baseFee, err := e.BaseFee(resBlock.Block.Height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.logger.Debug("HeaderByHash BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
e.logger.Debug("HeaderByHash BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -710,7 +710,21 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
|
|||||||
return 0, err
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -730,7 +744,7 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
|
|||||||
// From ContextWithHeight: if the provided height is 0,
|
// From ContextWithHeight: if the provided height is 0,
|
||||||
// it will return an empty context and the gRPC query will use
|
// it will return an empty context and the gRPC query will use
|
||||||
// the latest block height for querying.
|
// 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 {
|
if err != nil {
|
||||||
return 0, err
|
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,
|
// 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.
|
// it returns the initial base fee amount. Return nil if London is not activated.
|
||||||
func (e *EVMBackend) BaseFee() (*big.Int, error) {
|
func (e *EVMBackend) BaseFee(height int64) (*big.Int, error) {
|
||||||
res, err := e.queryClient.FeeMarket.BaseFee(e.ctx, &feemarkettypes.QueryBaseFeeRequest{})
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -816,7 +835,7 @@ func (e *EVMBackend) BaseFee() (*big.Int, error) {
|
|||||||
return res.BaseFee.BigInt(), nil
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -587,7 +587,21 @@ func (e *PublicAPI) doCall(
|
|||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -680,7 +694,7 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
baseFee, err := e.backend.BaseFee()
|
baseFee, err := e.backend.BaseFee(resBlock.Block.Height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// get the latest signer according to the chain rules from the config
|
||||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
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)
|
msg, err := tx.AsMessage(signer, baseFee)
|
||||||
if err != nil {
|
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")
|
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)
|
tracer := types.NewTracer(k.tracer, msg, ethCfg, ctx.BlockHeight(), k.debug)
|
||||||
evm := k.NewEVM(msg, ethCfg, params, coinbase, baseFee, tracer)
|
evm := k.NewEVM(msg, ethCfg, params, coinbase, baseFee, tracer)
|
||||||
|
@ -2,6 +2,9 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
@ -132,3 +135,8 @@ func validateChainConfig(i interface{}) error {
|
|||||||
|
|
||||||
return cfg.Validate()
|
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 (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
"github.com/stretchr/testify/require"
|
"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