Skip to content

Commit

Permalink
chore(evm): set is_london true by default and removed from config (#1909
Browse files Browse the repository at this point in the history
)

* chore(evm): set is_london true by default and removed from config

* chore: rebuilt evm query proto

* chore: changelog update
  • Loading branch information
onikonychev authored Jun 4, 2024
1 parent 3a60458 commit a5fe920
Show file tree
Hide file tree
Showing 17 changed files with 44 additions and 161 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 14 additions & 16 deletions app/evmante_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down
8 changes: 1 addition & 7 deletions app/evmante_fee_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand Down
11 changes: 1 addition & 10 deletions app/evmante_fee_market.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
}

Expand Down
70 changes: 2 additions & 68 deletions app/evmante_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)
Expand Down Expand Up @@ -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)
}
2 changes: 0 additions & 2 deletions app/evmante_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
12 changes: 7 additions & 5 deletions app/evmante_setup_ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion eth/rpc/backend/call_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 1 addition & 3 deletions eth/rpc/backend/chain_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 5 additions & 8 deletions eth/rpc/backend/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 3 additions & 5 deletions x/evm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down
13 changes: 3 additions & 10 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 1 addition & 6 deletions x/evm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit a5fe920

Please sign in to comment.