Some checks failed
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
Build & Push SDK Proto Builder / build (push) Has been cancelled
213 lines
7.1 KiB
Go
213 lines
7.1 KiB
Go
package ante_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/mock/gomock"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
|
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
|
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
|
txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
|
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
)
|
|
|
|
type UnorderedTxTestSuite struct {
|
|
anteSuite *AnteTestSuite
|
|
priv1, priv2, priv3 cryptotypes.PrivKey
|
|
antehandler sdk.AnteHandler
|
|
defaultSignMode signing.SignMode
|
|
accs []sdk.AccountI
|
|
msgs []sdk.Msg
|
|
}
|
|
|
|
func setupUnorderedTxTestSuite(t *testing.T, isCheckTx, withUnordered bool) *UnorderedTxTestSuite {
|
|
t.Helper()
|
|
anteSuite := SetupTestSuiteWithUnordered(t, isCheckTx, withUnordered)
|
|
anteSuite.txBankKeeper.EXPECT().DenomMetadata(gomock.Any(), gomock.Any()).Return(&banktypes.QueryDenomMetadataResponse{}, nil).AnyTimes()
|
|
|
|
enabledSignModes := []signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT}
|
|
txConfigOpts := authtx.ConfigOptions{
|
|
TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(anteSuite.clientCtx),
|
|
EnabledSignModes: enabledSignModes,
|
|
}
|
|
var err error
|
|
anteSuite.clientCtx.TxConfig, err = authtx.NewTxConfigWithOptions(
|
|
codec.NewProtoCodec(anteSuite.encCfg.InterfaceRegistry),
|
|
txConfigOpts,
|
|
)
|
|
require.NoError(t, err)
|
|
anteSuite.txBuilder = anteSuite.clientCtx.TxConfig.NewTxBuilder()
|
|
|
|
// make block height non-zero to ensure account numbers part of signBytes
|
|
anteSuite.ctx = anteSuite.ctx.WithBlockHeight(1)
|
|
|
|
// keys and addresses
|
|
pk1, _, addr1 := testdata.KeyTestPubAddr()
|
|
pk2, _, addr2 := testdata.KeyTestPubAddr()
|
|
pk3, _, addr3 := testdata.KeyTestPubAddr()
|
|
priv1, priv2, priv3 := pk1, pk2, pk3
|
|
|
|
addrs := []sdk.AccAddress{addr1, addr2, addr3}
|
|
|
|
msgs := make([]sdk.Msg, len(addrs))
|
|
accs := make([]sdk.AccountI, len(addrs))
|
|
// set accounts and create msg for each address
|
|
for i, addr := range addrs {
|
|
acc := anteSuite.accountKeeper.NewAccountWithAddress(anteSuite.ctx, addr)
|
|
require.NoError(t, acc.SetAccountNumber(uint64(i)+1000))
|
|
anteSuite.accountKeeper.SetAccount(anteSuite.ctx, acc)
|
|
msgs[i] = testdata.NewTestMsg(addr)
|
|
accs[i] = acc
|
|
}
|
|
|
|
spkd := ante.NewSetPubKeyDecorator(anteSuite.accountKeeper)
|
|
txConfigOpts = authtx.ConfigOptions{
|
|
TextualCoinMetadataQueryFn: txmodule.NewBankKeeperCoinMetadataQueryFn(anteSuite.txBankKeeper),
|
|
EnabledSignModes: enabledSignModes,
|
|
}
|
|
anteTxConfig, err := authtx.NewTxConfigWithOptions(
|
|
codec.NewProtoCodec(anteSuite.encCfg.InterfaceRegistry),
|
|
txConfigOpts,
|
|
)
|
|
require.NoError(t, err)
|
|
svd := ante.NewSigVerificationDecorator(anteSuite.accountKeeper, anteTxConfig.SignModeHandler())
|
|
antehandler := sdk.ChainAnteDecorators(spkd, svd)
|
|
defaultSignMode := signing.SignMode_SIGN_MODE_DIRECT
|
|
|
|
return &UnorderedTxTestSuite{
|
|
anteSuite: anteSuite,
|
|
priv1: priv1,
|
|
priv2: priv2,
|
|
priv3: priv3,
|
|
antehandler: antehandler,
|
|
defaultSignMode: defaultSignMode,
|
|
accs: accs,
|
|
msgs: msgs,
|
|
}
|
|
}
|
|
|
|
func TestSigVerification_UnorderedTxs(t *testing.T) {
|
|
feeAmount := testdata.NewTestFeeAmount()
|
|
gasLimit := testdata.NewTestGasLimit()
|
|
testCases := map[string]struct {
|
|
unorderedDisabled bool
|
|
unordered bool
|
|
timeout time.Time
|
|
blockTime time.Time
|
|
duplicate bool
|
|
execMode sdk.ExecMode
|
|
expectedErr string
|
|
}{
|
|
"normal/ordered tx should just skip": {
|
|
unordered: false,
|
|
blockTime: time.Unix(0, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
},
|
|
"normal/ordered tx should just skip with unordered disabled too": {
|
|
unorderedDisabled: true,
|
|
unordered: false,
|
|
blockTime: time.Unix(0, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
},
|
|
"happy case": {
|
|
unordered: true,
|
|
timeout: time.Unix(10, 0),
|
|
blockTime: time.Unix(0, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
},
|
|
"zero time should fail": {
|
|
unordered: true,
|
|
blockTime: time.Unix(10, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
expectedErr: "unordered transaction must have timeout_timestamp set",
|
|
},
|
|
"fail if tx is unordered but unordered is disabled": {
|
|
unorderedDisabled: true,
|
|
unordered: true,
|
|
blockTime: time.Unix(10, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
expectedErr: "unordered transactions are not enabled",
|
|
},
|
|
"timeout before current block time should fail": {
|
|
unordered: true,
|
|
timeout: time.Unix(7, 0),
|
|
blockTime: time.Unix(10, 1),
|
|
execMode: sdk.ExecModeFinalize,
|
|
expectedErr: "unordered transaction has a timeout_timestamp that has already passed",
|
|
},
|
|
"timeout equal to current block time should pass": {
|
|
unordered: true,
|
|
timeout: time.Unix(10, 0),
|
|
blockTime: time.Unix(10, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
},
|
|
"timeout after the max duration should fail": {
|
|
unordered: true,
|
|
timeout: time.Unix(10, 1).Add(ante.DefaultMaxTimeoutDuration),
|
|
blockTime: time.Unix(10, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
expectedErr: "unordered tx ttl exceeds",
|
|
},
|
|
"fails if manager has duplicate": {
|
|
unordered: true,
|
|
timeout: time.Unix(10, 0),
|
|
duplicate: true,
|
|
blockTime: time.Unix(5, 0),
|
|
execMode: sdk.ExecModeFinalize,
|
|
expectedErr: "already used timeout",
|
|
},
|
|
"duplicate doesn't matter if we're in simulate mode": {
|
|
unordered: true,
|
|
timeout: time.Unix(10, 0),
|
|
duplicate: true,
|
|
blockTime: time.Unix(5, 0),
|
|
execMode: sdk.ExecModeSimulate,
|
|
},
|
|
}
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
suite := setupUnorderedTxTestSuite(t, tc.execMode == sdk.ExecModeCheck, !tc.unorderedDisabled)
|
|
ctx := suite.anteSuite.ctx.WithBlockTime(tc.blockTime).WithExecMode(tc.execMode).WithIsSigverifyTx(true)
|
|
|
|
suite.anteSuite.txBuilder = suite.anteSuite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test
|
|
require.NoError(t, suite.anteSuite.txBuilder.SetMsgs(suite.msgs...))
|
|
suite.anteSuite.txBuilder.SetFeeAmount(feeAmount)
|
|
suite.anteSuite.txBuilder.SetGasLimit(gasLimit)
|
|
tx, err := suite.anteSuite.CreateTestUnorderedTx(
|
|
suite.anteSuite.ctx,
|
|
[]cryptotypes.PrivKey{suite.priv1, suite.priv2, suite.priv3},
|
|
[]uint64{suite.accs[0].GetAccountNumber(), suite.accs[1].GetAccountNumber(), suite.accs[2].GetAccountNumber()},
|
|
[]uint64{0, 0, 0},
|
|
suite.anteSuite.ctx.ChainID(),
|
|
suite.defaultSignMode,
|
|
tc.unordered,
|
|
tc.timeout,
|
|
)
|
|
require.NoError(t, err)
|
|
txBytes, err := suite.anteSuite.clientCtx.TxConfig.TxEncoder()(tx)
|
|
require.NoError(t, err)
|
|
ctx = ctx.WithTxBytes(txBytes)
|
|
|
|
simulate := tc.execMode == sdk.ExecModeSimulate
|
|
|
|
if tc.duplicate {
|
|
_, err = suite.antehandler(ctx, tx, simulate)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
_, err = suite.antehandler(ctx, tx, simulate)
|
|
if tc.expectedErr != "" {
|
|
require.ErrorContains(t, err, tc.expectedErr)
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|