diff --git a/app/ante/ante.go b/app/ante/ante.go index 7d9586edfb..83d8345b4a 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -17,10 +17,10 @@ package ante import ( "fmt" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" "runtime/debug" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ethante "github.com/evmos/ethermint/app/ante" cctxtypes "github.com/zeta-chain/zetacore/x/crosschain/types" tmlog "github.com/tendermint/tendermint/libs/log" @@ -29,9 +29,10 @@ import ( 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/cosmos/cosmos-sdk/x/authz" ) -func ValidateHandlerOptions(options ethante.HandlerOptions) error { +func ValidateHandlerOptions(options HandlerOptions) error { if options.AccountKeeper == nil { return errorsmod.Wrap(errortypes.ErrLogic, "account keeper is required for AnteHandler") } @@ -47,6 +48,9 @@ func ValidateHandlerOptions(options ethante.HandlerOptions) error { if options.EvmKeeper == nil { return errorsmod.Wrap(errortypes.ErrLogic, "evm keeper is required for AnteHandler") } + if options.ObserverKeeper == nil { + return errorsmod.Wrap(errortypes.ErrLogic, "observer keeper is required for AnteHandler") + } return nil } @@ -54,7 +58,7 @@ func ValidateHandlerOptions(options ethante.HandlerOptions) error { // Ethereum or SDK transaction to an internal ante handler for performing // transaction-level processing (e.g. fee payment, signature verification) before // being passed onto it's respective handler. -func NewAnteHandler(options ethante.HandlerOptions) (sdk.AnteHandler, error) { +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if err := ValidateHandlerOptions(options); err != nil { return nil, err } @@ -94,28 +98,55 @@ func NewAnteHandler(options ethante.HandlerOptions) (sdk.AnteHandler, error) { // handle as totally normal Cosmos SDK tx switch tx.(type) { case sdk.Tx: - found := false - for _, msg := range tx.GetMsgs() { - switch msg.(type) { - // treat these three msg types differently because they might call EVM which results in massive gas consumption - // For these two msg types, we don't check gas limit by using a different ante handler - case *cctxtypes.MsgGasPriceVoter, *cctxtypes.MsgVoteOnObservedInboundTx: - found = true - break - case *stakingtypes.MsgCreateValidator: - if ctx.BlockHeight() == 0 { - found = true - break - } + anteHandler = newCosmosAnteHandler(options) + if len(tx.GetMsgs()) != 1 { + break + } + + msg := tx.GetMsgs()[0] // now we must have len(tx.GetMsgs()) == 1 + var innerMsg sdk.Msg + innerMsg = msg + if mm, ok := msg.(*authz.MsgExec); ok { // authz tx; look inside it + msgs, err := mm.GetMessages() + if err == nil && len(msgs) == 1 { + innerMsg = msgs[0] } } - if len(tx.GetMsgs()) == 1 && found { - // this differs newCosmosAnteHandler only in that it doesn't check gas limit - // by using an Infinite Gas Meter. - anteHandler = newCosmosAnteHandlerNoGasLimit(options) - } else { - anteHandler = newCosmosAnteHandler(options) + + isAuthorize := options.ObserverKeeper.IsAuthorized + if mm, ok := innerMsg.(*cctxtypes.MsgGasPriceVoter); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + if mm, ok := innerMsg.(*cctxtypes.MsgVoteOnObservedInboundTx); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + if mm, ok := innerMsg.(*cctxtypes.MsgVoteOnObservedOutboundTx); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break } + if mm, ok := innerMsg.(*cctxtypes.MsgAddToOutTxTracker); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + if mm, ok := innerMsg.(*cctxtypes.MsgCreateTSSVoter); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + if mm, ok := innerMsg.(*observertypes.MsgAddBlockHeader); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + if mm, ok := innerMsg.(*observertypes.MsgAddBlameVote); ok && isAuthorize(ctx, mm.Creator) { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + if _, ok := innerMsg.(*stakingtypes.MsgCreateValidator); ok && ctx.BlockHeight() == 0 { + anteHandler = newCosmosAnteHandlerNoGasFee(options) + break + } + default: return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid transaction type: %T", tx) } diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 5fe40847e9..c1052765b1 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -18,17 +18,39 @@ package ante import ( "fmt" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + evmtypes "github.com/evmos/ethermint/x/evm/types" + observerkeeper "github.com/zeta-chain/zetacore/x/observer/keeper" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" ibcante "github.com/cosmos/ibc-go/v6/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper" ethante "github.com/evmos/ethermint/app/ante" ethermint "github.com/evmos/ethermint/types" ) -func NewLegacyCosmosAnteHandlerEip712(options ethante.HandlerOptions) sdk.AnteHandler { +type HandlerOptions struct { + AccountKeeper evmtypes.AccountKeeper + BankKeeper evmtypes.BankKeeper + IBCKeeper *ibckeeper.Keeper + FeeMarketKeeper FeeMarketKeeper + EvmKeeper EVMKeeper + FeegrantKeeper ante.FeegrantKeeper + SignModeHandler authsigning.SignModeHandler + SigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error + MaxTxGasWanted uint64 + ExtensionOptionChecker ante.ExtensionOptionChecker + TxFeeChecker ante.TxFeeChecker + DisabledAuthzMsgs []string + ObserverKeeper *observerkeeper.Keeper +} + +func NewLegacyCosmosAnteHandlerEip712(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs NewAuthzLimiterDecorator(options.DisabledAuthzMsgs...), @@ -52,7 +74,7 @@ func NewLegacyCosmosAnteHandlerEip712(options ethante.HandlerOptions) sdk.AnteHa ) } -func newEthAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { +func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first ethante.NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices @@ -68,7 +90,7 @@ func newEthAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { ) } -func newCosmosAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { +func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs NewAuthzLimiterDecorator(options.DisabledAuthzMsgs...), @@ -92,19 +114,21 @@ func newCosmosAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { } // this applies to special cosmos tx that calls EVM, in which case the EVM overrides the gas limit -func newCosmosAnteHandlerNoGasLimit(options ethante.HandlerOptions) sdk.AnteHandler { +func newCosmosAnteHandlerNoGasFee(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs NewAuthzLimiterDecorator(options.DisabledAuthzMsgs...), NewVestingAccountDecorator(), - NewSetUpContextDecorator(), + ante.NewSetUpContextDecorator(), ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), - NewMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), + // system txs are not subject to minimum gas price check + //NewMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), - ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), + // the following decorators are disabled; so no fees are deducted for special system txs. + //ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewSetPubKeyDecorator(options.AccountKeeper), ante.NewValidateSigCountDecorator(options.AccountKeeper), diff --git a/app/app.go b/app/app.go index d78ef88643..a87abb240b 100644 --- a/app/app.go +++ b/app/app.go @@ -575,7 +575,7 @@ func New( app.SetBeginBlocker(app.BeginBlocker) maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted)) - options := evmante.HandlerOptions{ + options := ante.HandlerOptions{ AccountKeeper: app.AccountKeeper, BankKeeper: app.BankKeeper, EvmKeeper: app.EvmKeeper, @@ -589,6 +589,7 @@ func New( sdk.MsgTypeURL(&vestingtypes.MsgCreatePermanentLockedAccount{}), sdk.MsgTypeURL(&vestingtypes.MsgCreatePeriodicVestingAccount{}), }, + ObserverKeeper: app.ZetaObserverKeeper, } anteHandler, err := ante.NewAnteHandler(options)