upgrade to ethermint v0.21.0 #99

Closed
0xmuralik wants to merge 384 commits from murali/update-fork into main
10 changed files with 236 additions and 198 deletions
Showing only changes of commit 286f919709 - Show all commits

View File

@ -294,12 +294,13 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
} }
// NOTE: pass in an empty coinbase address and nil tracer as we don't need them for the check below // NOTE: pass in an empty coinbase address and nil tracer as we don't need them for the check below
cfg := &evmtypes.EVMConfig{ cfg := &statedb.EVMConfig{
ChainConfig: ethCfg, ChainConfig: ethCfg,
Params: params, Params: params,
CoinBase: common.Address{}, CoinBase: common.Address{},
BaseFee: baseFee, BaseFee: baseFee,
} }
stateDB := statedb.New(ctx, ctd.evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes()))) stateDB := statedb.New(ctx, ctd.evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())))
evm := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evmtypes.NewNoOpTracer(), stateDB) evm := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evmtypes.NewNoOpTracer(), stateDB)

View File

@ -20,10 +20,12 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
tx "github.com/cosmos/cosmos-sdk/types/tx" tx "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/evmos/ethermint/x/evm/statedb" "github.com/evmos/ethermint/x/evm/statedb"
evmtypes "github.com/evmos/ethermint/x/evm/types" evmtypes "github.com/evmos/ethermint/x/evm/types"
evm "github.com/evmos/ethermint/x/evm/vm" evm "github.com/evmos/ethermint/x/evm/vm"
@ -42,7 +44,7 @@ type EVMKeeper interface {
statedb.Keeper statedb.Keeper
DynamicFeeEVMKeeper DynamicFeeEVMKeeper
NewEVM(ctx sdk.Context, msg core.Message, cfg *evmtypes.EVMConfig, tracer vm.EVMLogger, stateDB vm.StateDB) evm.EVM NewEVM(ctx sdk.Context, msg core.Message, cfg *statedb.EVMConfig, tracer vm.EVMLogger, stateDB vm.StateDB) evm.EVM
DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error
GetBalance(ctx sdk.Context, addr common.Address) *big.Int GetBalance(ctx sdk.Context, addr common.Address) *big.Int
ResetTransientGasUsed(ctx sdk.Context) ResetTransientGasUsed(ctx sdk.Context)

79
x/evm/keeper/config.go Normal file
View File

@ -0,0 +1,79 @@
// Copyright 2021 Evmos Foundation
// This file is part of Evmos' Ethermint library.
//
// The Ethermint library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The Ethermint library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
package keeper
import (
"math/big"
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/evmos/ethermint/x/evm/statedb"
"github.com/evmos/ethermint/x/evm/types"
)
// EVMConfig creates the EVMConfig based on current state
func (k *Keeper) EVMConfig(ctx sdk.Context, proposerAddress sdk.ConsAddress, chainID *big.Int) (*statedb.EVMConfig, error) {
params := k.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(chainID)
// get the coinbase address from the block proposer
coinbase, err := k.GetCoinbaseAddress(ctx, proposerAddress)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to obtain coinbase address")
}
baseFee := k.GetBaseFee(ctx, ethCfg)
return &statedb.EVMConfig{
Params: params,
ChainConfig: ethCfg,
CoinBase: coinbase,
BaseFee: baseFee,
}, nil
}
// TxConfig loads `TxConfig` from current transient storage
func (k *Keeper) TxConfig(ctx sdk.Context, txHash common.Hash) statedb.TxConfig {
return statedb.NewTxConfig(
common.BytesToHash(ctx.HeaderHash()), // BlockHash
txHash, // TxHash
uint(k.GetTxIndexTransient(ctx)), // TxIndex
uint(k.GetLogSizeTransient(ctx)), // LogIndex
)
}
// VMConfig creates an EVM configuration from the debug setting and the extra EIPs enabled on the
// module parameters. The config generated uses the default JumpTable from the EVM.
func (k Keeper) VMConfig(ctx sdk.Context, msg core.Message, cfg *statedb.EVMConfig, tracer vm.EVMLogger) vm.Config {
noBaseFee := true
if types.IsLondon(cfg.ChainConfig, ctx.BlockHeight()) {
noBaseFee = k.feeMarketKeeper.GetParams(ctx).NoBaseFee
}
var debug bool
if _, ok := tracer.(types.NoOpTracer); !ok {
debug = true
}
return vm.Config{
Debug: debug,
Tracer: tracer,
NoBaseFee: noBaseFee,
ExtraEips: cfg.Params.EIPs(),
}
}

90
x/evm/keeper/gas.go Normal file
View File

@ -0,0 +1,90 @@
// Copyright 2021 Evmos Foundation
// This file is part of Evmos' Ethermint library.
//
// The Ethermint library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The Ethermint library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
package keeper
import (
"math/big"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/params"
errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/evmos/ethermint/x/evm/types"
)
// GetEthIntrinsicGas returns the intrinsic gas cost for the transaction
func (k *Keeper) GetEthIntrinsicGas(ctx sdk.Context, msg core.Message, cfg *params.ChainConfig, isContractCreation bool) (uint64, error) {
height := big.NewInt(ctx.BlockHeight())
homestead := cfg.IsHomestead(height)
istanbul := cfg.IsIstanbul(height)
return core.IntrinsicGas(msg.Data(), msg.AccessList(), isContractCreation, homestead, istanbul)
}
// RefundGas transfers the leftover gas to the sender of the message, caped to half of the total gas
// consumed in the transaction. Additionally, the function sets the total gas consumed to the value
// returned by the EVM execution, thus ignoring the previous intrinsic gas consumed during in the
// AnteHandler.
func (k *Keeper) RefundGas(ctx sdk.Context, msg core.Message, leftoverGas uint64, denom string) error {
// Return EVM tokens for remaining gas, exchanged at the original rate.
remaining := new(big.Int).Mul(new(big.Int).SetUint64(leftoverGas), msg.GasPrice())
switch remaining.Sign() {
case -1:
// negative refund errors
return errorsmod.Wrapf(types.ErrInvalidRefund, "refunded amount value cannot be negative %d", remaining.Int64())
case 1:
// positive amount refund
refundedCoins := sdk.Coins{sdk.NewCoin(denom, sdkmath.NewIntFromBigInt(remaining))}
// refund to sender from the fee collector module account, which is the escrow account in charge of collecting tx fees
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, authtypes.FeeCollectorName, msg.From().Bytes(), refundedCoins)
if err != nil {
err = errorsmod.Wrapf(errortypes.ErrInsufficientFunds, "fee collector account failed to refund fees: %s", err.Error())
return errorsmod.Wrapf(err, "failed to refund %d leftover gas (%s)", leftoverGas, refundedCoins.String())
}
default:
// no refund, consume gas and update the tx gas meter
}
return nil
}
// ResetGasMeterAndConsumeGas reset first the gas meter consumed value to zero and set it back to the new value
// 'gasUsed'
func (k *Keeper) ResetGasMeterAndConsumeGas(ctx sdk.Context, gasUsed uint64) {
// reset the gas count
ctx.GasMeter().RefundGas(ctx.GasMeter().GasConsumed(), "reset the gas count")
ctx.GasMeter().ConsumeGas(gasUsed, "apply evm transaction")
}
// GasToRefund calculates the amount of gas the state machine should refund to the sender. It is
// capped by the refund quotient value.
// Note: do not pass 0 to refundQuotient
func GasToRefund(availableRefund, gasConsumed, refundQuotient uint64) uint64 {
// Apply refund counter
refund := gasConsumed / refundQuotient
if refund > availableRefund {
return availableRefund
}
return refund
}

View File

@ -532,7 +532,7 @@ func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest)
// traceTx do trace on one transaction, it returns a tuple: (traceResult, nextLogIndex, error). // traceTx do trace on one transaction, it returns a tuple: (traceResult, nextLogIndex, error).
func (k *Keeper) traceTx( func (k *Keeper) traceTx(
ctx sdk.Context, ctx sdk.Context,
cfg *types.EVMConfig, cfg *statedb.EVMConfig,
txConfig statedb.TxConfig, txConfig statedb.TxConfig,
signer ethtypes.Signer, signer ethtypes.Signer,
tx *ethtypes.Transaction, tx *ethtypes.Transaction,

View File

@ -18,15 +18,10 @@ package keeper
import ( import (
"math/big" "math/big"
sdkmath "cosmossdk.io/math"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
errorsmod "cosmossdk.io/errors" errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
ethermint "github.com/evmos/ethermint/types" ethermint "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/evm/statedb" "github.com/evmos/ethermint/x/evm/statedb"
@ -41,48 +36,6 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
// GasToRefund calculates the amount of gas the state machine should refund to the sender. It is
// capped by the refund quotient value.
// Note: do not pass 0 to refundQuotient
func GasToRefund(availableRefund, gasConsumed, refundQuotient uint64) uint64 {
// Apply refund counter
refund := gasConsumed / refundQuotient
if refund > availableRefund {
return availableRefund
}
return refund
}
// EVMConfig creates the EVMConfig based on current state
func (k *Keeper) EVMConfig(ctx sdk.Context, proposerAddress sdk.ConsAddress, chainID *big.Int) (*types.EVMConfig, error) {
params := k.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(chainID)
// get the coinbase address from the block proposer
coinbase, err := k.GetCoinbaseAddress(ctx, proposerAddress)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to obtain coinbase address")
}
baseFee := k.GetBaseFee(ctx, ethCfg)
return &types.EVMConfig{
Params: params,
ChainConfig: ethCfg,
CoinBase: coinbase,
BaseFee: baseFee,
}, nil
}
// TxConfig loads `TxConfig` from current transient storage
func (k *Keeper) TxConfig(ctx sdk.Context, txHash common.Hash) statedb.TxConfig {
return statedb.NewTxConfig(
common.BytesToHash(ctx.HeaderHash()), // BlockHash
txHash, // TxHash
uint(k.GetTxIndexTransient(ctx)), // TxIndex
uint(k.GetLogSizeTransient(ctx)), // LogIndex
)
}
// NewEVM generates a go-ethereum VM from the provided Message fields and the chain parameters // NewEVM generates a go-ethereum VM from the provided Message fields and the chain parameters
// (ChainConfig and module Params). It additionally sets the validator operator address as the // (ChainConfig and module Params). It additionally sets the validator operator address as the
// coinbase address to make it available for the COINBASE opcode, even though there is no // coinbase address to make it available for the COINBASE opcode, even though there is no
@ -95,7 +48,7 @@ func (k *Keeper) TxConfig(ctx sdk.Context, txHash common.Hash) statedb.TxConfig
func (k *Keeper) NewEVM( func (k *Keeper) NewEVM(
ctx sdk.Context, ctx sdk.Context,
msg core.Message, msg core.Message,
cfg *types.EVMConfig, cfg *statedb.EVMConfig,
tracer vm.EVMLogger, tracer vm.EVMLogger,
stateDB vm.StateDB, stateDB vm.StateDB,
) evm.EVM { ) evm.EVM {
@ -120,27 +73,6 @@ func (k *Keeper) NewEVM(
return k.evmConstructor(blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.customPrecompiles) return k.evmConstructor(blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.customPrecompiles)
} }
// VMConfig creates an EVM configuration from the debug setting and the extra EIPs enabled on the
// module parameters. The config generated uses the default JumpTable from the EVM.
func (k Keeper) VMConfig(ctx sdk.Context, msg core.Message, cfg *types.EVMConfig, tracer vm.EVMLogger) vm.Config {
noBaseFee := true
if types.IsLondon(cfg.ChainConfig, ctx.BlockHeight()) {
noBaseFee = k.feeMarketKeeper.GetParams(ctx).NoBaseFee
}
var debug bool
if _, ok := tracer.(types.NoOpTracer); !ok {
debug = true
}
return vm.Config{
Debug: debug,
Tracer: tracer,
NoBaseFee: noBaseFee,
ExtraEips: cfg.Params.EIPs(),
}
}
// GetHashFn implements vm.GetHashFunc for Ethermint. It handles 3 cases: // GetHashFn implements vm.GetHashFunc for Ethermint. It handles 3 cases:
// 1. The requested height matches the current height from context (and thus same epoch number) // 1. The requested height matches the current height from context (and thus same epoch number)
// 2. The requested height is from an previous height from the same chain epoch // 2. The requested height is from an previous height from the same chain epoch
@ -329,6 +261,17 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t
return res, nil return res, nil
} }
// ApplyMessage calls ApplyMessageWithConfig with an empty TxConfig.
func (k *Keeper) ApplyMessage(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool) (*types.MsgEthereumTxResponse, error) {
cfg, err := k.EVMConfig(ctx, sdk.ConsAddress(ctx.BlockHeader().ProposerAddress), k.eip155ChainID)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to load evm config")
}
txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash()))
return k.ApplyMessageWithConfig(ctx, msg, tracer, commit, cfg, txConfig)
}
// ApplyMessageWithConfig computes the new state by applying the given message against the existing state. // ApplyMessageWithConfig computes the new state by applying the given message against the existing state.
// If the message fails, the VM execution error with the reason will be returned to the client // If the message fails, the VM execution error with the reason will be returned to the client
// and the transaction won't be committed to the store. // and the transaction won't be committed to the store.
@ -371,7 +314,7 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
msg core.Message, msg core.Message,
tracer vm.EVMLogger, tracer vm.EVMLogger,
commit bool, commit bool,
cfg *types.EVMConfig, cfg *statedb.EVMConfig,
txConfig statedb.TxConfig, txConfig statedb.TxConfig,
) (*types.MsgEthereumTxResponse, error) { ) (*types.MsgEthereumTxResponse, error) {
var ( var (
@ -485,83 +428,3 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
Hash: txConfig.TxHash.Hex(), Hash: txConfig.TxHash.Hex(),
}, nil }, nil
} }
// ApplyMessage calls ApplyMessageWithConfig with default EVMConfig
func (k *Keeper) ApplyMessage(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool) (*types.MsgEthereumTxResponse, error) {
cfg, err := k.EVMConfig(ctx, sdk.ConsAddress(ctx.BlockHeader().ProposerAddress), k.eip155ChainID)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to load evm config")
}
txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash()))
return k.ApplyMessageWithConfig(ctx, msg, tracer, commit, cfg, txConfig)
}
// GetEthIntrinsicGas returns the intrinsic gas cost for the transaction
func (k *Keeper) GetEthIntrinsicGas(ctx sdk.Context, msg core.Message, cfg *params.ChainConfig, isContractCreation bool) (uint64, error) {
height := big.NewInt(ctx.BlockHeight())
homestead := cfg.IsHomestead(height)
istanbul := cfg.IsIstanbul(height)
return core.IntrinsicGas(msg.Data(), msg.AccessList(), isContractCreation, homestead, istanbul)
}
// RefundGas transfers the leftover gas to the sender of the message, caped to half of the total gas
// consumed in the transaction. Additionally, the function sets the total gas consumed to the value
// returned by the EVM execution, thus ignoring the previous intrinsic gas consumed during in the
// AnteHandler.
func (k *Keeper) RefundGas(ctx sdk.Context, msg core.Message, leftoverGas uint64, denom string) error {
// Return EVM tokens for remaining gas, exchanged at the original rate.
remaining := new(big.Int).Mul(new(big.Int).SetUint64(leftoverGas), msg.GasPrice())
switch remaining.Sign() {
case -1:
// negative refund errors
return errorsmod.Wrapf(types.ErrInvalidRefund, "refunded amount value cannot be negative %d", remaining.Int64())
case 1:
// positive amount refund
refundedCoins := sdk.Coins{sdk.NewCoin(denom, sdkmath.NewIntFromBigInt(remaining))}
// refund to sender from the fee collector module account, which is the escrow account in charge of collecting tx fees
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, authtypes.FeeCollectorName, msg.From().Bytes(), refundedCoins)
if err != nil {
err = errorsmod.Wrapf(errortypes.ErrInsufficientFunds, "fee collector account failed to refund fees: %s", err.Error())
return errorsmod.Wrapf(err, "failed to refund %d leftover gas (%s)", leftoverGas, refundedCoins.String())
}
default:
// no refund, consume gas and update the tx gas meter
}
return nil
}
// ResetGasMeterAndConsumeGas reset first the gas meter consumed value to zero and set it back to the new value
// 'gasUsed'
func (k *Keeper) ResetGasMeterAndConsumeGas(ctx sdk.Context, gasUsed uint64) {
// reset the gas count
ctx.GasMeter().RefundGas(ctx.GasMeter().GasConsumed(), "reset the gas count")
ctx.GasMeter().ConsumeGas(gasUsed, "apply evm transaction")
}
// GetProposerAddress returns current block proposer's address when provided proposer address is empty.
func GetProposerAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) sdk.ConsAddress {
if len(proposerAddress) == 0 {
proposerAddress = ctx.BlockHeader().ProposerAddress
}
return proposerAddress
}
// GetCoinbaseAddress returns the block proposer's validator operator address.
func (k Keeper) GetCoinbaseAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) (common.Address, error) {
validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, GetProposerAddress(ctx, proposerAddress))
if !found {
return common.Address{}, errorsmod.Wrapf(
stakingtypes.ErrNoValidatorFound,
"failed to retrieve validator from block proposer address %s",
proposerAddress.String(),
)
}
coinbase := common.BytesToAddress(validator.GetOperator())
return coinbase, nil
}

View File

@ -571,7 +571,7 @@ func (suite *KeeperTestSuite) TestApplyMessageWithConfig() {
msg core.Message msg core.Message
err error err error
expectedGasUsed uint64 expectedGasUsed uint64
config *types.EVMConfig config *statedb.EVMConfig
keeperParams types.Params keeperParams types.Params
signer ethtypes.Signer signer ethtypes.Signer
vmdb *statedb.StateDB vmdb *statedb.StateDB
@ -660,13 +660,10 @@ func (suite *KeeperTestSuite) TestApplyMessageWithConfig() {
suite.Require().Equal(expectedGasUsed, res.GasUsed) suite.Require().Equal(expectedGasUsed, res.GasUsed)
}) })
} }
} }
func (suite *KeeperTestSuite) createContractGethMsg(nonce uint64, signer ethtypes.Signer, cfg *params.ChainConfig, gasPrice *big.Int) (core.Message, error) { func (suite *KeeperTestSuite) createContractGethMsg(nonce uint64, signer ethtypes.Signer, cfg *params.ChainConfig, gasPrice *big.Int) (core.Message, error) {
ethMsg, err := suite.createContractMsgTx(nonce, signer, cfg, gasPrice) ethMsg, err := suite.createContractMsgTx(nonce, signer, cfg, gasPrice)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -676,7 +673,6 @@ func (suite *KeeperTestSuite) createContractGethMsg(nonce uint64, signer ethtype
} }
func (suite *KeeperTestSuite) createContractMsgTx(nonce uint64, signer ethtypes.Signer, cfg *params.ChainConfig, gasPrice *big.Int) (*types.MsgEthereumTx, error) { func (suite *KeeperTestSuite) createContractMsgTx(nonce uint64, signer ethtypes.Signer, cfg *params.ChainConfig, gasPrice *big.Int) (*types.MsgEthereumTx, error) {
contractCreateTx := &ethtypes.AccessListTx{ contractCreateTx := &ethtypes.AccessListTx{
GasPrice: gasPrice, GasPrice: gasPrice,
Gas: params.TxGasContractCreation, Gas: params.TxGasContractCreation,

View File

@ -18,19 +18,43 @@ package keeper
import ( import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types"
errorsmod "cosmossdk.io/errors" errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math" sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors" errortypes "github.com/cosmos/cosmos-sdk/types/errors"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante" authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/evmos/ethermint/x/evm/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types"
) )
// GetCoinbaseAddress returns the block proposer's validator operator address.
func (k Keeper) GetCoinbaseAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) (common.Address, error) {
validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, GetProposerAddress(ctx, proposerAddress))
if !found {
return common.Address{}, errorsmod.Wrapf(
stakingtypes.ErrNoValidatorFound,
"failed to retrieve validator from block proposer address %s",
proposerAddress.String(),
)
}
coinbase := common.BytesToAddress(validator.GetOperator())
return coinbase, nil
}
// GetProposerAddress returns current block proposer's address when provided proposer address is empty.
func GetProposerAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) sdk.ConsAddress {
if len(proposerAddress) == 0 {
proposerAddress = ctx.BlockHeader().ProposerAddress
}
return proposerAddress
}
// DeductTxCostsFromUserBalance deducts the fees from the user balance. Returns an // DeductTxCostsFromUserBalance deducts the fees from the user balance. Returns an
// error if the specified sender address does not exist or the account balance is not sufficient. // error if the specified sender address does not exist or the account balance is not sufficient.
func (k *Keeper) DeductTxCostsFromUserBalance( func (k *Keeper) DeductTxCostsFromUserBalance(
@ -56,7 +80,7 @@ func (k *Keeper) DeductTxCostsFromUserBalance(
// gas limit is not reached, the gas limit is higher than the intrinsic gas and that the // gas limit is not reached, the gas limit is higher than the intrinsic gas and that the
// base fee is higher than the gas fee cap. // base fee is higher than the gas fee cap.
func VerifyFee( func VerifyFee(
txData evmtypes.TxData, txData types.TxData,
denom string, denom string,
baseFee *big.Int, baseFee *big.Int,
homestead, istanbul, isCheckTx bool, homestead, istanbul, isCheckTx bool,
@ -107,7 +131,7 @@ func VerifyFee(
// sender has enough funds to pay for the fees and value of the transaction. // sender has enough funds to pay for the fees and value of the transaction.
func CheckSenderBalance( func CheckSenderBalance(
balance sdkmath.Int, balance sdkmath.Int,
txData evmtypes.TxData, txData types.TxData,
) error { ) error {
cost := txData.Cost() cost := txData.Cost()

View File

@ -15,7 +15,13 @@
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE // along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
package statedb package statedb
import "github.com/ethereum/go-ethereum/common" import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/evmos/ethermint/x/evm/types"
)
// TxConfig encapulates the readonly information of current tx for `StateDB`. // TxConfig encapulates the readonly information of current tx for `StateDB`.
type TxConfig struct { type TxConfig struct {
@ -45,3 +51,12 @@ func NewEmptyTxConfig(bhash common.Hash) TxConfig {
LogIndex: 0, LogIndex: 0,
} }
} }
// EVMConfig encapsulates common parameters needed to create an EVM to execute a message
// It's mainly to reduce the number of method parameters
type EVMConfig struct {
Params types.Params
ChainConfig *params.ChainConfig
CoinBase common.Address
BaseFee *big.Int
}

View File

@ -1,32 +0,0 @@
// Copyright 2021 Evmos Foundation
// This file is part of Evmos' Ethermint library.
//
// The Ethermint library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The Ethermint library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
package types
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
)
// EVMConfig encapsulates common parameters needed to create an EVM to execute a message
// It's mainly to reduce the number of method parameters
type EVMConfig struct {
Params Params
ChainConfig *params.ChainConfig
CoinBase common.Address
BaseFee *big.Int
}