Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: skip sequence number check at simulation #107

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions app/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ func (suite *AnteTestSuite) SetupTest() {
}

// CreateTestTx is a helper function to create a tx given multiple inputs.
func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []uint64, accSeqs []uint64, chainID string) (authsign.Tx, error) {
defaultSignMode, err := authsign.APISignModeToInternal(suite.clientCtx.TxConfig.SignModeHandler().DefaultMode())
suite.NoError(err)

func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []uint64, accSeqs []uint64, chainID string, signMode signing.SignMode) (authsign.Tx, error) {
// First round: we gather all the signer infos. We use the "set empty
// signature" hack to do that.
var sigsV2 []signing.SignatureV2
Expand All @@ -91,15 +88,15 @@ func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []
sigV2 := signing.SignatureV2{
PubKey: priv.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: defaultSignMode,
SignMode: signMode,
beer-1 marked this conversation as resolved.
Show resolved Hide resolved
Signature: nil,
},
Sequence: accSeqs[i],
}

sigsV2 = append(sigsV2, sigV2)
}
err = suite.txBuilder.SetSignatures(sigsV2...)
err := suite.txBuilder.SetSignatures(sigsV2...)
if err != nil {
return nil, err
}
Expand All @@ -115,7 +112,7 @@ func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []
PubKey: priv.PubKey(),
}
sigV2, err := tx.SignWithPrivKey(
context.TODO(), defaultSignMode, signerData,
context.TODO(), signMode, signerData,
suite.txBuilder, priv, suite.clientCtx.TxConfig, accSeqs[i])
if err != nil {
return nil, err
Expand Down
5 changes: 4 additions & 1 deletion app/ante/fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
authsign "github.com/cosmos/cosmos-sdk/x/auth/signing"

"github.com/initia-labs/minievm/app/ante"
)
Expand Down Expand Up @@ -33,7 +34,9 @@ func (suite *AnteTestSuite) Test_NotSpendingGasForTxWithFeeDenom() {
suite.txBuilder.SetGasLimit(gasLimit)

privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID())
defaultSignMode, err := authsign.APISignModeToInternal(suite.app.TxConfig().SignModeHandler().DefaultMode())
suite.NoError(err)
tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID(), defaultSignMode)
suite.Require().NoError(err)

gasMeter := storetypes.NewGasMeter(500000)
Expand Down
12 changes: 11 additions & 1 deletion app/ante/sigverify.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/types"

"github.com/initia-labs/initia/crypto/ethsecp256k1"
evmkeeper "github.com/initia-labs/minievm/x/evm/keeper"
)

// SigVerificationDecorator verifies all signatures for a tx and return an error if any are invalid. Note,
Expand Down Expand Up @@ -81,8 +82,17 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
}

skipSequenceCheck := false
if simulate && len(sigs) == 1 {
if sigData, ok := sig.Data.(*signing.SingleSignatureData); ok {
if sigData.SignMode == evmkeeper.SignMode_SIGN_MODE_ETHEREUM {
beer-1 marked this conversation as resolved.
Show resolved Hide resolved
skipSequenceCheck = true
}
}
}

// Check account sequence number.
if sig.Sequence != acc.GetSequence() {
if !skipSequenceCheck && sig.Sequence != acc.GetSequence() {
return ctx, errorsmod.Wrapf(
sdkerrors.ErrWrongSequence,
"account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence,
Expand Down
56 changes: 56 additions & 0 deletions app/ante/sigverify_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package ante_test

import (
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"

"github.com/initia-labs/minievm/app/ante"
evmkeeper "github.com/initia-labs/minievm/x/evm/keeper"
)

func (suite *AnteTestSuite) Test_SkipSequenceCheck() {
suite.SetupTest() // setup
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()

priv1, _, addr1 := testdata.KeyTestPubAddr()
acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
acc1.SetPubKey(priv1.PubKey())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc1)

suite.txBuilder.SetMsgs(testdata.NewTestMsg(addr1))
suite.txBuilder.SetSignatures()

sigV2 := signing.SignatureV2{
PubKey: priv1.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: evmkeeper.SignMode_SIGN_MODE_ETHEREUM,
Signature: nil,
},
// invalid sequence
Sequence: 100,
}

err := suite.txBuilder.SetSignatures(sigV2)
suite.NoError(err)

// 1. simulate should skip sequence check
sigVerifyAnte := ante.NewSigVerificationDecorator(suite.app.AccountKeeper, suite.app.EVMKeeper, suite.app.TxConfig().SignModeHandler())
_, err = sigVerifyAnte.AnteHandle(suite.ctx, suite.txBuilder.GetTx(), true, func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil })
suite.NoError(err)

// 2. simulate should check sequence when it is not ethereum sign mode
sigV2.Data.(*signing.SingleSignatureData).SignMode = signing.SignMode_SIGN_MODE_DIRECT
err = suite.txBuilder.SetSignatures(sigV2)
suite.NoError(err)
_, err = sigVerifyAnte.AnteHandle(suite.ctx, suite.txBuilder.GetTx(), true, func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil })
suite.ErrorIs(err, sdkerrors.ErrWrongSequence)

// 3. non-simulate should check sequence
sigV2.Data.(*signing.SingleSignatureData).SignMode = evmkeeper.SignMode_SIGN_MODE_ETHEREUM
err = suite.txBuilder.SetSignatures(sigV2)
suite.NoError(err)
_, err = sigVerifyAnte.AnteHandle(suite.ctx, suite.txBuilder.GetTx(), false, func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil })
suite.ErrorIs(err, sdkerrors.ErrWrongSequence)
}
Loading