diff --git a/app/ante.go b/app/ante.go index 0f8282d29..0a18887b4 100644 --- a/app/ante.go +++ b/app/ante.go @@ -10,7 +10,6 @@ import ( authante "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/NibiruChain/nibiru/app/ante" - "github.com/NibiruChain/nibiru/app/evmante" "github.com/NibiruChain/nibiru/eth" devgasante "github.com/NibiruChain/nibiru/x/devgas/v1/ante" "github.com/NibiruChain/nibiru/x/evm" @@ -54,7 +53,7 @@ func AnteHandlerExtendedTx( ) (anteHandler sdk.AnteHandler) { switch typeUrl { case evm.TYPE_URL_ETHEREUM_TX: - anteHandler = evmante.NewAnteHandlerEVM(opts) + anteHandler = NewAnteHandlerEVM(keepers, opts) case eth.TYPE_URL_DYNAMIC_FEE_TX: anteHandler = NewAnteHandlerNonEVM(opts) default: @@ -74,7 +73,7 @@ func NewAnteHandlerNonEVM( opts ante.AnteHandlerOptions, ) sdk.AnteHandler { return sdk.ChainAnteDecorators( - ante.AnteDecoratorPreventEtheruemTxMsgs{}, // reject MsgEthereumTxs + AnteDecoratorPreventEtheruemTxMsgs{}, // reject MsgEthereumTxs authante.NewSetUpContextDecorator(), wasmkeeper.NewLimitSimulationGasDecorator(opts.WasmConfig.SimulationGasLimit), wasmkeeper.NewCountTXDecorator(opts.TxCounterStoreKey), @@ -104,7 +103,7 @@ func NewAnteHandlerNonEVM( authante.NewSigVerificationDecorator(opts.AccountKeeper, opts.SignModeHandler), authante.NewIncrementSequenceDecorator(opts.AccountKeeper), ibcante.NewRedundantRelayDecorator(opts.IBCKeeper), - ante.AnteDecoratorGasWanted{}, + AnteDecoratorGasWanted{}, ) } diff --git a/app/ante/handler_opts.go b/app/ante/handler_opts.go index 2a9cd2408..79c099a00 100644 --- a/app/ante/handler_opts.go +++ b/app/ante/handler_opts.go @@ -7,12 +7,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/errors" sdkante "github.com/cosmos/cosmos-sdk/x/auth/ante" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" devgasante "github.com/NibiruChain/nibiru/x/devgas/v1/ante" devgaskeeper "github.com/NibiruChain/nibiru/x/devgas/v1/keeper" - evmkeeper "github.com/NibiruChain/nibiru/x/evm/keeper" ) type AnteHandlerOptions struct { @@ -20,8 +18,6 @@ type AnteHandlerOptions struct { IBCKeeper *ibckeeper.Keeper DevGasKeeper *devgaskeeper.Keeper DevGasBankKeeper devgasante.BankKeeper - EvmKeeper evmkeeper.Keeper - AccountKeeper authkeeper.AccountKeeper TxCounterStoreKey types.StoreKey WasmConfig *wasmtypes.WasmConfig @@ -29,6 +25,9 @@ type AnteHandlerOptions struct { } func (opts *AnteHandlerOptions) ValidateAndClean() error { + if opts.AccountKeeper == nil { + return AnteHandlerError("account keeper") + } if opts.BankKeeper == nil { return AnteHandlerError("bank keeper") } diff --git a/app/app.go b/app/app.go index 9e6604ae6..60ba12494 100644 --- a/app/app.go +++ b/app/app.go @@ -225,7 +225,6 @@ func NewNibiruApp( DevGasBankKeeper: app.BankKeeper, // TODO: feat(evm): enable app/server/config flag for Evm MaxTxGasWanted. MaxTxGasWanted: DefaultMaxTxGasWanted, - EvmKeeper: app.EvmKeeper, }) app.SetAnteHandler(anteHandler) diff --git a/app/evmante/evmante_handler.go b/app/evmante/evmante_handler.go deleted file mode 100644 index 84faefc89..000000000 --- a/app/evmante/evmante_handler.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2023-2024 Nibi, Inc. -package evmante - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/NibiruChain/nibiru/app/ante" -) - -// NewAnteHandlerEVM creates the default ante handler for Ethereum transactions -func NewAnteHandlerEVM( - options ante.AnteHandlerOptions, -) sdk.AnteHandler { - return sdk.ChainAnteDecorators( - // outermost AnteDecorator. SetUpContext must be called first - NewEthSetUpContextDecorator(&options.EvmKeeper), - // Check eth effective gas price against the global MinGasPrice - NewEthMinGasPriceDecorator(&options.EvmKeeper), - NewEthValidateBasicDecorator(&options.EvmKeeper), - NewEthSigVerificationDecorator(&options.EvmKeeper), - NewAnteDecVerifyEthAcc(&options.EvmKeeper, options.AccountKeeper), - NewCanTransferDecorator(&options.EvmKeeper), - NewAnteDecEthGasConsume(&options.EvmKeeper, options.MaxTxGasWanted), - NewAnteDecEthIncrementSenderSequence(&options.EvmKeeper, options.AccountKeeper), - ante.AnteDecoratorGasWanted{}, - // emit eth tx hash and index at the very last ante handler. - NewEthEmitEventDecorator(&options.EvmKeeper), - ) -} diff --git a/app/evmante/suite_test.go b/app/evmante/suite_test.go deleted file mode 100644 index fac4157a8..000000000 --- a/app/evmante/suite_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package evmante_test - -import ( - "testing" - - "cosmossdk.io/math" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/suite" - - "github.com/NibiruChain/nibiru/app" -) - -type TestSuite struct { - suite.Suite - - encCfg app.EncodingConfig -} - -func TestAppTestSuite(t *testing.T) { - suite.Run(t, new(TestSuite)) -} - -func (s *TestSuite) SetupSuite() { - s.encCfg = app.MakeEncodingConfig() -} - -func (s *TestSuite) DefaultGenesisCopy() app.GenesisState { - return app.NewDefaultGenesisState(s.encCfg.Codec) -} - -func (s *TestSuite) TestGenesis() { - getDefaultStakingGenesis := func() *stakingtypes.GenesisState { - genStaking := new(stakingtypes.GenesisState) - s.encCfg.Codec.MustUnmarshalJSON( - app.StakingModule{}.DefaultGenesis(s.encCfg.Codec), - genStaking, - ) - return genStaking - } - - gens := []*stakingtypes.GenesisState{} - gens = append(gens, getDefaultStakingGenesis()) - - genStaking := getDefaultStakingGenesis() - genStaking.Params.MinCommissionRate = math.LegacyZeroDec() - gens = append(gens, genStaking) - - for _, tc := range []struct { - name string - gen *stakingtypes.GenesisState - wantErr string - }{ - { - name: "default should work fine", - gen: gens[0], - }, - { - name: "zero commission should fail", - gen: gens[1], - wantErr: "min_commission must be positive", - }, - } { - s.T().Run(tc.name, func(t *testing.T) { - genStakingJson := s.encCfg.Codec.MustMarshalJSON(tc.gen) - err := app.StakingModule{}.ValidateGenesis( - s.encCfg.Codec, - s.encCfg.TxConfig, - genStakingJson, - ) - if tc.wantErr != "" { - s.ErrorContains(err, tc.wantErr) - return - } - s.NoError(err) - }) - } -} diff --git a/app/evmante/evmante_can_transfer.go b/app/evmante_can_transfer.go similarity index 88% rename from app/evmante/evmante_can_transfer.go rename to app/evmante_can_transfer.go index 2826aa742..c2ec4b4a9 100644 --- a/app/evmante/evmante_can_transfer.go +++ b/app/evmante_can_transfer.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "math/big" @@ -7,23 +7,24 @@ import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - gethcommon "github.com/ethereum/go-ethereum/common" - gethcore "github.com/ethereum/go-ethereum/core/types" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/statedb" + + gethcommon "github.com/ethereum/go-ethereum/common" + gethcore "github.com/ethereum/go-ethereum/core/types" ) // CanTransferDecorator checks if the sender is allowed to transfer funds according to the EVM block // context rules. type CanTransferDecorator struct { - evmKeeper EVMKeeper + AppKeepers } // NewCanTransferDecorator creates a new CanTransferDecorator instance. -func NewCanTransferDecorator(k EVMKeeper) CanTransferDecorator { +func NewCanTransferDecorator(k AppKeepers) CanTransferDecorator { return CanTransferDecorator{ - evmKeeper: k, + AppKeepers: k, } } @@ -32,8 +33,8 @@ func NewCanTransferDecorator(k EVMKeeper) CanTransferDecorator { func (ctd CanTransferDecorator) AnteHandle( ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, ) (sdk.Context, error) { - params := ctd.evmKeeper.GetParams(ctx) - ethCfg := evm.EthereumConfig(ctd.evmKeeper.EthChainID(ctx)) + params := ctd.EvmKeeper.GetParams(ctx) + ethCfg := evm.EthereumConfig(ctd.EvmKeeper.EthChainID(ctx)) signer := gethcore.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight())) for _, msg := range tx.GetMsgs() { @@ -44,7 +45,7 @@ func (ctd CanTransferDecorator) AnteHandle( "invalid message type %T, expected %T", msg, (*evm.MsgEthereumTx)(nil), ) } - baseFee := ctd.evmKeeper.GetBaseFee(ctx) + baseFee := ctd.EvmKeeper.GetBaseFee(ctx) coreMsg, err := msgEthTx.AsMessage(signer, baseFee) if err != nil { @@ -78,10 +79,10 @@ func (ctd CanTransferDecorator) AnteHandle( stateDB := statedb.New( ctx, - ctd.evmKeeper, + &ctd.EvmKeeper, statedb.NewEmptyTxConfig(gethcommon.BytesToHash(ctx.HeaderHash().Bytes())), ) - evmInstance := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evm.NewNoOpTracer(), stateDB) + evmInstance := ctd.EvmKeeper.NewEVM(ctx, coreMsg, cfg, evm.NewNoOpTracer(), stateDB) // check that caller has enough balance to cover asset transfer for **topmost** call // NOTE: here the gas consumed is from the context with the infinite gas meter diff --git a/app/evmante/evmante_can_transfer_test.go b/app/evmante_can_transfer_test.go similarity index 84% rename from app/evmante/evmante_can_transfer_test.go rename to app/evmante_can_transfer_test.go index 139e9600a..4e70e06a1 100644 --- a/app/evmante/evmante_can_transfer_test.go +++ b/app/evmante_can_transfer_test.go @@ -1,13 +1,12 @@ -package evmante_test +package app_test import ( "math/big" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/NibiruChain/nibiru/app/evmante" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/eth" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" "github.com/NibiruChain/nibiru/x/evm/statedb" ) @@ -26,7 +25,7 @@ func (s *TestSuite) TestCanTransferDecorator() { sdb.AddBalance(deps.Sender.EthAddr, big.NewInt(100)) }, txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { - txMsg := evmtestutil.HappyTransferTx(deps, 0) + txMsg := happyTransfertTx(deps, 0) txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) @@ -44,7 +43,7 @@ func (s *TestSuite) TestCanTransferDecorator() { { name: "sad: signed tx, insufficient funds", txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { - txMsg := evmtestutil.HappyTransferTx(deps, 0) + txMsg := happyTransfertTx(deps, 0) txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) @@ -62,7 +61,7 @@ func (s *TestSuite) TestCanTransferDecorator() { { name: "sad: unsigned tx", txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { - txMsg := evmtestutil.HappyTransferTx(deps, 0) + txMsg := happyTransfertTx(deps, 0) txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() tx, err := txMsg.BuildTx(txBuilder, eth.EthBaseDenom) @@ -75,7 +74,7 @@ func (s *TestSuite) TestCanTransferDecorator() { { name: "sad: tx with non evm message", txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { - return evmtestutil.NonEvmMsgTx(deps).(sdk.FeeTx) + return nonEvmMsgTx(deps).(sdk.FeeTx) }, wantErr: "invalid message", }, @@ -85,7 +84,7 @@ func (s *TestSuite) TestCanTransferDecorator() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewCanTransferDecorator(&deps.Chain.AppKeepers.EvmKeeper) + anteDec := app.NewCanTransferDecorator(deps.Chain.AppKeepers) tx := tc.txSetup(&deps) if tc.ctxSetup != nil { @@ -98,7 +97,7 @@ func (s *TestSuite) TestCanTransferDecorator() { } _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante/evmante_emit_event.go b/app/evmante_emit_event.go similarity index 88% rename from app/evmante/evmante_emit_event.go rename to app/evmante_emit_event.go index 0470965bb..b621a8dbe 100644 --- a/app/evmante/evmante_emit_event.go +++ b/app/evmante_emit_event.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "strconv" @@ -13,14 +13,12 @@ import ( // EthEmitEventDecorator emit events in ante handler in case of tx execution failed (out of block gas limit). type EthEmitEventDecorator struct { - evmKeeper EVMKeeper + AppKeepers } // NewEthEmitEventDecorator creates a new EthEmitEventDecorator -func NewEthEmitEventDecorator(k EVMKeeper) EthEmitEventDecorator { - return EthEmitEventDecorator{ - evmKeeper: k, - } +func NewEthEmitEventDecorator(k AppKeepers) EthEmitEventDecorator { + return EthEmitEventDecorator{AppKeepers: k} } // AnteHandle emits some basic events for the eth messages @@ -30,7 +28,7 @@ func (eeed EthEmitEventDecorator) AnteHandle( // After eth tx passed ante handler, the fee is deducted and nonce increased, // it shouldn't be ignored by json-rpc. We need to emit some events at the // very end of ante handler to be indexed by the consensus engine. - txIndex := eeed.evmKeeper.EVMState().BlockTxIndex.GetOr(ctx, 0) + txIndex := eeed.EvmKeeper.EVMState().BlockTxIndex.GetOr(ctx, 0) for i, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evm.MsgEthereumTx) diff --git a/app/evmante/evmante_emit_event_test.go b/app/evmante_emit_event_test.go similarity index 84% rename from app/evmante/evmante_emit_event_test.go rename to app/evmante_emit_event_test.go index 0b90881cc..39aa1351f 100644 --- a/app/evmante/evmante_emit_event_test.go +++ b/app/evmante_emit_event_test.go @@ -1,13 +1,12 @@ -package evmante_test +package app_test import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - "github.com/NibiruChain/nibiru/app/evmante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" tf "github.com/NibiruChain/nibiru/x/tokenfactory/types" ) @@ -32,7 +31,7 @@ func (s *TestSuite) TestEthEmitEventDecorator() { { name: "happy: eth tx emitted event", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) return tx }, wantErr: "", @@ -43,13 +42,13 @@ func (s *TestSuite) TestEthEmitEventDecorator() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewEthEmitEventDecorator(&deps.Chain.AppKeepers.EvmKeeper) + anteDec := app.NewEthEmitEventDecorator(deps.Chain.AppKeepers) tx := tc.txSetup(&deps) s.Require().NoError(stateDB.Commit()) _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante_fee_checker.go b/app/evmante_fee_checker.go new file mode 100644 index 000000000..5bc5c50f2 --- /dev/null +++ b/app/evmante_fee_checker.go @@ -0,0 +1,158 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package app + +import ( + "math" + + "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" + + "github.com/NibiruChain/nibiru/app/ante" + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/evm" + evmkeeper "github.com/NibiruChain/nibiru/x/evm/keeper" +) + +// NewDynamicFeeChecker returns a `TxFeeChecker` that applies a dynamic fee to +// Cosmos txs using the EIP-1559 fee market logic. +// This can be called in both CheckTx and deliverTx modes. +// a) feeCap = tx.fees / tx.gas +// b) tipFeeCap = tx.MaxPriorityPrice (default) or MaxInt64 +// - when `ExtensionOptionDynamicFeeTx` is omitted, `tipFeeCap` defaults to `MaxInt64`. +// - 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) { + // TODO: in the e2e test, + // if the fee in the genesis transaction meet the baseFee and minGasPrice in the feemarket, + // we can remove this code + if ctx.BlockHeight() == 0 { + // genesis transactions: fallback to min-gas-price logic + return checkTxFeeWithValidatorMinGasPrices(ctx, feeTx) + } + params := k.GetParams(ctx) + denom := params.EvmDenom + + baseFee := k.GetBaseFee(ctx) + + // default to `MaxInt64` when there's no extension option. + maxPriorityPrice := sdkmath.NewInt(math.MaxInt64) + + // get the priority tip cap from the extension option. + if hasExtOptsTx, ok := feeTx.(authante.HasExtensionOptionsTx); ok { + for _, opt := range hasExtOptsTx.GetExtensionOptions() { + if extOpt, ok := opt.GetCachedValue().(*eth.ExtensionOptionDynamicFeeTx); ok { + maxPriorityPrice = extOpt.MaxPriorityPrice + break + } + } + } + + // priority fee cannot be negative + if maxPriorityPrice.IsNegative() { + return nil, 0, errors.Wrapf( + errortypes.ErrInsufficientFee, + "max priority price cannot be negative", + ) + } + + gas := feeTx.GetGas() + feeCoins := feeTx.GetFee() + fee := feeCoins.AmountOfNoDenomValidation(denom) + + feeCap := fee.Quo(sdkmath.NewIntFromUint64(gas)) + baseFeeInt := sdkmath.NewIntFromBigInt(baseFee) + + if feeCap.LT(baseFeeInt) { + return nil, 0, errors.Wrapf( + errortypes.ErrInsufficientFee, + "gas prices too low, got: %s%s required: %s%s. "+ + "Please retry using a higher gas price or a higher fee", + feeCap, + denom, + baseFeeInt, + denom, + ) + } + + // calculate the effective gas price using the EIP-1559 logic. + effectivePrice := sdkmath.NewIntFromBigInt( + evm.EffectiveGasPrice(baseFeeInt.BigInt(), feeCap.BigInt(), maxPriorityPrice.BigInt()), + ) + + // NOTE: create a new coins slice without having to validate the denom + effectiveFee := sdk.Coins{ + { + Denom: denom, + Amount: effectivePrice.Mul(sdkmath.NewIntFromUint64(gas)), + }, + } + + bigPriority := effectivePrice.Sub(baseFeeInt).Quo(evm.DefaultPriorityReduction) + priority := int64(math.MaxInt64) + + if bigPriority.IsInt64() { + priority = bigPriority.Int64() + } + + return effectiveFee, priority, nil + } +} + +// checkTxFeeWithValidatorMinGasPrices implements the default fee logic, where the minimum price per +// unit of gas is fixed and set by each validator, and the tx priority is computed from the gas price. +func checkTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.FeeTx) (sdk.Coins, int64, error) { + feeCoins := tx.GetFee() + minGasPrices := ctx.MinGasPrices() + gas := int64(tx.GetGas()) //#nosec G701 -- checked for int overflow on ValidateBasic() + + // Ensure that the provided fees meet a minimum threshold for the validator, + // if this is a CheckTx. This is only for local mempool purposes, and thus + // is only ran on check tx. + if ctx.IsCheckTx() && !minGasPrices.IsZero() { + requiredFees := make(sdk.Coins, len(minGasPrices)) + + // Determine the required fees by multiplying each required minimum gas + // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). + glDec := sdkmath.LegacyNewDec(gas) + for i, gp := range minGasPrices { + fee := gp.Amount.Mul(glDec) + requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + } + + if !feeCoins.IsAnyGTE(requiredFees) { + return nil, 0, errors.Wrapf( + errortypes.ErrInsufficientFee, + "insufficient fees; got: %s required: %s", feeCoins, requiredFees, + ) + } + } + + priority := getTxPriority(feeCoins, gas) + return feeCoins, priority, nil +} + +// getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price +// provided in a transaction. +func getTxPriority(fees sdk.Coins, gas int64) int64 { + var priority int64 + + for _, fee := range fees { + gasPrice := fee.Amount.QuoRaw(gas) + amt := gasPrice.Quo(evm.DefaultPriorityReduction) + p := int64(math.MaxInt64) + + if amt.IsInt64() { + p = amt.Int64() + } + + if priority == 0 || p < priority { + priority = p + } + } + + return priority +} diff --git a/app/evmante_fee_checker_test.go b/app/evmante_fee_checker_test.go new file mode 100644 index 000000000..184045704 --- /dev/null +++ b/app/evmante_fee_checker_test.go @@ -0,0 +1,97 @@ +package app_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/NibiruChain/nibiru/app" + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/evm/evmtest" +) + +func (s *TestSuite) TestDynamicFeeChecker() { + testCases := []struct { + name string + txSetup func(deps *evmtest.TestDeps) sdk.FeeTx + ctxSetup func(deps *evmtest.TestDeps) + wantErr string + wantFee int64 + wantPriority int64 + }{ + { + name: "happy: genesis tx with sufficient fee", + ctxSetup: func(deps *evmtest.TestDeps) { + gasPrice := sdk.NewInt64Coin("unibi", 1) + deps.Ctx = deps.Ctx. + WithBlockHeight(0). + WithMinGasPrices( + sdk.NewDecCoins(sdk.NewDecCoinFromCoin(gasPrice)), + ). + WithIsCheckTx(true) + }, + txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { + txMsg := happyCreateContractTx(deps) + txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() + tx, err := txMsg.BuildTx(txBuilder, eth.EthBaseDenom) + s.Require().NoError(err) + return tx + }, + wantErr: "", + wantFee: gasLimitCreateContract().Int64(), + wantPriority: 0, + }, + { + name: "sad: genesis tx insufficient fee", + ctxSetup: func(deps *evmtest.TestDeps) { + gasPrice := sdk.NewInt64Coin("unibi", 2) + deps.Ctx = deps.Ctx. + WithBlockHeight(0). + WithMinGasPrices( + sdk.NewDecCoins(sdk.NewDecCoinFromCoin(gasPrice)), + ). + WithIsCheckTx(true) + }, + txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { + txMsg := happyCreateContractTx(deps) + txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() + tx, err := txMsg.BuildTx(txBuilder, eth.EthBaseDenom) + s.Require().NoError(err) + return tx + }, + wantErr: "insufficient fee", + }, + { + name: "happy: tx with sufficient fee", + txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { + txMsg := happyCreateContractTx(deps) + txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() + tx, err := txMsg.BuildTx(txBuilder, eth.EthBaseDenom) + s.Require().NoError(err) + return tx + }, + wantErr: "", + wantFee: gasLimitCreateContract().Int64(), + wantPriority: 0, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + checker := app.NewDynamicFeeChecker(deps.K) + + if tc.ctxSetup != nil { + tc.ctxSetup(&deps) + } + + fee, priority, err := checker(deps.Ctx, tc.txSetup(&deps)) + + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Require().NoError(err) + s.Require().Equal(tc.wantFee, fee.AmountOf("unibi").Int64()) + s.Require().Equal(tc.wantPriority, priority) + }) + } +} diff --git a/app/evmante/evmante_fees.go b/app/evmante_fees.go similarity index 92% rename from app/evmante/evmante_fees.go rename to app/evmante_fees.go index d6a5ef6ae..0e180d7e5 100644 --- a/app/evmante/evmante_fees.go +++ b/app/evmante_fees.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "math/big" @@ -7,6 +7,7 @@ import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" + gethcore "github.com/ethereum/go-ethereum/core/types" "github.com/NibiruChain/nibiru/x/evm" @@ -20,15 +21,13 @@ var _ sdk.AnteDecorator = EthMinGasPriceDecorator{} // fee market params (EIP-1559) are enabled. // If fee is high enough, then call next AnteHandler type EthMinGasPriceDecorator struct { - evmKeeper EVMKeeper + AppKeepers } // NewEthMinGasPriceDecorator creates a new MinGasPriceDecorator instance used only for // Ethereum transactions. -func NewEthMinGasPriceDecorator(k EVMKeeper) EthMinGasPriceDecorator { - return EthMinGasPriceDecorator{ - evmKeeper: k, - } +func NewEthMinGasPriceDecorator(k AppKeepers) EthMinGasPriceDecorator { + return EthMinGasPriceDecorator{AppKeepers: k} } // AnteHandle ensures that the effective fee from the transaction is greater than the @@ -37,7 +36,7 @@ func (empd EthMinGasPriceDecorator) AnteHandle( ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, ) (newCtx sdk.Context, err error) { minGasPrices := ctx.MinGasPrices() - evmParams := empd.evmKeeper.GetParams(ctx) + evmParams := empd.EvmKeeper.GetParams(ctx) evmDenom := evmParams.GetEvmDenom() minGasPrice := minGasPrices.AmountOf(evmDenom) @@ -46,7 +45,7 @@ func (empd EthMinGasPriceDecorator) AnteHandle( return next(ctx, tx, simulate) } - baseFee := empd.evmKeeper.GetBaseFee(ctx) + baseFee := empd.EvmKeeper.GetBaseFee(ctx) for _, msg := range tx.GetMsgs() { ethMsg, ok := msg.(*evm.MsgEthereumTx) diff --git a/app/evmante/evmante_fees_test.go b/app/evmante_fees_test.go similarity index 84% rename from app/evmante/evmante_fees_test.go rename to app/evmante_fees_test.go index 875949738..f2ac7238b 100644 --- a/app/evmante/evmante_fees_test.go +++ b/app/evmante_fees_test.go @@ -1,11 +1,10 @@ -package evmante_test +package app_test import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/NibiruChain/nibiru/app/evmante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" ) @@ -19,7 +18,7 @@ func (s *TestSuite) TestEthMinGasPriceDecorator() { { name: "happy: min gas price is 0", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) return tx }, wantErr: "", @@ -35,7 +34,7 @@ func (s *TestSuite) TestEthMinGasPriceDecorator() { WithIsCheckTx(true) }, txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) return tx }, wantErr: "", @@ -51,7 +50,7 @@ func (s *TestSuite) TestEthMinGasPriceDecorator() { WithIsCheckTx(true) }, txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) return tx }, wantErr: "insufficient fee", @@ -83,7 +82,7 @@ func (s *TestSuite) TestEthMinGasPriceDecorator() { for _, tc := range testCases { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() - anteDec := evmante.NewEthMinGasPriceDecorator(&deps.Chain.AppKeepers.EvmKeeper) + anteDec := app.NewEthMinGasPriceDecorator(deps.Chain.AppKeepers) tx := tc.txSetup(&deps) @@ -92,7 +91,7 @@ func (s *TestSuite) TestEthMinGasPriceDecorator() { } _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante/evmante_gas_consume.go b/app/evmante_gas_consume.go similarity index 93% rename from app/evmante/evmante_gas_consume.go rename to app/evmante_gas_consume.go index af0ac423c..b50613e99 100644 --- a/app/evmante/evmante_gas_consume.go +++ b/app/evmante_gas_consume.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "math" @@ -7,6 +7,7 @@ import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/NibiruChain/nibiru/eth" @@ -17,17 +18,21 @@ import ( // AnteDecEthGasConsume validates enough intrinsic gas for the transaction and // gas consumption. type AnteDecEthGasConsume struct { - evmKeeper EVMKeeper + AppKeepers + // bankKeeper anteutils.BankKeeper + // distributionKeeper anteutils.DistributionKeeper + // evmKeeper EVMKeeper + // stakingKeeper anteutils.StakingKeeper maxGasWanted uint64 } // NewAnteDecEthGasConsume creates a new EthGasConsumeDecorator func NewAnteDecEthGasConsume( - k EVMKeeper, + keepers AppKeepers, maxGasWanted uint64, ) AnteDecEthGasConsume { return AnteDecEthGasConsume{ - evmKeeper: k, + AppKeepers: keepers, maxGasWanted: maxGasWanted, } } @@ -65,14 +70,14 @@ func (anteDec AnteDecEthGasConsume) AnteHandle( return next(newCtx, tx, simulate) } - evmParams := anteDec.evmKeeper.GetParams(ctx) + evmParams := anteDec.EvmKeeper.GetParams(ctx) evmDenom := evmParams.GetEvmDenom() var events sdk.Events // Use the lowest priority of all the messages as the final one. minPriority := int64(math.MaxInt64) - baseFee := anteDec.evmKeeper.GetBaseFee(ctx) + baseFee := anteDec.EvmKeeper.GetBaseFee(ctx) for _, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evm.MsgEthereumTx) @@ -165,7 +170,7 @@ func (anteDec AnteDecEthGasConsume) deductFee(ctx sdk.Context, fees sdk.Coins, f // If the account balance is not sufficient, try to withdraw enough staking rewards - if err := anteDec.evmKeeper.DeductTxCostsFromUserBalance(ctx, fees, gethcommon.BytesToAddress(feePayer)); err != nil { + if err := anteDec.EvmKeeper.DeductTxCostsFromUserBalance(ctx, fees, gethcommon.BytesToAddress(feePayer)); err != nil { return errors.Wrapf(err, "failed to deduct transaction costs from user balance") } return nil diff --git a/app/evmante/evmante_gas_consume_test.go b/app/evmante_gas_consume_test.go similarity index 82% rename from app/evmante/evmante_gas_consume_test.go rename to app/evmante_gas_consume_test.go index 1616c32ff..8918a20a9 100644 --- a/app/evmante/evmante_gas_consume_test.go +++ b/app/evmante_gas_consume_test.go @@ -1,13 +1,12 @@ -package evmante_test +package app_test import ( "math/big" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/NibiruChain/nibiru/app/evmante" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/eth" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" "github.com/NibiruChain/nibiru/x/evm/statedb" @@ -29,7 +28,7 @@ func (s *TestSuite) TestAnteDecEthGasConsume() { balance := new(big.Int).Add(gasLimit, big.NewInt(100)) sdb.AddBalance(deps.Sender.EthAddr, balance) }, - txSetup: evmtestutil.HappyCreateContractTx, + txSetup: happyCreateContractTx, wantErr: "", gasMeter: eth.NewInfiniteGasMeterWithLimit(happyGasLimit().Uint64()), maxGasWanted: 0, @@ -39,7 +38,7 @@ func (s *TestSuite) TestAnteDecEthGasConsume() { beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) { deps.Ctx = deps.Ctx.WithIsReCheckTx(true) }, - txSetup: evmtestutil.HappyCreateContractTx, + txSetup: happyCreateContractTx, gasMeter: eth.NewInfiniteGasMeterWithLimit(0), wantErr: "", }, @@ -50,7 +49,7 @@ func (s *TestSuite) TestAnteDecEthGasConsume() { balance := new(big.Int).Add(gasLimit, big.NewInt(100)) sdb.AddBalance(deps.Sender.EthAddr, balance) }, - txSetup: evmtestutil.HappyCreateContractTx, + txSetup: happyCreateContractTx, wantErr: "exceeds block gas limit (0)", gasMeter: eth.NewInfiniteGasMeterWithLimit(0), maxGasWanted: 0, @@ -61,8 +60,8 @@ func (s *TestSuite) TestAnteDecEthGasConsume() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewAnteDecEthGasConsume( - &deps.Chain.AppKeepers.EvmKeeper, tc.maxGasWanted, + anteDec := app.NewAnteDecEthGasConsume( + deps.Chain.AppKeepers, tc.maxGasWanted, ) tc.beforeTxSetup(&deps, stateDB) @@ -72,7 +71,7 @@ func (s *TestSuite) TestAnteDecEthGasConsume() { deps.Ctx = deps.Ctx.WithIsCheckTx(true) deps.Ctx = deps.Ctx.WithBlockGasMeter(tc.gasMeter) _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/ante/gas_wanted.go b/app/evmante_gas_wanted.go similarity index 98% rename from app/ante/gas_wanted.go rename to app/evmante_gas_wanted.go index 1ef4e9752..b7cebbfa3 100644 --- a/app/ante/gas_wanted.go +++ b/app/evmante_gas_wanted.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package ante +package app import ( "cosmossdk.io/errors" diff --git a/app/ante/gas_wanted_test.go b/app/evmante_gas_wanted_test.go similarity index 82% rename from app/ante/gas_wanted_test.go rename to app/evmante_gas_wanted_test.go index 84a67e04e..f77531427 100644 --- a/app/ante/gas_wanted_test.go +++ b/app/evmante_gas_wanted_test.go @@ -1,16 +1,15 @@ -package ante_test +package app_test import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - "github.com/NibiruChain/nibiru/app/ante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" ) -func (s *AnteTestSuite) TestGasWantedDecorator() { +func (s *TestSuite) TestGasWantedDecorator() { testCases := []struct { name string ctxSetup func(deps *evmtest.TestDeps) @@ -20,7 +19,7 @@ func (s *AnteTestSuite) TestGasWantedDecorator() { { name: "happy: non fee tx type", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - return evmtestutil.HappyCreateContractTx(deps) + return happyCreateContractTx(deps) }, wantErr: "", }, @@ -35,7 +34,7 @@ func (s *AnteTestSuite) TestGasWantedDecorator() { txSetup: func(deps *evmtest.TestDeps) sdk.Tx { return legacytx.StdTx{ Msgs: []sdk.Msg{ - evmtestutil.HappyCreateContractTx(deps), + happyCreateContractTx(deps), }, } }, @@ -52,7 +51,7 @@ func (s *AnteTestSuite) TestGasWantedDecorator() { txSetup: func(deps *evmtest.TestDeps) sdk.Tx { return legacytx.StdTx{ Msgs: []sdk.Msg{ - evmtestutil.HappyCreateContractTx(deps), + happyCreateContractTx(deps), }, Fee: legacytx.StdFee{Gas: 500}, } @@ -72,7 +71,7 @@ func (s *AnteTestSuite) TestGasWantedDecorator() { txSetup: func(deps *evmtest.TestDeps) sdk.Tx { return legacytx.StdTx{ Msgs: []sdk.Msg{ - evmtestutil.HappyCreateContractTx(deps), + happyCreateContractTx(deps), }, Fee: legacytx.StdFee{Gas: 1000}, } @@ -85,7 +84,7 @@ func (s *AnteTestSuite) TestGasWantedDecorator() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := ante.AnteDecoratorGasWanted{} + anteDec := app.AnteDecoratorGasWanted{} tx := tc.txSetup(&deps) s.Require().NoError(stateDB.Commit()) @@ -95,7 +94,7 @@ func (s *AnteTestSuite) TestGasWantedDecorator() { tc.ctxSetup(&deps) } _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante_handler.go b/app/evmante_handler.go new file mode 100644 index 000000000..74cbea3ac --- /dev/null +++ b/app/evmante_handler.go @@ -0,0 +1,29 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package app + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/NibiruChain/nibiru/app/ante" +) + +// NewAnteHandlerEVM creates the default ante handler for Ethereum transactions +func NewAnteHandlerEVM( + k AppKeepers, options ante.AnteHandlerOptions, +) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + // outermost AnteDecorator. SetUpContext must be called first + NewEthSetUpContextDecorator(k), + // Check eth effective gas price against the global MinGasPrice + NewEthMinGasPriceDecorator(k), + NewEthValidateBasicDecorator(k), + NewEthSigVerificationDecorator(k), + NewAnteDecVerifyEthAcc(k), + NewCanTransferDecorator(k), + NewAnteDecEthGasConsume(k, options.MaxTxGasWanted), + NewAnteDecEthIncrementSenderSequence(k), + AnteDecoratorGasWanted{}, + // emit eth tx hash and index at the very last ante handler. + NewEthEmitEventDecorator(k), + ) +} diff --git a/app/evmante/evmante_handler_test.go b/app/evmante_handler_test.go similarity index 84% rename from app/evmante/evmante_handler_test.go rename to app/evmante_handler_test.go index 8fbc58c4c..e60b075b1 100644 --- a/app/evmante/evmante_handler_test.go +++ b/app/evmante_handler_test.go @@ -1,4 +1,4 @@ -package evmante_test +package app_test import ( "math/big" @@ -8,10 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/app/ante" - "github.com/NibiruChain/nibiru/app/evmante" "github.com/NibiruChain/nibiru/eth" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" "github.com/NibiruChain/nibiru/x/evm/statedb" ) @@ -29,14 +28,14 @@ func (s *TestSuite) TestAnteHandlerEVM() { beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) { sdb.AddBalance( deps.Sender.EthAddr, - new(big.Int).Add(evmtestutil.GasLimitCreateContract(), big.NewInt(100)), + new(big.Int).Add(gasLimitCreateContract(), big.NewInt(100)), ) }, ctxSetup: func(deps *evmtest.TestDeps) { gasPrice := sdk.NewInt64Coin("unibi", 1) cp := &tmproto.ConsensusParams{ Block: &tmproto.BlockParams{ - MaxGas: new(big.Int).Add(evmtestutil.GasLimitCreateContract(), big.NewInt(100)).Int64(), + MaxGas: new(big.Int).Add(gasLimitCreateContract(), big.NewInt(100)).Int64(), }, } deps.Ctx = deps.Ctx. @@ -47,7 +46,7 @@ func (s *TestSuite) TestAnteHandlerEVM() { WithConsensusParams(cp) }, txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx { - txMsg := evmtestutil.HappyTransferTx(deps, 0) + txMsg := happyTransfertTx(deps, 0) txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) @@ -69,8 +68,8 @@ func (s *TestSuite) TestAnteHandlerEVM() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteHandlerEVM := evmante.NewAnteHandlerEVM( - ante.AnteHandlerOptions{ + anteHandlerEVM := app.NewAnteHandlerEVM( + deps.Chain.AppKeepers, ante.AnteHandlerOptions{ HandlerOptions: authante.HandlerOptions{ AccountKeeper: deps.Chain.AccountKeeper, BankKeeper: deps.Chain.BankKeeper, @@ -79,7 +78,6 @@ func (s *TestSuite) TestAnteHandlerEVM() { SigGasConsumer: authante.DefaultSigVerificationGasConsumer, ExtensionOptionChecker: func(*codectypes.Any) bool { return true }, }, - EvmKeeper: deps.Chain.EvmKeeper, }) tx := tc.txSetup(&deps) diff --git a/app/evmante/evmante_increment_sender_seq.go b/app/evmante_increment_sender_seq.go similarity index 84% rename from app/evmante/evmante_increment_sender_seq.go rename to app/evmante_increment_sender_seq.go index d033b66a8..ef4ac75a5 100644 --- a/app/evmante/evmante_increment_sender_seq.go +++ b/app/evmante_increment_sender_seq.go @@ -1,11 +1,11 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/auth/ante" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/NibiruChain/nibiru/x/evm" @@ -13,15 +13,13 @@ import ( // AnteDecEthIncrementSenderSequence increments the sequence of the signers. type AnteDecEthIncrementSenderSequence struct { - evmKeeper EVMKeeper - accountKeeper ante.AccountKeeper + AppKeepers } // NewAnteDecEthIncrementSenderSequence creates a new EthIncrementSenderSequenceDecorator. -func NewAnteDecEthIncrementSenderSequence(k EVMKeeper, ak ante.AccountKeeper) AnteDecEthIncrementSenderSequence { +func NewAnteDecEthIncrementSenderSequence(k AppKeepers) AnteDecEthIncrementSenderSequence { return AnteDecEthIncrementSenderSequence{ - evmKeeper: k, - accountKeeper: ak, + AppKeepers: k, } } @@ -49,7 +47,7 @@ func (issd AnteDecEthIncrementSenderSequence) AnteHandle( } // increase sequence of sender - acc := issd.accountKeeper.GetAccount(ctx, msgEthTx.GetFrom()) + acc := issd.AccountKeeper.GetAccount(ctx, msgEthTx.GetFrom()) if acc == nil { return ctx, errors.Wrapf( errortypes.ErrUnknownAddress, @@ -71,7 +69,7 @@ func (issd AnteDecEthIncrementSenderSequence) AnteHandle( return ctx, errors.Wrapf(err, "failed to set sequence to %d", acc.GetSequence()+1) } - issd.accountKeeper.SetAccount(ctx, acc) + issd.AccountKeeper.SetAccount(ctx, acc) } return next(ctx, tx, simulate) diff --git a/app/evmante/evmante_increment_sender_seq_test.go b/app/evmante_increment_sender_seq_test.go similarity index 78% rename from app/evmante/evmante_increment_sender_seq_test.go rename to app/evmante_increment_sender_seq_test.go index 38831408c..7778522e0 100644 --- a/app/evmante/evmante_increment_sender_seq_test.go +++ b/app/evmante_increment_sender_seq_test.go @@ -1,12 +1,11 @@ -package evmante_test +package app_test import ( "math/big" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/NibiruChain/nibiru/app/evmante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" "github.com/NibiruChain/nibiru/x/evm/statedb" ) @@ -26,7 +25,7 @@ func (s *TestSuite) TestAnteDecEthIncrementSenderSequence() { sdb.AddBalance(deps.Sender.EthAddr, balance) }, txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - return evmtestutil.HappyTransferTx(deps, 0) + return happyTransfertTx(deps, 0) }, wantErr: "", wantSeq: 1, @@ -38,8 +37,8 @@ func (s *TestSuite) TestAnteDecEthIncrementSenderSequence() { sdb.AddBalance(deps.Sender.EthAddr, balance) }, txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - txMsgOne := evmtestutil.HappyTransferTx(deps, 0) - txMsgTwo := evmtestutil.HappyTransferTx(deps, 1) + txMsgOne := happyTransfertTx(deps, 0) + txMsgTwo := happyTransfertTx(deps, 1) txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() s.Require().NoError(txBuilder.SetMsgs(txMsgOne, txMsgTwo)) @@ -53,13 +52,13 @@ func (s *TestSuite) TestAnteDecEthIncrementSenderSequence() { { name: "sad: account does not exists", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - return evmtestutil.HappyTransferTx(deps, 0) + return happyTransfertTx(deps, 0) }, wantErr: "unknown address", }, { name: "sad: tx with non evm message", - txSetup: evmtestutil.NonEvmMsgTx, + txSetup: nonEvmMsgTx, wantErr: "invalid message", }, } @@ -68,7 +67,7 @@ func (s *TestSuite) TestAnteDecEthIncrementSenderSequence() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewAnteDecEthIncrementSenderSequence(&deps.Chain.EvmKeeper, deps.Chain.AccountKeeper) + anteDec := app.NewAnteDecEthIncrementSenderSequence(deps.Chain.AppKeepers) if tc.beforeTxSetup != nil { tc.beforeTxSetup(&deps, stateDB) @@ -77,7 +76,7 @@ func (s *TestSuite) TestAnteDecEthIncrementSenderSequence() { tx := tc.txSetup(&deps) _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante/interfaces.go b/app/evmante_interfaces.go similarity index 91% rename from app/evmante/interfaces.go rename to app/evmante_interfaces.go index 09b10dab7..dc8192bfa 100644 --- a/app/evmante/interfaces.go +++ b/app/evmante_interfaces.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "math/big" @@ -26,8 +26,6 @@ type EVMKeeper interface { GetParams(ctx sdk.Context) evm.Params EVMState() evmkeeper.EvmState - EthChainID(ctx sdk.Context) *big.Int - GetBaseFee(ctx sdk.Context) *big.Int } type protoTxProvider interface { diff --git a/app/ante/reject_ethereum_tx_msgs.go b/app/evmante_reject_msgs.go similarity index 98% rename from app/ante/reject_ethereum_tx_msgs.go rename to app/evmante_reject_msgs.go index fb8f4d39d..b9b1bb2ee 100644 --- a/app/ante/reject_ethereum_tx_msgs.go +++ b/app/evmante_reject_msgs.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package ante +package app import ( "cosmossdk.io/errors" diff --git a/app/ante/reject_ethereum_tx_msgs_test.go b/app/evmante_reject_msgs_test.go similarity index 63% rename from app/ante/reject_ethereum_tx_msgs_test.go rename to app/evmante_reject_msgs_test.go index 147e4a0c8..76636340f 100644 --- a/app/ante/reject_ethereum_tx_msgs_test.go +++ b/app/evmante_reject_msgs_test.go @@ -1,14 +1,13 @@ -package ante_test +package app_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/NibiruChain/nibiru/app/ante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" ) -func (s *AnteTestSuite) TestAnteDecoratorPreventEtheruemTxMsgs() { +func (s *TestSuite) TestAnteDecoratorPreventEtheruemTxMsgs() { testCases := []struct { name string txSetup func(deps *evmtest.TestDeps) sdk.Tx @@ -17,13 +16,13 @@ func (s *AnteTestSuite) TestAnteDecoratorPreventEtheruemTxMsgs() { { name: "sad: evm message", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - return evmtestutil.HappyTransferTx(deps, 0) + return happyTransfertTx(deps, 0) }, wantErr: "invalid type", }, { name: "happy: non evm message", - txSetup: evmtestutil.NonEvmMsgTx, + txSetup: nonEvmMsgTx, wantErr: "", }, } @@ -31,11 +30,11 @@ func (s *AnteTestSuite) TestAnteDecoratorPreventEtheruemTxMsgs() { for _, tc := range testCases { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() - anteDec := ante.AnteDecoratorPreventEtheruemTxMsgs{} + anteDec := app.AnteDecoratorPreventEtheruemTxMsgs{} tx := tc.txSetup(&deps) _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante/evmante_setup_ctx.go b/app/evmante_setup_ctx.go similarity index 88% rename from app/evmante/evmante_setup_ctx.go rename to app/evmante_setup_ctx.go index 6cad962a7..be4d5f897 100644 --- a/app/evmante/evmante_setup_ctx.go +++ b/app/evmante_setup_ctx.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( errorsmod "cosmossdk.io/errors" @@ -12,12 +12,12 @@ import ( // EthSetupContextDecorator is adapted from SetUpContextDecorator from cosmos-sdk, it ignores gas consumption // by setting the gas meter to infinite type EthSetupContextDecorator struct { - evmKeeper EVMKeeper + AppKeepers } -func NewEthSetUpContextDecorator(k EVMKeeper) EthSetupContextDecorator { +func NewEthSetUpContextDecorator(k AppKeepers) EthSetupContextDecorator { return EthSetupContextDecorator{ - evmKeeper: k, + AppKeepers: k, } } @@ -43,6 +43,6 @@ func (esc EthSetupContextDecorator) AnteHandle( // Reset transient gas used to prepare the execution of current cosmos tx. // Transient gas-used is necessary to sum the gas-used of cosmos tx, when it contains multiple eth msgs. - esc.evmKeeper.ResetTransientGasUsed(ctx) + esc.EvmKeeper.ResetTransientGasUsed(ctx) return next(newCtx, tx, simulate) } diff --git a/app/evmante/evmante_setup_ctx_test.go b/app/evmante_setup_ctx_test.go similarity index 68% rename from app/evmante/evmante_setup_ctx_test.go rename to app/evmante_setup_ctx_test.go index 7bdd25f08..132ed8f1a 100644 --- a/app/evmante/evmante_setup_ctx_test.go +++ b/app/evmante_setup_ctx_test.go @@ -1,4 +1,4 @@ -package evmante_test +package app_test import ( "math" @@ -6,25 +6,24 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/NibiruChain/nibiru/app/evmante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" ) func (s *TestSuite) TestEthSetupContextDecorator() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewEthSetUpContextDecorator(&deps.Chain.EvmKeeper) + anteDec := app.NewEthSetUpContextDecorator(deps.Chain.AppKeepers) s.Require().NoError(stateDB.Commit()) - tx := evmtestutil.HappyCreateContractTx(&deps) + tx := happyCreateContractTx(&deps) // Set block gas used to non 0 to check that handler resets it - deps.Chain.EvmKeeper.EvmState.BlockGasUsed.Set(deps.Ctx, 1000) + anteDec.EvmKeeper.EvmState.BlockGasUsed.Set(deps.Ctx, 1000) // Ante handler returns new context newCtx, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) s.Require().NoError(err) @@ -38,7 +37,7 @@ func (s *TestSuite) TestEthSetupContextDecorator() { s.Require().Equal(defaultGasConfig, newCtx.TransientKVGasConfig()) // Check that block gas used is reset to 0 - gas, err := deps.Chain.EvmKeeper.EvmState.BlockGasUsed.Get(newCtx) + gas, err := anteDec.EvmKeeper.EvmState.BlockGasUsed.Get(newCtx) s.Require().NoError(err) s.Require().Equal(gas, uint64(0)) } diff --git a/app/evmante/evmante_sigverify.go b/app/evmante_sigverify.go similarity index 90% rename from app/evmante/evmante_sigverify.go rename to app/evmante_sigverify.go index 2c41da448..314681cd8 100644 --- a/app/evmante/evmante_sigverify.go +++ b/app/evmante_sigverify.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "math/big" @@ -14,13 +14,13 @@ import ( // EthSigVerificationDecorator validates an ethereum signatures type EthSigVerificationDecorator struct { - evmKeeper EVMKeeper + AppKeepers } // NewEthSigVerificationDecorator creates a new EthSigVerificationDecorator -func NewEthSigVerificationDecorator(k EVMKeeper) EthSigVerificationDecorator { +func NewEthSigVerificationDecorator(k AppKeepers) EthSigVerificationDecorator { return EthSigVerificationDecorator{ - evmKeeper: k, + AppKeepers: k, } } @@ -32,8 +32,8 @@ func NewEthSigVerificationDecorator(k EVMKeeper) EthSigVerificationDecorator { func (esvd EthSigVerificationDecorator) AnteHandle( ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, ) (newCtx sdk.Context, err error) { - chainID := esvd.evmKeeper.EthChainID(ctx) - evmParams := esvd.evmKeeper.GetParams(ctx) + chainID := esvd.EvmKeeper.EthChainID(ctx) + evmParams := esvd.EvmKeeper.GetParams(ctx) ethCfg := evm.EthereumConfig(chainID) blockNum := big.NewInt(ctx.BlockHeight()) signer := gethcore.MakeSigner(ethCfg, blockNum) diff --git a/app/evmante/evmante_sigverify_test.go b/app/evmante_sigverify_test.go similarity index 79% rename from app/evmante/evmante_sigverify_test.go rename to app/evmante_sigverify_test.go index de64c9dc6..145174e09 100644 --- a/app/evmante/evmante_sigverify_test.go +++ b/app/evmante_sigverify_test.go @@ -1,4 +1,4 @@ -package evmante_test +package app_test import ( "math/big" @@ -6,13 +6,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - "github.com/NibiruChain/nibiru/app/evmante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm/evmtest" tf "github.com/NibiruChain/nibiru/x/tokenfactory/types" ) -var InvalidChainID = big.NewInt(987654321) +var ( + InvalidChainID = big.NewInt(987654321) +) func (s *TestSuite) TestEthSigVerificationDecorator() { testCases := []struct { @@ -23,7 +24,7 @@ func (s *TestSuite) TestEthSigVerificationDecorator() { { name: "sad: unsigned tx", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) return tx }, wantErr: "rejected unprotected Ethereum transaction", @@ -42,7 +43,7 @@ func (s *TestSuite) TestEthSigVerificationDecorator() { { name: "sad: ethereum tx invalid chain id", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) gethSigner := deps.Sender.GethSigner(InvalidChainID) keyringSigner := deps.Sender.KeyringSigner err := tx.Sign(gethSigner, keyringSigner) @@ -54,7 +55,7 @@ func (s *TestSuite) TestEthSigVerificationDecorator() { { name: "happy: signed ethereum tx", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) keyringSigner := deps.Sender.KeyringSigner err := tx.Sign(gethSigner, keyringSigner) @@ -69,14 +70,14 @@ func (s *TestSuite) TestEthSigVerificationDecorator() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewEthSigVerificationDecorator(&deps.Chain.AppKeepers.EvmKeeper) + anteDec := app.NewEthSigVerificationDecorator(deps.Chain.AppKeepers) tx := tc.txSetup(&deps) s.Require().NoError(stateDB.Commit()) deps.Ctx = deps.Ctx.WithIsCheckTx(true) _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante/evmante_validate_basic.go b/app/evmante_validate_basic.go similarity index 95% rename from app/evmante/evmante_validate_basic.go rename to app/evmante_validate_basic.go index 22f599f8b..2c006485a 100644 --- a/app/evmante/evmante_validate_basic.go +++ b/app/evmante_validate_basic.go @@ -1,5 +1,5 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "errors" @@ -15,13 +15,13 @@ import ( // EthValidateBasicDecorator is adapted from ValidateBasicDecorator from cosmos-sdk, it ignores ErrNoSignatures type EthValidateBasicDecorator struct { - evmKeeper EVMKeeper + AppKeepers } // NewEthValidateBasicDecorator creates a new EthValidateBasicDecorator -func NewEthValidateBasicDecorator(k EVMKeeper) EthValidateBasicDecorator { +func NewEthValidateBasicDecorator(k AppKeepers) EthValidateBasicDecorator { return EthValidateBasicDecorator{ - evmKeeper: k, + AppKeepers: k, } } @@ -89,8 +89,8 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu txFee := sdk.Coins{} txGasLimit := uint64(0) - evmParams := vbd.evmKeeper.GetParams(ctx) - baseFee := vbd.evmKeeper.GetBaseFee(ctx) + evmParams := vbd.EvmKeeper.GetParams(ctx) + baseFee := vbd.EvmKeeper.GetBaseFee(ctx) enableCreate := evmParams.GetEnableCreate() enableCall := evmParams.GetEnableCall() evmDenom := evmParams.GetEvmDenom() diff --git a/app/evmante/evmante_validate_basic_test.go b/app/evmante_validate_basic_test.go similarity index 89% rename from app/evmante/evmante_validate_basic_test.go rename to app/evmante_validate_basic_test.go index 77b59c44b..f3b74d4fc 100644 --- a/app/evmante/evmante_validate_basic_test.go +++ b/app/evmante_validate_basic_test.go @@ -1,4 +1,4 @@ -package evmante_test +package app_test import ( "math/big" @@ -10,10 +10,9 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/common" - "github.com/NibiruChain/nibiru/app/evmante" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/eth" "github.com/NibiruChain/nibiru/x/common/testutil" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" ) @@ -30,7 +29,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { name: "happy: properly built eth tx", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() - tx, err := evmtestutil.HappyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) + tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) s.Require().NoError(err) return tx }, @@ -42,21 +41,21 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { deps.Ctx = deps.Ctx.WithIsReCheckTx(true) }, txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - return evmtestutil.HappyCreateContractTx(deps) + return happyCreateContractTx(deps) }, wantErr: "", }, { name: "sad: fail chain id basic validation", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - return evmtestutil.HappyCreateContractTx(deps) + return happyCreateContractTx(deps) }, wantErr: "invalid chain-id", }, { name: "sad: tx not implementing protoTxProvider", txSetup: func(deps *evmtest.TestDeps) sdk.Tx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) gethSigner := deps.Sender.GethSigner(InvalidChainID) keyringSigner := deps.Sender.KeyringSigner err := tx.Sign(gethSigner, keyringSigner) @@ -70,7 +69,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { txSetup: func(deps *evmtest.TestDeps) sdk.Tx { txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() txBuilder.SetMemo("memo") - tx, err := evmtestutil.HappyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) + tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) s.Require().NoError(err) return tx }, @@ -81,7 +80,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { txSetup: func(deps *evmtest.TestDeps) sdk.Tx { txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() txBuilder.SetFeePayer(testutil.AccAddress()) - tx, err := evmtestutil.HappyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) + tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) s.Require().NoError(err) return tx }, @@ -92,7 +91,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { txSetup: func(deps *evmtest.TestDeps) sdk.Tx { txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() txBuilder.SetFeeGranter(testutil.AccAddress()) - tx, err := evmtestutil.HappyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) + tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) s.Require().NoError(err) return tx }, @@ -112,7 +111,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { } err := txBuilder.SetSignatures(sigV2) s.Require().NoError(err) - txMsg := evmtestutil.HappyCreateContractTx(deps) + txMsg := happyCreateContractTx(deps) gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) keyringSigner := deps.Sender.KeyringSigner @@ -134,7 +133,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { }, txSetup: func(deps *evmtest.TestDeps) sdk.Tx { txBuilder := deps.EncCfg.TxConfig.NewTxBuilder() - tx, err := evmtestutil.HappyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) + tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom) s.Require().NoError(err) return tx }, @@ -221,7 +220,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewEthValidateBasicDecorator(&deps.Chain.AppKeepers.EvmKeeper) + anteDec := app.NewEthValidateBasicDecorator(deps.Chain.AppKeepers) tx := tc.txSetup(&deps) s.Require().NoError(stateDB.Commit()) @@ -233,7 +232,7 @@ func (s *TestSuite) TestEthValidateBasicDecorator() { deps.K.SetParams(deps.Ctx, tc.paramsSetup(&deps)) } _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) diff --git a/app/evmante/evmante_verify_eth_acc.go b/app/evmante_verify_eth_acc.go similarity index 85% rename from app/evmante/evmante_verify_eth_acc.go rename to app/evmante_verify_eth_acc.go index d3bb8a4f0..6832bc06e 100644 --- a/app/evmante/evmante_verify_eth_acc.go +++ b/app/evmante_verify_eth_acc.go @@ -1,29 +1,34 @@ // Copyright (c) 2023-2024 Nibi, Inc. -package evmante +package app import ( "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - gethcommon "github.com/ethereum/go-ethereum/common" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/keeper" "github.com/NibiruChain/nibiru/x/evm/statedb" + + gethcommon "github.com/ethereum/go-ethereum/common" +) + +var ( + _ sdk.AnteDecorator = (*AnteDecEthGasConsume)(nil) + _ sdk.AnteDecorator = (*AnteDecVerifyEthAcc)(nil) ) // AnteDecVerifyEthAcc validates an account balance checks type AnteDecVerifyEthAcc struct { - evmKeeper EVMKeeper - accountKeeper evm.AccountKeeper + AppKeepers } // NewAnteDecVerifyEthAcc creates a new EthAccountVerificationDecorator -func NewAnteDecVerifyEthAcc(k EVMKeeper, ak evm.AccountKeeper) AnteDecVerifyEthAcc { +func NewAnteDecVerifyEthAcc(k AppKeepers) AnteDecVerifyEthAcc { return AnteDecVerifyEthAcc{ - evmKeeper: k, - accountKeeper: ak, + AppKeepers: k, } } @@ -62,11 +67,11 @@ func (anteDec AnteDecVerifyEthAcc) AnteHandle( // check whether the sender address is EOA fromAddr := gethcommon.BytesToAddress(from) - acct := anteDec.evmKeeper.GetAccount(ctx, fromAddr) + acct := anteDec.EvmKeeper.GetAccount(ctx, fromAddr) if acct == nil { - acc := anteDec.accountKeeper.NewAccountWithAddress(ctx, from) - anteDec.accountKeeper.SetAccount(ctx, acc) + acc := anteDec.AccountKeeper.NewAccountWithAddress(ctx, from) + anteDec.AccountKeeper.SetAccount(ctx, acc) acct = statedb.NewEmptyAccount() } else if acct.IsContract() { return ctx, errors.Wrapf(errortypes.ErrInvalidType, diff --git a/app/evmante/evmante_verify_eth_acc_test.go b/app/evmante_verify_eth_acc_test.go similarity index 54% rename from app/evmante/evmante_verify_eth_acc_test.go rename to app/evmante_verify_eth_acc_test.go index 2fa78400a..c8f124ac0 100644 --- a/app/evmante/evmante_verify_eth_acc_test.go +++ b/app/evmante_verify_eth_acc_test.go @@ -1,17 +1,26 @@ -package evmante_test +package app_test import ( "math/big" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + gethparams "github.com/ethereum/go-ethereum/params" - "github.com/NibiruChain/nibiru/app/evmante" - evmtestutil "github.com/NibiruChain/nibiru/x/common/testutil/evm" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" + "github.com/NibiruChain/nibiru/x/evm/statedb" ) +var NextNoOpAnteHandler sdk.AnteHandler = func( + ctx sdk.Context, tx sdk.Tx, simulate bool, +) (newCtx sdk.Context, err error) { + return ctx, nil +} + func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() { testCases := []struct { name string @@ -24,13 +33,13 @@ func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() { beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) { sdb.AddBalance(deps.Sender.EthAddr, happyGasLimit()) }, - txSetup: evmtestutil.HappyCreateContractTx, + txSetup: happyCreateContractTx, wantErr: "", }, { name: "sad: sender has insufficient gas balance", beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {}, - txSetup: evmtestutil.HappyCreateContractTx, + txSetup: happyCreateContractTx, wantErr: "sender balance < tx cost", }, { @@ -39,7 +48,7 @@ func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() { // Force account to be a smart contract sdb.SetCode(deps.Sender.EthAddr, []byte("evm bytecode stuff")) }, - txSetup: evmtestutil.HappyCreateContractTx, + txSetup: happyCreateContractTx, wantErr: "sender is not EOA", }, { @@ -54,7 +63,7 @@ func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() { name: "sad: empty from addr", beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {}, txSetup: func(deps *evmtest.TestDeps) *evm.MsgEthereumTx { - tx := evmtestutil.HappyCreateContractTx(deps) + tx := happyCreateContractTx(deps) tx.From = "" return tx }, @@ -66,7 +75,7 @@ func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() { s.Run(tc.name, func() { deps := evmtest.NewTestDeps() stateDB := deps.StateDB() - anteDec := evmante.NewAnteDecVerifyEthAcc(&deps.Chain.AppKeepers.EvmKeeper, &deps.Chain.AppKeepers.AccountKeeper) + anteDec := app.NewAnteDecVerifyEthAcc(deps.Chain.AppKeepers) tc.beforeTxSetup(&deps, stateDB) tx := tc.txSetup(&deps) @@ -74,7 +83,7 @@ func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() { deps.Ctx = deps.Ctx.WithIsCheckTx(true) _, err := anteDec.AnteHandle( - deps.Ctx, tx, false, evmtestutil.NextNoOpAnteHandler, + deps.Ctx, tx, false, NextNoOpAnteHandler, ) if tc.wantErr != "" { s.Require().ErrorContains(err, tc.wantErr) @@ -91,3 +100,48 @@ func happyGasLimit() *big.Int { // 888 is a cushion to account for KV store reads and writes ) } + +func gasLimitCreateContract() *big.Int { + return new(big.Int).SetUint64( + gethparams.TxGasContractCreation + 700, + ) +} + +func happyCreateContractTx(deps *evmtest.TestDeps) *evm.MsgEthereumTx { + ethContractCreationTxParams := &evm.EvmTxArgs{ + ChainID: deps.Chain.EvmKeeper.EthChainID(deps.Ctx), + Nonce: 1, + Amount: big.NewInt(10), + GasLimit: gasLimitCreateContract().Uint64(), + GasPrice: big.NewInt(1), + } + tx := evm.NewTx(ethContractCreationTxParams) + tx.From = deps.Sender.EthAddr.Hex() + return tx +} + +func happyTransfertTx(deps *evmtest.TestDeps, nonce uint64) *evm.MsgEthereumTx { + to := evmtest.NewEthAccInfo().EthAddr + ethContractCreationTxParams := &evm.EvmTxArgs{ + ChainID: deps.Chain.EvmKeeper.EthChainID(deps.Ctx), + Nonce: nonce, + Amount: big.NewInt(10), + GasLimit: gasLimitCreateContract().Uint64(), + GasPrice: big.NewInt(1), + To: &to, + } + tx := evm.NewTx(ethContractCreationTxParams) + tx.From = deps.Sender.EthAddr.Hex() + return tx +} + +func nonEvmMsgTx(deps *evmtest.TestDeps) sdk.Tx { + gasLimit := uint64(10) + fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit))) + msg := &banktypes.MsgSend{ + FromAddress: deps.Sender.NibiruAddr.String(), + ToAddress: evmtest.NewEthAccInfo().NibiruAddr.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("unibi", 1)), + } + return buildTx(deps, true, msg, gasLimit, fees) +} diff --git a/x/common/testutil/evm/evm.go b/x/common/testutil/evm/evm.go deleted file mode 100644 index 3090de617..000000000 --- a/x/common/testutil/evm/evm.go +++ /dev/null @@ -1,87 +0,0 @@ -package evmtestutil - -import ( - "math/big" - - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - gethparams "github.com/ethereum/go-ethereum/params" - - "github.com/NibiruChain/nibiru/x/evm" - "github.com/NibiruChain/nibiru/x/evm/evmtest" -) - -var NextNoOpAnteHandler sdk.AnteHandler = func( - ctx sdk.Context, tx sdk.Tx, simulate bool, -) (newCtx sdk.Context, err error) { - return ctx, nil -} - -func HappyTransferTx(deps *evmtest.TestDeps, nonce uint64) *evm.MsgEthereumTx { - to := evmtest.NewEthAccInfo().EthAddr - ethContractCreationTxParams := &evm.EvmTxArgs{ - ChainID: deps.Chain.EvmKeeper.EthChainID(deps.Ctx), - Nonce: nonce, - Amount: big.NewInt(10), - GasLimit: GasLimitCreateContract().Uint64(), - GasPrice: big.NewInt(1), - To: &to, - } - tx := evm.NewTx(ethContractCreationTxParams) - tx.From = deps.Sender.EthAddr.Hex() - return tx -} - -func NonEvmMsgTx(deps *evmtest.TestDeps) sdk.Tx { - gasLimit := uint64(10) - fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit))) - msg := &banktypes.MsgSend{ - FromAddress: deps.Sender.NibiruAddr.String(), - ToAddress: evmtest.NewEthAccInfo().NibiruAddr.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("unibi", 1)), - } - return buildTx(deps, true, msg, gasLimit, fees) -} - -func buildTx( - deps *evmtest.TestDeps, - ethExtentions bool, - msg sdk.Msg, - gasLimit uint64, - fees sdk.Coins, -) sdk.FeeTx { - txBuilder, _ := deps.EncCfg.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder) - if ethExtentions { - option, _ := codectypes.NewAnyWithValue(&evm.ExtensionOptionsEthereumTx{}) - txBuilder.SetExtensionOptions(option) - } - err := txBuilder.SetMsgs(msg) - if err != nil { - panic(err) - } - txBuilder.SetGasLimit(gasLimit) - txBuilder.SetFeeAmount(fees) - - return txBuilder.GetTx() -} - -func HappyCreateContractTx(deps *evmtest.TestDeps) *evm.MsgEthereumTx { - ethContractCreationTxParams := &evm.EvmTxArgs{ - ChainID: deps.Chain.EvmKeeper.EthChainID(deps.Ctx), - Nonce: 1, - Amount: big.NewInt(10), - GasLimit: GasLimitCreateContract().Uint64(), - GasPrice: big.NewInt(1), - } - tx := evm.NewTx(ethContractCreationTxParams) - tx.From = deps.Sender.EthAddr.Hex() - return tx -} - -func GasLimitCreateContract() *big.Int { - return new(big.Int).SetUint64( - gethparams.TxGasContractCreation + 700, - ) -}