diff --git a/CHANGELOG.md b/CHANGELOG.md index 06a5b4824..2c316d31a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - [\#589](https://github.com/cosmos/evm/pull/589) Remove parallelization blockers via migration from transient to object store, refactoring of gas, indexing, and bloom utilities. - [\#768](https://github.com/cosmos/evm/pull/768) Added ICS-02 Client Router precompile - [\#815](https://github.com/cosmos/evm/pull/815) Support for multi gRPC query clients serve with old binary. +- [\#1082](https://github.com/cosmos/evm/pull/1082) Enable incarnation cache for verify result. ### BUG FIXES diff --git a/ante/evm/05_signature_verification.go b/ante/evm/05_signature_verification.go index e24aee83c..12c2258ad 100644 --- a/ante/evm/05_signature_verification.go +++ b/ante/evm/05_signature_verification.go @@ -14,6 +14,8 @@ import ( errortypes "github.com/cosmos/cosmos-sdk/types/errors" ) +const EthSigVerificationResultCacheKey = "ante:EthSigVerificationResult" + // EthSigVerificationDecorator validates an ethereum signatures type EthSigVerificationDecorator struct { evmKeeper anteinterfaces.EVMKeeper @@ -32,6 +34,15 @@ func NewEthSigVerificationDecorator(ek anteinterfaces.EVMKeeper) EthSigVerificat // Failure in RecheckTx will prevent tx to be included into block, especially when CheckTx succeed, in which case user // won't see the error message. func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if v, ok := ctx.GetIncarnationCache(EthSigVerificationResultCacheKey); ok { + if v != nil { + if cachedErr, ok := v.(error); ok { + return ctx, cachedErr + } + } + return next(ctx, tx, simulate) + } + ethCfg := evmtypes.GetEthChainConfig() blockNum := big.NewInt(ctx.BlockHeight()) signer := ethtypes.MakeSigner(ethCfg, blockNum, uint64(ctx.BlockTime().Unix())) //#nosec G115 -- int overflow is not a concern here @@ -44,15 +55,20 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s for _, msg := range msgs { msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) if !ok { - return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) + err = errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) + ctx.SetIncarnationCache(EthSigVerificationResultCacheKey, err) + return ctx, err } - err := SignatureVerification(msgEthTx, msgEthTx.AsTransaction(), signer) + err = SignatureVerification(msgEthTx, msgEthTx.AsTransaction(), signer) if err != nil { + ctx.SetIncarnationCache(EthSigVerificationResultCacheKey, err) return ctx, err } } + ctx.SetIncarnationCache(EthSigVerificationResultCacheKey, nil) + return next(ctx, tx, simulate) } diff --git a/ante/evm/mono_decorator.go b/ante/evm/mono_decorator.go index 9cccf8a79..1188f73ab 100644 --- a/ante/evm/mono_decorator.go +++ b/ante/evm/mono_decorator.go @@ -159,8 +159,18 @@ func (md MonoDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne } // 5. signature verification - if err := SignatureVerification(ethMsg, ethTx, decUtils.Signer); err != nil { - return ctx, err + if v, ok := ctx.GetIncarnationCache(EthSigVerificationResultCacheKey); ok { + if v != nil { + if cachedErr, ok := v.(error); ok { + return ctx, cachedErr + } + } + } else { + err = SignatureVerification(ethMsg, ethTx, decUtils.Signer) + ctx.SetIncarnationCache(EthSigVerificationResultCacheKey, err) + if err != nil { + return ctx, err + } } from := ethMsg.GetFrom()