From bb91d8d93d1cd5746479102140d5840533be085b Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:24:08 -0400 Subject: [PATCH] ante, evm: fix panic when checking `BlockGasMeter` (#120) * ante, evm: fix panic when checking BlockGasMeter * update block gas limit function --- app/ante/eth.go | 15 +++++++++++---- ethereum/rpc/eth_api.go | 2 +- tests/rpc/rpc_test.go | 4 +++- types/block.go | 25 +++++++++++++++++++++++++ x/evm/keeper/state_transition.go | 3 ++- x/evm/types/protocol.go | 9 --------- 6 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 types/block.go delete mode 100644 x/evm/types/protocol.go diff --git a/app/ante/eth.go b/app/ante/eth.go index 6c686ee8..b2d404d6 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -7,6 +7,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + ethermint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" "github.com/ethereum/go-ethereum/common" @@ -296,10 +297,16 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula ctx.GasMeter().ConsumeGas(intrinsicGas, "intrinsic gas") } - // generate a copy of the gas pool (i.e block gas meter) to see if we've run out of gas for this block - // if current gas consumed is greater than the limit, this funcion panics and the error is recovered on the Baseapp - gasPool := sdk.NewGasMeter(ctx.BlockGasMeter().Limit()) - gasPool.ConsumeGas(ctx.GasMeter().GasConsumedToLimit(), "gas pool check") + // TODO: deprecate after https://github.com/cosmos/cosmos-sdk/issues/9514 is fixed on SDK + blockGasLimit := ethermint.BlockGasLimit(ctx) + + // NOTE: safety check + if blockGasLimit > 0 { + // generate a copy of the gas pool (i.e block gas meter) to see if we've run out of gas for this block + // if current gas consumed is greater than the limit, this funcion panics and the error is recovered on the Baseapp + gasPool := sdk.NewGasMeter(blockGasLimit) + gasPool.ConsumeGas(ctx.GasMeter().GasConsumedToLimit(), "gas pool check") + } // we know that we have enough gas on the pool to cover the intrinsic gas // set up the updated context to the evm Keeper diff --git a/ethereum/rpc/eth_api.go b/ethereum/rpc/eth_api.go index 7237b959..cda1ba4a 100644 --- a/ethereum/rpc/eth_api.go +++ b/ethereum/rpc/eth_api.go @@ -96,7 +96,7 @@ func (e *PublicEthAPI) ClientCtx() client.Context { // ProtocolVersion returns the supported Ethereum protocol version. func (e *PublicEthAPI) ProtocolVersion() hexutil.Uint { e.logger.Debugln("eth_protocolVersion") - return hexutil.Uint(evmtypes.ProtocolVersion) + return hexutil.Uint(ethermint.ProtocolVersion) } // ChainId returns the chain's identifier in hex format diff --git a/tests/rpc/rpc_test.go b/tests/rpc/rpc_test.go index c038f6c7..b5203d3b 100644 --- a/tests/rpc/rpc_test.go +++ b/tests/rpc/rpc_test.go @@ -20,7 +20,9 @@ import ( "github.com/stretchr/testify/require" rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types" + ethermint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" + ethcmn "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -230,7 +232,7 @@ func TestEth_GetTransactionLogs(t *testing.T) { } func TestEth_protocolVersion(t *testing.T) { - expectedRes := hexutil.Uint(evmtypes.ProtocolVersion) + expectedRes := hexutil.Uint(ethermint.ProtocolVersion) rpcRes := call(t, "eth_protocolVersion", []string{}) diff --git a/types/block.go b/types/block.go new file mode 100644 index 00000000..cf48b8df --- /dev/null +++ b/types/block.go @@ -0,0 +1,25 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +// BlockGasLimit returns the max gas (limit) defined in the block gas meter. If the meter is not +// set, it returns the max gas from the application consensus params. +// NOTE: see https://github.com/cosmos/cosmos-sdk/issues/9514 for full reference +func BlockGasLimit(ctx sdk.Context) uint64 { + blockGasMeter := ctx.BlockGasMeter() + if blockGasMeter != nil { + return blockGasMeter.Limit() + } + + cp := ctx.ConsensusParams() + if cp == nil || cp.Block == nil { + return 0 + } + + maxGas := cp.Block.MaxGas + if maxGas > 0 { + return uint64(maxGas) + } + + return 0 +} diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index d9fba220..9f6e296c 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -14,6 +14,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + ethermint "github.com/cosmos/ethermint/types" "github.com/cosmos/ethermint/x/evm/types" "github.com/ethereum/go-ethereum/common" @@ -30,7 +31,7 @@ func (k *Keeper) NewEVM(msg core.Message, config *params.ChainConfig) *vm.EVM { Transfer: core.Transfer, GetHash: k.GetHashFn(), Coinbase: common.Address{}, // there's no beneficiary since we're not mining - GasLimit: k.ctx.BlockGasMeter().Limit(), + GasLimit: ethermint.BlockGasLimit(k.ctx), BlockNumber: big.NewInt(k.ctx.BlockHeight()), Time: big.NewInt(k.ctx.BlockHeader().Time.Unix()), Difficulty: big.NewInt(0), // unused. Only required in PoW context diff --git a/x/evm/types/protocol.go b/x/evm/types/protocol.go deleted file mode 100644 index 580c344c..00000000 --- a/x/evm/types/protocol.go +++ /dev/null @@ -1,9 +0,0 @@ -package types - -// Constants to match up protocol versions and messages -const ( - eth65 = 65 - - // ProtocolVersion is the latest supported version of the eth protocol. - ProtocolVersion = eth65 -)