diff --git a/CHANGELOG.md b/CHANGELOG.md index 05f3b27d4..7a1ae768b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1889](https://github.com/NibiruChain/nibiru/pull/1889) - feat: implemented basic evm tx methods - [#1895](https://github.com/NibiruChain/nibiru/pull/1895) - refactor(geth): Reference go-ethereum as a submodule for easier change tracking with upstream - [#1901](https://github.com/NibiruChain/nibiru/pull/1901) - test(evm): more e2e test contracts for edge cases +- [#1909](https://github.com/NibiruChain/nibiru/pull/1909) - chore(evm): set is_london true by default and removed from config #### Dapp modules: perp, spot, oracle, etc diff --git a/app/evmante_eth.go b/app/evmante_eth.go index 3b4c722df..256ca93f3 100644 --- a/app/evmante_eth.go +++ b/app/evmante_eth.go @@ -157,7 +157,7 @@ func (anteDec AnteDecEthGasConsume) AnteHandle( // Use the lowest priority of all the messages as the final one. minPriority := int64(math.MaxInt64) - baseFee := anteDec.EvmKeeper.GetBaseFee(ctx, ethCfg) + baseFee := anteDec.EvmKeeper.GetBaseFee(ctx) for _, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evm.MsgEthereumTx) @@ -284,7 +284,7 @@ func (ctd CanTransferDecorator) AnteHandle( return ctx, errors.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evm.MsgEthereumTx)(nil)) } - baseFee := ctd.EvmKeeper.GetBaseFee(ctx, ethCfg) + baseFee := ctd.EvmKeeper.GetBaseFee(ctx) coreMsg, err := msgEthTx.AsMessage(signer, baseFee) if err != nil { @@ -294,20 +294,18 @@ func (ctd CanTransferDecorator) AnteHandle( ) } - if evm.IsLondon(ethCfg, ctx.BlockHeight()) { - if baseFee == nil { - return ctx, errors.Wrap( - evm.ErrInvalidBaseFee, - "base fee is supported but evm block context value is nil", - ) - } - if coreMsg.GasFeeCap().Cmp(baseFee) < 0 { - return ctx, errors.Wrapf( - errortypes.ErrInsufficientFee, - "max fee per gas less than block base fee (%s < %s)", - coreMsg.GasFeeCap(), baseFee, - ) - } + if baseFee == nil { + return ctx, errors.Wrap( + evm.ErrInvalidBaseFee, + "base fee is supported but evm block context value is nil", + ) + } + if coreMsg.GasFeeCap().Cmp(baseFee) < 0 { + return ctx, errors.Wrapf( + errortypes.ErrInsufficientFee, + "max fee per gas less than block base fee (%s < %s)", + coreMsg.GasFeeCap(), baseFee, + ) } // NOTE: pass in an empty coinbase address and nil tracer as we don't need them for the check below diff --git a/app/evmante_fee_checker.go b/app/evmante_fee_checker.go index 1583ebb88..5299e0eb1 100644 --- a/app/evmante_fee_checker.go +++ b/app/evmante_fee_checker.go @@ -23,7 +23,6 @@ import ( // a) feeCap = tx.fees / tx.gas // b) tipFeeCap = tx.MaxPriorityPrice (default) or MaxInt64 // - when `ExtensionOptionDynamicFeeTx` is omitted, `tipFeeCap` defaults to `MaxInt64`. -// - when london hardfork is not enabled, it falls back to SDK default behavior (validator min-gas-prices). // - Tx priority is set to `effectiveGasPrice / DefaultPriorityReduction`. func NewDynamicFeeChecker(k evmkeeper.Keeper) ante.TxFeeChecker { return func(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, int64, error) { @@ -34,13 +33,8 @@ func NewDynamicFeeChecker(k evmkeeper.Keeper) ante.TxFeeChecker { } params := k.GetParams(ctx) denom := params.EvmDenom - ethCfg := params.ChainConfig.EthereumConfig(k.EthChainID(ctx)) - baseFee := k.GetBaseFee(ctx, ethCfg) - if baseFee == nil { - // london hardfork is not enabled: fallback to min-gas-prices logic - return checkTxFeeWithValidatorMinGasPrices(ctx, feeTx) - } + baseFee := k.GetBaseFee(ctx) // default to `MaxInt64` when there's no extension option. maxPriorityPrice := sdkmath.NewInt(math.MaxInt64) diff --git a/app/evmante_fee_market.go b/app/evmante_fee_market.go index 0efc0089f..22cff38f9 100644 --- a/app/evmante_fee_market.go +++ b/app/evmante_fee_market.go @@ -2,8 +2,6 @@ package app import ( - "math/big" - "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" @@ -30,15 +28,8 @@ func NewGasWantedDecorator( func (gwd GasWantedDecorator) AnteHandle( ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, ) (newCtx sdk.Context, err error) { - evmParams := gwd.EvmKeeper.GetParams(ctx) - chainCfg := evmParams.GetChainConfig() - ethCfg := chainCfg.EthereumConfig(gwd.EvmKeeper.EthChainID(ctx)) - - blockHeight := big.NewInt(ctx.BlockHeight()) - isLondon := ethCfg.IsLondon(blockHeight) - feeTx, ok := tx.(sdk.FeeTx) - if !ok || !isLondon { + if !ok { return next(ctx, tx, simulate) } diff --git a/app/evmante_fees.go b/app/evmante_fees.go index b0628f7bf..9728fa160 100644 --- a/app/evmante_fees.go +++ b/app/evmante_fees.go @@ -15,43 +15,23 @@ import ( var ( _ sdk.AnteDecorator = EthMinGasPriceDecorator{} - _ sdk.AnteDecorator = EthMempoolFeeDecorator{} ) // EthMinGasPriceDecorator will check if the transaction's fee is at least as large // as the MinGasPrices param. If fee is too low, decorator returns error and tx // is rejected. This applies to both CheckTx and DeliverTx and regardless -// if London hard fork or fee market params (EIP-1559) are enabled. +// fee market params (EIP-1559) are enabled. // If fee is high enough, then call next AnteHandler type EthMinGasPriceDecorator struct { AppKeepers } -// EthMempoolFeeDecorator will check if the transaction's effective fee is at -// least as large as the local validator's minimum gasFee (defined in validator -// config). -// If fee is too low, decorator returns error and tx is rejected from mempool. -// Note this only applies when ctx.CheckTx = true -// If fee is high enough or not CheckTx, then call next AnteHandler -// CONTRACT: Tx must implement FeeTx to use MempoolFeeDecorator -type EthMempoolFeeDecorator struct { - AppKeepers -} - // NewEthMinGasPriceDecorator creates a new MinGasPriceDecorator instance used only for // Ethereum transactions. func NewEthMinGasPriceDecorator(k AppKeepers) EthMinGasPriceDecorator { return EthMinGasPriceDecorator{AppKeepers: k} } -// NewEthMempoolFeeDecorator creates a new NewEthMempoolFeeDecorator instance used only for -// Ethereum transactions. -func NewEthMempoolFeeDecorator(k AppKeepers) EthMempoolFeeDecorator { - return EthMempoolFeeDecorator{ - AppKeepers: k, - } -} - // AnteHandle ensures that the effective fee from the transaction is greater than the // minimum global fee, which is defined by the MinGasPrice (parameter) * GasLimit (tx argument). func (empd EthMinGasPriceDecorator) AnteHandle( @@ -67,9 +47,7 @@ func (empd EthMinGasPriceDecorator) AnteHandle( return next(ctx, tx, simulate) } - chainCfg := evmParams.GetChainConfig() - ethCfg := chainCfg.EthereumConfig(empd.EvmKeeper.EthChainID(ctx)) - baseFee := empd.EvmKeeper.GetBaseFee(ctx, ethCfg) + baseFee := empd.EvmKeeper.GetBaseFee(ctx) for _, msg := range tx.GetMsgs() { ethMsg, ok := msg.(*evm.MsgEthereumTx) @@ -117,47 +95,3 @@ func (empd EthMinGasPriceDecorator) AnteHandle( return next(ctx, tx, simulate) } - -// AnteHandle ensures that the provided fees meet a minimum threshold for the validator. -// This check only for local mempool purposes, and thus it is only run on (Re)CheckTx. -// The logic is also skipped if the London hard fork and EIP-1559 are enabled. -func (mfd EthMempoolFeeDecorator) AnteHandle( - ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, -) (newCtx sdk.Context, err error) { - if !ctx.IsCheckTx() || simulate { - return next(ctx, tx, simulate) - } - evmParams := mfd.EvmKeeper.GetParams(ctx) - chainCfg := evmParams.GetChainConfig() - ethCfg := chainCfg.EthereumConfig(mfd.EvmKeeper.EthChainID(ctx)) - - baseFee := mfd.EvmKeeper.GetBaseFee(ctx, ethCfg) - // skip check as the London hard fork and EIP-1559 are enabled - if baseFee != nil { - return next(ctx, tx, simulate) - } - - evmDenom := evmParams.GetEvmDenom() - minGasPrice := ctx.MinGasPrices().AmountOf(evmDenom) - - for _, msg := range tx.GetMsgs() { - ethMsg, ok := msg.(*evm.MsgEthereumTx) - if !ok { - return ctx, errors.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evm.MsgEthereumTx)(nil)) - } - - fee := sdk.NewDecFromBigInt(ethMsg.GetFee()) - gasLimit := sdk.NewDecFromBigInt(new(big.Int).SetUint64(ethMsg.GetGas())) - requiredFee := minGasPrice.Mul(gasLimit) - - if fee.LT(requiredFee) { - return ctx, errors.Wrapf( - errortypes.ErrInsufficientFee, - "insufficient fee; got: %s required: %s", - fee, requiredFee, - ) - } - } - - return next(ctx, tx, simulate) -} diff --git a/app/evmante_handler.go b/app/evmante_handler.go index 2ab2557ff..5d0ce2740 100644 --- a/app/evmante_handler.go +++ b/app/evmante_handler.go @@ -14,8 +14,6 @@ func NewAnteHandlerEVM( return sdk.ChainAnteDecorators( // outermost AnteDecorator. SetUpContext must be called first NewEthSetUpContextDecorator(k), - // Check eth effective gas price against the node's minimal-gas-prices config - NewEthMempoolFeeDecorator(k), // Check eth effective gas price against the global MinGasPrice NewEthMinGasPriceDecorator(k), NewEthValidateBasicDecorator(k), diff --git a/app/evmante_setup_ctx.go b/app/evmante_setup_ctx.go index 2c1af8d8d..847bd77bd 100644 --- a/app/evmante_setup_ctx.go +++ b/app/evmante_setup_ctx.go @@ -28,7 +28,12 @@ func NewEthSetUpContextDecorator(k AppKeepers) EthSetupContextDecorator { } } -func (esc EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { +func (esc EthSetupContextDecorator) AnteHandle( + ctx sdk.Context, + tx sdk.Tx, + simulate bool, + next sdk.AnteHandler, +) (newCtx sdk.Context, err error) { // all transactions must implement GasTx _, ok := tx.(authante.GasTx) if !ok { @@ -145,10 +150,7 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu txGasLimit := uint64(0) evmParams := vbd.EvmKeeper.GetParams(ctx) - chainCfg := evmParams.GetChainConfig() - chainID := vbd.EvmKeeper.EthChainID(ctx) - ethCfg := chainCfg.EthereumConfig(chainID) - baseFee := vbd.EvmKeeper.GetBaseFee(ctx, ethCfg) + baseFee := vbd.EvmKeeper.GetBaseFee(ctx) enableCreate := evmParams.GetEnableCreate() enableCall := evmParams.GetEnableCall() evmDenom := evmParams.GetEvmDenom() diff --git a/eth/rpc/backend/call_tx.go b/eth/rpc/backend/call_tx.go index d70161b81..a7c83a2d4 100644 --- a/eth/rpc/backend/call_tx.go +++ b/eth/rpc/backend/call_tx.go @@ -175,7 +175,7 @@ func (b *Backend) SetTxDefaults(args evm.JsonTxArgs) (evm.JsonTxArgs, error) { } // If user specifies both maxPriorityfee and maxFee, then we do not - // need to consult the chain for defaults. It's definitely a London tx. + // need to consult the chain for defaults. if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil { // In this clause, user left some fields unspecified. if head.BaseFee != nil && args.GasPrice == nil { diff --git a/eth/rpc/backend/chain_info.go b/eth/rpc/backend/chain_info.go index 4b67db79a..5e4e78339 100644 --- a/eth/rpc/backend/chain_info.go +++ b/eth/rpc/backend/chain_info.go @@ -52,12 +52,10 @@ func (b *Backend) ChainConfig() *params.ChainConfig { // BaseFee returns the base fee tracked by the Fee Market module. // If the base fee is not enabled globally, the query returns nil. -// If the London hard fork is not activated at the current height, the query will -// return nil. func (b *Backend) BaseFee( blockRes *tmrpctypes.ResultBlockResults, ) (baseFee *big.Int, err error) { - // return BaseFee if London hard fork is activated and feemarket is enabled + // return BaseFee if feemarket is enabled res, err := b.queryClient.BaseFee(rpc.NewContextWithHeight(blockRes.Height), &evm.QueryBaseFeeRequest{}) if err != nil || res.BaseFee == nil { baseFee = nil diff --git a/eth/rpc/backend/utils.go b/eth/rpc/backend/utils.go index 4f93b0ea4..025fce754 100644 --- a/eth/rpc/backend/utils.go +++ b/eth/rpc/backend/utils.go @@ -120,15 +120,12 @@ func (b *Backend) processBlock( // set basefee targetOneFeeHistory.BaseFee = blockBaseFee cfg := b.ChainConfig() - if cfg.IsLondon(big.NewInt(blockHeight + 1)) { - header, err := b.CurrentHeader() - if err != nil { - return err - } - targetOneFeeHistory.NextBaseFee = misc.CalcBaseFee(cfg, header) - } else { - targetOneFeeHistory.NextBaseFee = new(big.Int) + header, err := b.CurrentHeader() + if err != nil { + return err } + targetOneFeeHistory.NextBaseFee = misc.CalcBaseFee(cfg, header) + // set gas used ratio gasLimitUint64, ok := (*ethBlock)["gasLimit"].(hexutil.Uint64) if !ok { diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index 7792c58a2..899324955 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -165,9 +165,7 @@ func (k Keeper) BaseFee( goCtx context.Context, _ *evm.QueryBaseFeeRequest, ) (*evm.QueryBaseFeeResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - params := k.GetParams(ctx) - ethCfg := params.ChainConfig.EthereumConfig(k.EthChainID(ctx)) - baseFee := sdkmath.NewIntFromBigInt(k.GetBaseFee(ctx, ethCfg)) + baseFee := sdkmath.NewIntFromBigInt(k.GetBaseFee(ctx)) return &evm.QueryBaseFeeResponse{ BaseFee: &baseFee, }, nil @@ -512,7 +510,7 @@ func (k Keeper) TraceTx( } // compute and use base fee of the height that is being traced - baseFee := k.GetBaseFee(ctx, cfg.ChainConfig) + baseFee := k.GetBaseFee(ctx) if baseFee != nil { cfg.BaseFee = baseFee } @@ -613,7 +611,7 @@ func (k Keeper) TraceBlock( } // compute and use base fee of height that is being traced - baseFee := k.GetBaseFeeNoCfg(ctx) + baseFee := k.GetBaseFee(ctx) if baseFee != nil { cfg.BaseFee = baseFee } diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 82cce516f..41c26113b 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -111,22 +111,15 @@ func (k Keeper) GetMinGasMultiplier(ctx sdk.Context) math.LegacyDec { return math.LegacyNewDecWithPrec(50, 2) // 50% } -func (k Keeper) GetBaseFee( - ctx sdk.Context, ethCfg *gethparams.ChainConfig, -) *big.Int { - isLondon := evm.IsLondon(ethCfg, ctx.BlockHeight()) - if !isLondon { - return nil - } +func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int { + // TODO: plug in fee market keeper return big.NewInt(0) } func (k Keeper) GetBaseFeeNoCfg( ctx sdk.Context, ) *big.Int { - ethChainId := k.EthChainID(ctx) - ethCfg := k.GetParams(ctx).ChainConfig.EthereumConfig(ethChainId) - return k.GetBaseFee(ctx, ethCfg) + return k.GetBaseFee(ctx) } // Logger returns a module-specific logger. diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 2b5221954..ea573fccc 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -423,7 +423,6 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context, sender := vm.AccountRef(msg.From()) contractCreation := msg.To() == nil - isLondon := cfg.ChainConfig.IsLondon(evmObj.Context.BlockNumber) intrinsicGas, err := k.GetEthIntrinsicGas(ctx, msg, cfg.ChainConfig, contractCreation) if err != nil { @@ -455,12 +454,8 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context, ret, leftoverGas, vmErr = evmObj.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value()) } - refundQuotient := params.RefundQuotient - // After EIP-3529: refunds are capped to gasUsed / 5 - if isLondon { - refundQuotient = params.RefundQuotientEIP3529 - } + refundQuotient := params.RefundQuotientEIP3529 // calculate gas refund if msg.Gas() < leftoverGas { diff --git a/x/evm/keeper/vm_config.go b/x/evm/keeper/vm_config.go index dd26702ef..7e6e3f3d4 100644 --- a/x/evm/keeper/vm_config.go +++ b/x/evm/keeper/vm_config.go @@ -27,7 +27,7 @@ func (k *Keeper) GetEVMConfig( return nil, errors.Wrap(err, "failed to obtain coinbase address") } - baseFee := k.GetBaseFee(ctx, ethCfg) + baseFee := k.GetBaseFee(ctx) return &statedb.EVMConfig{ Params: params, ChainConfig: ethCfg, @@ -48,17 +48,12 @@ func (k *Keeper) TxConfig( ) } -// DEFAULT_NO_BASE_FEE: Toggles whether or not a base fee will be used. It should -// always be on, since Nibiru EVM starts from a post-London upgrade state. -const DEFAULT_NO_BASE_FEE = false - // 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, _ core.Message, cfg *statedb.EVMConfig, tracer vm.EVMLogger, ) vm.Config { - noBaseFee := DEFAULT_NO_BASE_FEE var debug bool if _, ok := tracer.(evm.NoOpTracer); !ok { debug = true @@ -67,7 +62,7 @@ func (k Keeper) VMConfig( return vm.Config{ Debug: debug, Tracer: tracer, - NoBaseFee: noBaseFee, + NoBaseFee: false, ExtraEips: cfg.Params.EIPs(), } } diff --git a/x/evm/params.go b/x/evm/params.go index 8112b61e0..f2b55bc92 100644 --- a/x/evm/params.go +++ b/x/evm/params.go @@ -3,7 +3,6 @@ package evm import ( "fmt" - "math/big" "sort" "strings" @@ -14,7 +13,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" "golang.org/x/exp/slices" "github.com/NibiruChain/nibiru/eth" @@ -246,8 +244,3 @@ func ValidatePrecompiles(i interface{}) error { return nil } - -// IsLondon returns if london hardfork is enabled. -func IsLondon(ethConfig *params.ChainConfig, height int64) bool { - return ethConfig.IsLondon(big.NewInt(height)) -} diff --git a/x/evm/statedb/state_object.go b/x/evm/statedb/state_object.go index c473e1d73..39592af7c 100644 --- a/x/evm/statedb/state_object.go +++ b/x/evm/statedb/state_object.go @@ -127,7 +127,7 @@ func (s *stateObject) setBalance(amount *big.Int) { // Attribute accessors // -// Returns the address of the contract/account +// Address returns the address of the contract/account func (s *stateObject) Address() common.Address { return s.address } @@ -168,7 +168,7 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) { s.dirtyCode = true } -// SetCode set nonce to account +// SetNonce set nonce to account func (s *stateObject) SetNonce(nonce uint64) { s.db.journal.append(nonceChange{ account: &s.address, diff --git a/x/evm/tx.go b/x/evm/tx.go index c247506aa..44e0fecd8 100644 --- a/x/evm/tx.go +++ b/x/evm/tx.go @@ -46,10 +46,6 @@ var DefaultPriorityReduction = sdk.DefaultPowerReduction func GetTxPriority(txData TxData, baseFee *big.Int) (priority int64) { // calculate priority based on effective gas price tipPrice := txData.EffectiveGasPrice(baseFee) - // if london hardfork is not enabled, tipPrice is the gasPrice - if baseFee != nil { - tipPrice = new(big.Int).Sub(tipPrice, baseFee) - } priority = math.MaxInt64 priorityBig := new(big.Int).Quo(tipPrice, DefaultPriorityReduction.BigInt())