upgrade to ethermint v0.21.0 #99
@ -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
|
||||
cfg := &evmtypes.EVMConfig{
|
||||
cfg := &statedb.EVMConfig{
|
||||
ChainConfig: ethCfg,
|
||||
Params: params,
|
||||
CoinBase: common.Address{},
|
||||
BaseFee: baseFee,
|
||||
}
|
||||
|
||||
stateDB := statedb.New(ctx, ctd.evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())))
|
||||
evm := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evmtypes.NewNoOpTracer(), stateDB)
|
||||
|
||||
|
@ -20,10 +20,12 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
tx "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
evm "github.com/evmos/ethermint/x/evm/vm"
|
||||
@ -42,7 +44,7 @@ type EVMKeeper interface {
|
||||
statedb.Keeper
|
||||
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
|
||||
GetBalance(ctx sdk.Context, addr common.Address) *big.Int
|
||||
ResetTransientGasUsed(ctx sdk.Context)
|
||||
|
79
x/evm/keeper/config.go
Normal file
79
x/evm/keeper/config.go
Normal 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
90
x/evm/keeper/gas.go
Normal 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
|
||||
}
|
@ -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).
|
||||
func (k *Keeper) traceTx(
|
||||
ctx sdk.Context,
|
||||
cfg *types.EVMConfig,
|
||||
cfg *statedb.EVMConfig,
|
||||
txConfig statedb.TxConfig,
|
||||
signer ethtypes.Signer,
|
||||
tx *ethtypes.Transaction,
|
||||
|
@ -18,15 +18,10 @@ package keeper
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
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"
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
@ -41,48 +36,6 @@ import (
|
||||
"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
|
||||
// (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
|
||||
@ -95,7 +48,7 @@ func (k *Keeper) TxConfig(ctx sdk.Context, txHash common.Hash) statedb.TxConfig
|
||||
func (k *Keeper) NewEVM(
|
||||
ctx sdk.Context,
|
||||
msg core.Message,
|
||||
cfg *types.EVMConfig,
|
||||
cfg *statedb.EVMConfig,
|
||||
tracer vm.EVMLogger,
|
||||
stateDB vm.StateDB,
|
||||
) evm.EVM {
|
||||
@ -120,27 +73,6 @@ func (k *Keeper) NewEVM(
|
||||
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:
|
||||
// 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
|
||||
@ -329,6 +261,17 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t
|
||||
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.
|
||||
// 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.
|
||||
@ -371,7 +314,7 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
|
||||
msg core.Message,
|
||||
tracer vm.EVMLogger,
|
||||
commit bool,
|
||||
cfg *types.EVMConfig,
|
||||
cfg *statedb.EVMConfig,
|
||||
txConfig statedb.TxConfig,
|
||||
) (*types.MsgEthereumTxResponse, error) {
|
||||
var (
|
||||
@ -485,83 +428,3 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
|
||||
Hash: txConfig.TxHash.Hex(),
|
||||
}, 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
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ func (suite *KeeperTestSuite) TestApplyMessageWithConfig() {
|
||||
msg core.Message
|
||||
err error
|
||||
expectedGasUsed uint64
|
||||
config *types.EVMConfig
|
||||
config *statedb.EVMConfig
|
||||
keeperParams types.Params
|
||||
signer ethtypes.Signer
|
||||
vmdb *statedb.StateDB
|
||||
@ -660,13 +660,10 @@ func (suite *KeeperTestSuite) TestApplyMessageWithConfig() {
|
||||
suite.Require().Equal(expectedGasUsed, res.GasUsed)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if err != nil {
|
||||
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) {
|
||||
|
||||
contractCreateTx := ðtypes.AccessListTx{
|
||||
GasPrice: gasPrice,
|
||||
Gas: params.TxGasContractCreation,
|
||||
|
@ -18,19 +18,43 @@ package keeper
|
||||
import (
|
||||
"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"
|
||||
sdkmath "cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
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/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/evmos/ethermint/x/evm/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
|
||||
// error if the specified sender address does not exist or the account balance is not sufficient.
|
||||
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
|
||||
// base fee is higher than the gas fee cap.
|
||||
func VerifyFee(
|
||||
txData evmtypes.TxData,
|
||||
txData types.TxData,
|
||||
denom string,
|
||||
baseFee *big.Int,
|
||||
homestead, istanbul, isCheckTx bool,
|
||||
@ -107,7 +131,7 @@ func VerifyFee(
|
||||
// sender has enough funds to pay for the fees and value of the transaction.
|
||||
func CheckSenderBalance(
|
||||
balance sdkmath.Int,
|
||||
txData evmtypes.TxData,
|
||||
txData types.TxData,
|
||||
) error {
|
||||
cost := txData.Cost()
|
||||
|
||||
|
@ -15,7 +15,13 @@
|
||||
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
|
||||
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`.
|
||||
type TxConfig struct {
|
||||
@ -45,3 +51,12 @@ func NewEmptyTxConfig(bhash common.Hash) TxConfig {
|
||||
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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user