From a8a52d07752cdeb874948ab5f02494cf3e8450ff Mon Sep 17 00:00:00 2001 From: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Date: Wed, 27 Jul 2022 14:49:19 -0300 Subject: [PATCH] refactor: use mocks for x/auth testing + ante tests refactor (#12568) ## Description Main changes: #### `x/auth` and `x/auth/ante` stopped depending on simapp Some usages are left but this PR grew too much, so we might want to do it in a separate. #### Removed all usages of the `suite` in `ante` This makes tests way more verbose but helps keep the test cases self-contained and easier to understand (before you would need to mentally track the state of the suite throughout the test cases to understand them). Also, it's easier to test, given that all tests are converted to standard Go unit tests (`func TestSomething(t *testing.T){`) and at least VSCode recognizes them and lets you run a single one instead of the entire suite. I think this can/should be replicated in other modules. Closes: #12502 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- scripts/mockgen.sh | 2 + x/auth/ante/ante_test.go | 1352 +++++++++++------ x/auth/ante/basic_test.go | 89 +- x/auth/ante/ext_test.go | 17 +- x/auth/ante/fee_test.go | 87 +- x/auth/ante/feegrant_test.go | 222 +-- x/auth/ante/setup_test.go | 33 +- x/auth/ante/sigverify_test.go | 101 +- .../ante/testutil/expected_keepers_mocks.go | 127 ++ x/auth/ante/testutil_test.go | 222 +-- x/auth/keeper/grpc_query_test.go | 10 +- x/auth/keeper/keeper_test.go | 52 +- x/auth/keeper/querier_test.go | 2 +- x/auth/signing/verify_test.go | 51 +- x/auth/testutil/expected_keepers_mocks.go | 63 + x/auth/vesting/types/vesting_account_test.go | 30 +- 16 files changed, 1530 insertions(+), 930 deletions(-) create mode 100644 x/auth/ante/testutil/expected_keepers_mocks.go create mode 100644 x/auth/testutil/expected_keepers_mocks.go diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index e544db7f4d..f2c03d0f7d 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -15,4 +15,6 @@ $mockgen_cmd -source=x/feegrant/expected_keepers.go -package testutil -destinati $mockgen_cmd -source=x/mint/types/expected_keepers.go -package testutil -destination x/mint/testutil/expected_keepers_mocks.go $mockgen_cmd -source=x/params/proposal_handler_test.go -package testutil -destination x/params/testutil/staking_keeper_mock.go $mockgen_cmd -source=x/crisis/types/expected_keepers.go -package testutil -destination x/crisis/testutil/expected_keepers_mocks.go +$mockgen_cmd -source=x/auth/types/expected_keepers.go -package testutil -destination x/auth/testutil/expected_keepers_mocks.go +$mockgen_cmd -source=x/auth/ante/expected_keepers.go -package testutil -destination x/auth/ante/testutil/expected_keepers_mocks.go $mockgen_cmd -source=x/bank/types/expected_keepers.go -package testutil -destination x/bank/testutil/expected_keepers_mocks.go \ No newline at end of file diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index ec52d572cb..397b1ae4ab 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -7,10 +7,7 @@ import ( "strings" "testing" - "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/x/bank/testutil" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -22,32 +19,38 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/ante" - "github.com/cosmos/cosmos-sdk/x/auth/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) // Test that simulate transaction accurately estimates gas cost -func (suite *AnteTestSuite) TestSimulateGasCost() { - suite.SetupTest(false) // reset +func TestSimulateGasCost(t *testing.T) { + // This test has a test case that uses another's output. + var simulatedGas uint64 - // Same data for every test cases - accounts := suite.CreateTestAccounts(3) - msgs := []sdk.Msg{ - testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()), - testdata.NewTestMsg(accounts[2].acc.GetAddress(), accounts[0].acc.GetAddress()), - testdata.NewTestMsg(accounts[1].acc.GetAddress(), accounts[2].acc.GetAddress()), - } + // Same data for every test case feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - accSeqs := []uint64{0, 0, 0} - privs := []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv, accounts[2].priv} - accNums := []uint64{0, 1, 2} testCases := []TestCase{ { "tx with 150atom fee", - func() { - suite.txBuilder.SetFeeAmount(feeAmount) - suite.txBuilder.SetGasLimit(gasLimit) + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, feeAmount).Return(nil) + + msgs := []sdk.Msg{ + testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()), + testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()), + testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[2].acc.GetAddress()), + } + + return TestCaseArgs{ + accNums: []uint64{0, 1, 2}, + accSeqs: []uint64{0, 0, 0}, + feeAmount: feeAmount, + gasLimit: testdata.NewTestGasLimit(), + msgs: msgs, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, + } }, true, true, @@ -55,12 +58,23 @@ func (suite *AnteTestSuite) TestSimulateGasCost() { }, { "with previously estimated gas", - func() { - simulatedGas := suite.ctx.GasMeter().GasConsumed() + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, feeAmount).Return(nil) - accSeqs = []uint64{1, 1, 1} - suite.txBuilder.SetFeeAmount(feeAmount) - suite.txBuilder.SetGasLimit(simulatedGas) + msgs := []sdk.Msg{ + testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()), + testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()), + testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[2].acc.GetAddress()), + } + + return TestCaseArgs{accNums: []uint64{0, 1, 2}, + accSeqs: []uint64{0, 0, 0}, + feeAmount: feeAmount, + gasLimit: simulatedGas, + msgs: msgs, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, + } }, false, true, @@ -69,20 +83,22 @@ func (suite *AnteTestSuite) TestSimulateGasCost() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.chainID = suite.ctx.ChainID() + suite.RunTestCase(t, tc, args) - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + // Gather info for the next test case + simulatedGas = suite.ctx.GasMeter().GasConsumed() }) } } // Test various error cases in the AnteHandler control flow. -func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { - suite.SetupTest(false) // reset - - // Same data for every test cases +func TestAnteHandlerSigErrors(t *testing.T) { + // This test requires the accounts to not be set, so we create them here priv0, _, addr0 := testdata.KeyTestPubAddr() priv1, _, addr1 := testdata.KeyTestPubAddr() priv2, _, addr2 := testdata.KeyTestPubAddr() @@ -90,29 +106,28 @@ func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { testdata.NewTestMsg(addr0, addr1), testdata.NewTestMsg(addr0, addr2), } - feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - - // Variable data per test case - var ( - privs []cryptotypes.PrivKey - accNums []uint64 - accSeqs []uint64 - ) testCases := []TestCase{ { "check no signatures fails", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{}, []uint64{}, []uint64{} + func(suite *AnteTestSuite) TestCaseArgs { + privs, accNums, accSeqs := []cryptotypes.PrivKey{}, []uint64{}, []uint64{} // Create tx manually to test the tx's signers - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) + // tx.GetSigners returns addresses in correct order: addr1, addr2, addr3 expectedSigners := []sdk.AccAddress{addr0, addr1, addr2} - suite.Require().Equal(expectedSigners, tx.GetSigners()) + require.Equal(t, expectedSigners, tx.GetSigners()) + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -120,8 +135,15 @@ func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { }, { "num sigs dont match GetSigners", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{priv0}, []uint64{0}, []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv0}, []uint64{0}, []uint64{0} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -129,8 +151,15 @@ func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { }, { "unrecognized account", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{priv0, priv1, priv2}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + func(suite *AnteTestSuite) TestCaseArgs { + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv0, priv1, priv2}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -138,55 +167,76 @@ func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { }, { "save the first account, but second is still unrecognized", - func() { - acc1 := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr0) - suite.accountKeeper.SetAccount(suite.ctx, acc1) - err := suite.bankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, feeAmount) - suite.Require().NoError(err) - err = suite.bankKeeper.SendCoinsFromModuleToAccount(suite.ctx, minttypes.ModuleName, addr0, feeAmount) - suite.Require().NoError(err) + func(suite *AnteTestSuite) TestCaseArgs { + suite.accountKeeper.SetAccount(suite.ctx, suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr0)) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv0, priv1, priv2}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, sdkerrors.ErrUnknownAddress, }, + { + "save all the accounts, should pass", + func(suite *AnteTestSuite) TestCaseArgs { + suite.accountKeeper.SetAccount(suite.ctx, suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr0)) + suite.accountKeeper.SetAccount(suite.ctx, suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr1)) + suite.accountKeeper.SetAccount(suite.ctx, suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr2)) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv0, priv1, priv2}, []uint64{1, 2, 3}, []uint64{0, 0, 0} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } + }, + false, + true, + nil, + }, } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.chainID = suite.ctx.ChainID() + args.feeAmount = testdata.NewTestFeeAmount() + args.gasLimit = testdata.NewTestGasLimit() - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } // Test logic around account number checking with one signer and many signers. -func (suite *AnteTestSuite) TestAnteHandlerAccountNumbers() { - suite.SetupTest(false) // reset - - // Same data for every test cases - accounts := suite.CreateTestAccounts(2) - feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - - // Variable data per test case - var ( - accNums []uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) - +func TestAnteHandlerAccountNumbers(t *testing.T) { testCases := []TestCase{ { "good tx from one signer", - func() { - msg := testdata.NewTestMsg(accounts[0].acc.GetAddress()) - msgs = []sdk.Msg{msg} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil) - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{msg}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, @@ -194,29 +244,36 @@ func (suite *AnteTestSuite) TestAnteHandlerAccountNumbers() { }, { "new tx from wrong account number", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{1}, []uint64{1} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{1}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{msg}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, sdkerrors.ErrUnauthorized, }, - { - "new tx from correct account number", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{1} - }, - false, - true, - nil, - }, { "new tx with another signer and incorrect account numbers", - func() { - msg1 := testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()) - msg2 := testdata.NewTestMsg(accounts[1].acc.GetAddress(), accounts[0].acc.GetAddress()) - msgs = []sdk.Msg{msg1, msg2} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv}, []uint64{1, 0}, []uint64{2, 0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{2, 0}, + accSeqs: []uint64{0, 0}, + msgs: []sdk.Msg{msg1, msg2}, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv}, + } }, false, false, @@ -224,8 +281,18 @@ func (suite *AnteTestSuite) TestAnteHandlerAccountNumbers() { }, { "new tx with correct account numbers", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv}, []uint64{0, 1}, []uint64{2, 0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0, 1}, + accSeqs: []uint64{0, 0}, + msgs: []sdk.Msg{msg1, msg2}, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv}, + } }, false, true, @@ -234,41 +301,34 @@ func (suite *AnteTestSuite) TestAnteHandlerAccountNumbers() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) + args := tc.malleate(suite) + args.feeAmount = testdata.NewTestFeeAmount() + args.gasLimit = testdata.NewTestGasLimit() + args.chainID = suite.ctx.ChainID() - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } // Test logic around account number checking with many signers when BlockHeight is 0. -func (suite *AnteTestSuite) TestAnteHandlerAccountNumbersAtBlockHeightZero() { - suite.SetupTest(false) // setup - suite.ctx = suite.ctx.WithBlockHeight(0) - - // Same data for every test cases - accounts := suite.CreateTestAccounts(2) - feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - - // Variable data per test case - var ( - accNums []uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) - +func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { testCases := []TestCase{ { "good tx from one signer", - func() { - msg := testdata.NewTestMsg(accounts[0].acc.GetAddress()) - msgs = []sdk.Msg{msg} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{msg}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, @@ -276,30 +336,37 @@ func (suite *AnteTestSuite) TestAnteHandlerAccountNumbersAtBlockHeightZero() { }, { "new tx from wrong account number", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{1}, []uint64{1} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{1}, // wrong account number + accSeqs: []uint64{0}, + msgs: []sdk.Msg{msg}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, sdkerrors.ErrUnauthorized, }, - { - "new tx from correct account number", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{1} - }, - false, - true, - nil, - }, { "new tx with another signer and incorrect account numbers", - func() { - msg1 := testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()) - msg2 := testdata.NewTestMsg(accounts[1].acc.GetAddress(), accounts[0].acc.GetAddress()) - msgs = []sdk.Msg{msg1, msg2} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[0].acc.GetAddress()) - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv}, []uint64{1, 0}, []uint64{2, 0} + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{1, 0}, // wrong account numbers + accSeqs: []uint64{0, 0}, + msgs: []sdk.Msg{msg1, msg2}, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv}, + } }, false, false, @@ -307,9 +374,19 @@ func (suite *AnteTestSuite) TestAnteHandlerAccountNumbersAtBlockHeightZero() { }, { "new tx with another signer and correct account numbers", - func() { - // Note that accNums is [0,0] at block 0. - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv}, []uint64{0, 0}, []uint64{2, 0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[0].acc.GetAddress()) + + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0, 0}, // correct account numbers + accSeqs: []uint64{0, 0}, + msgs: []sdk.Msg{msg1, msg2}, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv}, + } }, false, true, @@ -318,40 +395,40 @@ func (suite *AnteTestSuite) TestAnteHandlerAccountNumbersAtBlockHeightZero() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) + suite.ctx = suite.ctx.WithBlockHeight(0) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + args := tc.malleate(suite) + args.feeAmount = testdata.NewTestFeeAmount() + args.gasLimit = testdata.NewTestGasLimit() + + suite.RunTestCase(t, tc, args) }) } } // Test logic around sequence checking with one signer and many signers. -func (suite *AnteTestSuite) TestAnteHandlerSequences() { - suite.SetupTest(false) // setup - +func TestAnteHandlerSequences(t *testing.T) { // Same data for every test cases - accounts := suite.CreateTestAccounts(3) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - // Variable data per test case - var ( - accNums []uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) - testCases := []TestCase{ { "good tx from one signer", - func() { - msg := testdata.NewTestMsg(accounts[0].acc.GetAddress()) - msgs = []sdk.Msg{msg} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{msg}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, @@ -359,8 +436,26 @@ func (suite *AnteTestSuite) TestAnteHandlerSequences() { }, { "test sending it again fails (replay protection)", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + msgs := []sdk.Msg{msg} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} + + // This will be called only once given that the second tx will fail + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + // Send the same tx before running the test case, to trigger replay protection. + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -368,8 +463,28 @@ func (suite *AnteTestSuite) TestAnteHandlerSequences() { }, { "fix sequence, should pass", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{1} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + msgs := []sdk.Msg{msg} + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + // Send the same tx before running the test case, then change the sequence to a valid one. + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + // +1 the account sequence + accSeqs = []uint64{1} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, true, @@ -377,12 +492,19 @@ func (suite *AnteTestSuite) TestAnteHandlerSequences() { }, { "new tx with another signer and correct sequences", - func() { - msg1 := testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()) - msg2 := testdata.NewTestMsg(accounts[2].acc.GetAddress(), accounts[0].acc.GetAddress()) - msgs = []sdk.Msg{msg1, msg2} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv, accounts[2].priv}, []uint64{0, 1, 2}, []uint64{2, 0, 0} + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0, 1, 2}, + accSeqs: []uint64{0, 0, 0}, + msgs: []sdk.Msg{msg1, msg2}, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, + } }, false, true, @@ -390,17 +512,59 @@ func (suite *AnteTestSuite) TestAnteHandlerSequences() { }, { "replay fails", - func() {}, + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msgs := []sdk.Msg{msg1, msg2} + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + // Send the same tx before running the test case, to trigger replay protection. + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: []sdk.Msg{msg1, msg2}, + privs: privs, + } + }, false, false, sdkerrors.ErrWrongSequence, }, { "tx from just second signer with incorrect sequence fails", - func() { - msg := testdata.NewTestMsg(accounts[1].acc.GetAddress()) - msgs = []sdk.Msg{msg} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[1].priv}, []uint64{1}, []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msgs := []sdk.Msg{msg1, msg2} + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + // Send the same tx before running the test case, to trigger replay protection. + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + // Send a message using the second signer, this will fail given that the second signer already sent a TX, + // thus the sequence (0) is incorrect. + msg1 = testdata.NewTestMsg(accs[1].acc.GetAddress()) + msgs = []sdk.Msg{msg1} + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[1].priv}, []uint64{1}, []uint64{0} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -408,20 +572,32 @@ func (suite *AnteTestSuite) TestAnteHandlerSequences() { }, { "fix the sequence and it passes", - func() { - accSeqs = []uint64{1} - }, - false, - true, - nil, - }, - { - "fix the sequence and it passes", - func() { - msg := testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()) - msgs = []sdk.Msg{msg} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msgs := []sdk.Msg{msg1, msg2} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv}, []uint64{0, 1}, []uint64{3, 2} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + // Send the same tx before running the test case, to trigger replay protection. + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + // Send a message using the second signer, this will now pass given that the second signer already sent a TX + // and the sequence was fixed (1). + msg1 = testdata.NewTestMsg(accs[1].acc.GetAddress()) + msgs = []sdk.Msg{msg1} + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[1].priv}, []uint64{1}, []uint64{1} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, true, @@ -430,117 +606,89 @@ func (suite *AnteTestSuite) TestAnteHandlerSequences() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.feeAmount = feeAmount + args.gasLimit = gasLimit - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } // Test logic around fee deduction. -func (suite *AnteTestSuite) TestAnteHandlerFees() { - suite.SetupTest(false) // setup - +func TestAnteHandlerFees(t *testing.T) { // Same data for every test cases - priv0, _, addr0 := testdata.KeyTestPubAddr() - - acc1 := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr0) - suite.accountKeeper.SetAccount(suite.ctx, acc1) - msgs := []sdk.Msg{testdata.NewTestMsg(addr0)} feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - privs, accNums, accSeqs := []cryptotypes.PrivKey{priv0}, []uint64{0}, []uint64{0} - testCases := []struct { - desc string - malleate func() - simulate bool - expPass bool - expErr error - }{ + testCases := []TestCase{ { "signer has no funds", - func() { - accSeqs = []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), feeAmount).Return(sdkerrors.ErrInsufficientFunds) + + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, sdkerrors.ErrInsufficientFunds, }, { - "signer does not have enough funds to pay the fee", - func() { - err := testutil.FundAccount(suite.bankKeeper, suite.ctx, addr0, sdk.NewCoins(sdk.NewInt64Coin("atom", 149))) - suite.Require().NoError(err) - }, - false, - false, - sdkerrors.ErrInsufficientFunds, - }, - { - "signer as enough funds, should pass", - func() { - accNums = []uint64{acc1.GetAccountNumber()} + "signer has enough funds, should pass", + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), gomock.Any(), feeAmount).Return(nil) - modAcc := suite.accountKeeper.GetModuleAccount(suite.ctx, types.FeeCollectorName) - - suite.Require().True(suite.bankKeeper.GetAllBalances(suite.ctx, modAcc.GetAddress()).Empty()) - require.True(math.IntEq(suite.T(), suite.bankKeeper.GetAllBalances(suite.ctx, addr0).AmountOf("atom"), sdk.NewInt(149))) - - err := testutil.FundAccount(suite.bankKeeper, suite.ctx, addr0, sdk.NewCoins(sdk.NewInt64Coin("atom", 1))) - suite.Require().NoError(err) + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, nil, }, - { - "signer doesn't have any more funds", - func() { - modAcc := suite.accountKeeper.GetModuleAccount(suite.ctx, types.FeeCollectorName) - - require.True(math.IntEq(suite.T(), suite.bankKeeper.GetAllBalances(suite.ctx, modAcc.GetAddress()).AmountOf("atom"), sdk.NewInt(150))) - require.True(math.IntEq(suite.T(), suite.bankKeeper.GetAllBalances(suite.ctx, addr0).AmountOf("atom"), sdk.NewInt(0))) - }, - false, - false, - sdkerrors.ErrInsufficientFunds, - }, } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.feeAmount = feeAmount + args.gasLimit = gasLimit - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } // Test logic around memo gas consumption. -func (suite *AnteTestSuite) TestAnteHandlerMemoGas() { - suite.SetupTest(false) // setup - - // Same data for every test cases - accounts := suite.CreateTestAccounts(1) - msgs := []sdk.Msg{testdata.NewTestMsg(accounts[0].acc.GetAddress())} - privs, accNums, accSeqs := []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} - - // Variable data per test case - var ( - feeAmount sdk.Coins - gasLimit uint64 - ) - +func TestAnteHandlerMemoGas(t *testing.T) { testCases := []TestCase{ { "tx does not have enough gas", - func() { - feeAmount = sdk.NewCoins(sdk.NewInt64Coin("atom", 0)) - gasLimit = 0 + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: sdk.NewCoins(sdk.NewInt64Coin("atom", 0)), + gasLimit: 0, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -548,10 +696,18 @@ func (suite *AnteTestSuite) TestAnteHandlerMemoGas() { }, { "tx with memo doesn't have enough gas", - func() { - feeAmount = sdk.NewCoins(sdk.NewInt64Coin("atom", 0)) - gasLimit = 801 + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) suite.txBuilder.SetMemo("abcininasidniandsinasindiansdiansdinaisndiasndiadninsd") + + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: sdk.NewCoins(sdk.NewInt64Coin("atom", 0)), + gasLimit: 801, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -559,10 +715,18 @@ func (suite *AnteTestSuite) TestAnteHandlerMemoGas() { }, { "memo too large", - func() { - feeAmount = sdk.NewCoins(sdk.NewInt64Coin("atom", 0)) - gasLimit = 50000 + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) suite.txBuilder.SetMemo(strings.Repeat("01234567890", 500)) + + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: sdk.NewCoins(sdk.NewInt64Coin("atom", 0)), + gasLimit: 50000, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -570,10 +734,17 @@ func (suite *AnteTestSuite) TestAnteHandlerMemoGas() { }, { "tx with memo has enough gas", - func() { - feeAmount = sdk.NewCoins(sdk.NewInt64Coin("atom", 0)) - gasLimit = 60000 + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) suite.txBuilder.SetMemo(strings.Repeat("0123456789", 10)) + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: sdk.NewCoins(sdk.NewInt64Coin("atom", 0)), + gasLimit: 60000, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, @@ -582,41 +753,37 @@ func (suite *AnteTestSuite) TestAnteHandlerMemoGas() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } -func (suite *AnteTestSuite) TestAnteHandlerMultiSigner() { - suite.SetupTest(false) // setup - - // Same data for every test cases - accounts := suite.CreateTestAccounts(3) - msg1 := testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()) - msg2 := testdata.NewTestMsg(accounts[2].acc.GetAddress(), accounts[0].acc.GetAddress()) - msg3 := testdata.NewTestMsg(accounts[1].acc.GetAddress(), accounts[2].acc.GetAddress()) +func TestAnteHandlerMultiSigner(t *testing.T) { feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - // Variable data per test case - var ( - accNums []uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) - testCases := []TestCase{ { "signers in order", - func() { - msgs = []sdk.Msg{msg1, msg2, msg3} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv, accounts[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msg3 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[2].acc.GetAddress()) suite.txBuilder.SetMemo("Check signers are in expected order and different account numbers works") + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0, 1, 2}, + accSeqs: []uint64{0, 0, 0}, + msgs: []sdk.Msg{msg1, msg2, msg3}, + privs: []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, + } }, false, true, @@ -624,9 +791,29 @@ func (suite *AnteTestSuite) TestAnteHandlerMultiSigner() { }, { "change sequence numbers (only accounts 0 and 1 sign)", - func() { + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msg3 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[2].acc.GetAddress()) + msgs := []sdk.Msg{msg1, msg2, msg3} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + msgs = []sdk.Msg{msg1} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv}, []uint64{0, 1}, []uint64{1, 1} + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[0].priv, accs[1].priv}, []uint64{0, 1}, []uint64{1, 1} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, true, @@ -634,9 +821,28 @@ func (suite *AnteTestSuite) TestAnteHandlerMultiSigner() { }, { "change sequence numbers (only accounts 1 and 2 sign)", - func() { - msgs = []sdk.Msg{msg2} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[2].priv, accounts[0].priv}, []uint64{2, 0}, []uint64{1, 2} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msg3 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[2].acc.GetAddress()) + msgs := []sdk.Msg{msg1, msg2, msg3} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + msgs = []sdk.Msg{msg3} + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[1].priv, accs[2].priv}, []uint64{1, 2}, []uint64{1, 1} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, true, @@ -644,9 +850,27 @@ func (suite *AnteTestSuite) TestAnteHandlerMultiSigner() { }, { "everyone signs again", - func() { - msgs = []sdk.Msg{msg1, msg2, msg3} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv, accounts[1].priv, accounts[2].priv}, []uint64{0, 1, 2}, []uint64{3, 2, 2} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(3) + msg1 := testdata.NewTestMsg(accs[0].acc.GetAddress(), accs[1].acc.GetAddress()) + msg2 := testdata.NewTestMsg(accs[2].acc.GetAddress(), accs[0].acc.GetAddress()) + msg3 := testdata.NewTestMsg(accs[1].acc.GetAddress(), accs[2].acc.GetAddress()) + msgs := []sdk.Msg{msg1, msg2, msg3} + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{0, 0, 0} + + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[0].priv, accs[1].priv, accs[2].priv}, []uint64{0, 1, 2}, []uint64{1, 1, 1} + + return TestCaseArgs{accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, true, @@ -655,42 +879,40 @@ func (suite *AnteTestSuite) TestAnteHandlerMultiSigner() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.feeAmount = feeAmount + args.gasLimit = gasLimit + args.chainID = suite.ctx.ChainID() - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } -func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { - suite.SetupTest(false) // setup - - // Same data for every test cases - accounts := suite.CreateTestAccounts(2) - msg0 := testdata.NewTestMsg(accounts[0].acc.GetAddress()) - - // Variable data per test case - var ( - accNums []uint64 - chainID string - feeAmount sdk.Coins - gasLimit uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) +func TestAnteHandlerBadSignBytes(t *testing.T) { + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() testCases := []TestCase{ { "test good tx and signBytes", - func() { - chainID = suite.ctx.ChainID() - feeAmount = testdata.NewTestFeeAmount() - gasLimit = testdata.NewTestGasLimit() - msgs = []sdk.Msg{msg0} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg0 := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: suite.ctx.ChainID(), + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{msg0}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, @@ -698,9 +920,20 @@ func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { }, { "test wrong chainID", - func() { - accSeqs = []uint64{1} // Back to correct accSeqs - chainID = "chain-foo" + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg0 := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: "wrong-chain-id", + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{msg0}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -708,9 +941,20 @@ func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { }, { "test wrong accSeqs", - func() { - chainID = suite.ctx.ChainID() // Back to correct chainID - accSeqs = []uint64{2} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg0 := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: suite.ctx.ChainID(), + accNums: []uint64{0}, + accSeqs: []uint64{2}, //wrong accSeq + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{msg0}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -718,9 +962,20 @@ func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { }, { "test wrong accNums", - func() { - accSeqs = []uint64{1} // Back to correct accSeqs - accNums = []uint64{1} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + msg0 := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: suite.ctx.ChainID(), + accNums: []uint64{1}, // wrong accNum + accSeqs: []uint64{0}, + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{msg0}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -728,41 +983,41 @@ func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { }, { "test wrong msg", - func() { - msgs = []sdk.Msg{testdata.NewTestMsg(accounts[1].acc.GetAddress())} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: suite.ctx.ChainID(), + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[1].acc.GetAddress())}, // wrong account in the msg + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, sdkerrors.ErrInvalidPubKey, }, - { - "test wrong fee gas", - func() { - msgs = []sdk.Msg{msg0} // Back to correct msgs - feeAmount = testdata.NewTestFeeAmount() - gasLimit = testdata.NewTestGasLimit() + 100 - }, - false, - false, - sdkerrors.ErrUnauthorized, - }, - { - "test wrong fee amount", - func() { - feeAmount = testdata.NewTestFeeAmount() - feeAmount[0].Amount = feeAmount[0].Amount.AddRaw(100) - gasLimit = testdata.NewTestGasLimit() - }, - false, - false, - sdkerrors.ErrUnauthorized, - }, { "test wrong signer if public key exist", - func() { - feeAmount = testdata.NewTestFeeAmount() - gasLimit = testdata.NewTestGasLimit() - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[1].priv}, []uint64{0}, []uint64{1} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + msg0 := testdata.NewTestMsg(accs[0].acc.GetAddress()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: suite.ctx.ChainID(), + accNums: []uint64{0}, + accSeqs: []uint64{0}, + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{msg0}, + privs: []cryptotypes.PrivKey{accs[1].priv}, + } + }, false, false, @@ -770,9 +1025,19 @@ func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { }, { "test wrong signer if public doesn't exist", - func() { - msgs = []sdk.Msg{testdata.NewTestMsg(accounts[1].acc.GetAddress())} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{1}, []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + chainID: suite.ctx.ChainID(), + accNums: []uint64{1}, + accSeqs: []uint64{0}, + feeAmount: feeAmount, + gasLimit: gasLimit, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[1].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -781,37 +1046,33 @@ func (suite *AnteTestSuite) TestAnteHandlerBadSignBytes() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, chainID, tc) + suite.RunTestCase(t, tc, args) }) } } -func (suite *AnteTestSuite) TestAnteHandlerSetPubKey() { - suite.SetupTest(false) // setup - - // Same data for every test cases - accounts := suite.CreateTestAccounts(2) +func TestAnteHandlerSetPubKey(t *testing.T) { feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - // Variable data per test case - var ( - accNums []uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) - testCases := []TestCase{ { "test good tx", - func() { - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} - msgs = []sdk.Msg{testdata.NewTestMsg(accounts[0].acc.GetAddress())} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, true, @@ -819,10 +1080,26 @@ func (suite *AnteTestSuite) TestAnteHandlerSetPubKey() { }, { "make sure public key has been set (tx itself should fail because of replay protection)", - func() { + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(1) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} + msgs := []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())} + var err error + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + // Make sure public key has been set from previous test. - acc0 := suite.accountKeeper.GetAccount(suite.ctx, accounts[0].acc.GetAddress()) - suite.Require().Equal(acc0.GetPubKey(), accounts[0].priv.PubKey()) + acc0 := suite.accountKeeper.GetAccount(suite.ctx, accs[0].acc.GetAddress()) + require.Equal(t, acc0.GetPubKey(), accs[0].priv.PubKey()) + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -830,9 +1107,15 @@ func (suite *AnteTestSuite) TestAnteHandlerSetPubKey() { }, { "test public key not found", - func() { - // See above, `privs` still holds the private key of accounts[0]. - msgs = []sdk.Msg{testdata.NewTestMsg(accounts[1].acc.GetAddress())} + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[1].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, // wrong signer + } }, false, false, @@ -840,35 +1123,45 @@ func (suite *AnteTestSuite) TestAnteHandlerSetPubKey() { }, { "make sure public key is not set, when tx has no pubkey or signature", - func() { - // Make sure public key has not been set from previous test. - acc1 := suite.accountKeeper.GetAccount(suite.ctx, accounts[1].acc.GetAddress()) - suite.Require().Nil(acc1.GetPubKey()) + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[1].priv}, []uint64{1}, []uint64{0} - msgs = []sdk.Msg{testdata.NewTestMsg(accounts[1].acc.GetAddress())} + // Make sure public key has not been set from previous test. + acc1 := suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress()) + require.Nil(t, acc1.GetPubKey()) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[1].priv}, []uint64{1}, []uint64{0} + msgs := []sdk.Msg{testdata.NewTestMsg(accs[1].acc.GetAddress())} suite.txBuilder.SetMsgs(msgs...) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) // Manually create tx, and remove signature. tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx) - suite.Require().NoError(err) - suite.Require().NoError(txBuilder.SetSignatures()) + require.NoError(t, err) + require.NoError(t, txBuilder.SetSignatures()) // Run anteHandler manually, expect ErrNoSignatures. _, err = suite.anteHandler(suite.ctx, txBuilder.GetTx(), false) - suite.Require().Error(err) - suite.Require().True(errors.Is(err, sdkerrors.ErrNoSignatures)) + require.Error(t, err) + require.True(t, errors.Is(err, sdkerrors.ErrNoSignatures)) // Make sure public key has not been set. - acc1 = suite.accountKeeper.GetAccount(suite.ctx, accounts[1].acc.GetAddress()) - suite.Require().Nil(acc1.GetPubKey()) + acc1 = suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress()) + require.Nil(t, acc1.GetPubKey()) // Set incorrect accSeq, to generate incorrect signature. - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[1].priv}, []uint64{1}, []uint64{1} + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[1].priv}, []uint64{1}, []uint64{1} + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -876,11 +1169,54 @@ func (suite *AnteTestSuite) TestAnteHandlerSetPubKey() { }, { "make sure previous public key has been set after wrong signature", - func() { + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + // Make sure public key has not been set from previous test. + acc1 := suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress()) + require.Nil(t, acc1.GetPubKey()) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[1].priv}, []uint64{1}, []uint64{0} + msgs := []sdk.Msg{testdata.NewTestMsg(accs[1].acc.GetAddress())} + suite.txBuilder.SetMsgs(msgs...) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + // Manually create tx, and remove signature. + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + require.NoError(t, err) + txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx) + require.NoError(t, err) + require.NoError(t, txBuilder.SetSignatures()) + + // Run anteHandler manually, expect ErrNoSignatures. + _, err = suite.anteHandler(suite.ctx, txBuilder.GetTx(), false) + require.Error(t, err) + require.True(t, errors.Is(err, sdkerrors.ErrNoSignatures)) + + // Make sure public key has not been set. + acc1 = suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress()) + require.Nil(t, acc1.GetPubKey()) + + // Set incorrect accSeq, to generate incorrect signature. + privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[1].priv}, []uint64{1}, []uint64{1} + + suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false) + require.Error(t, err) + // Make sure public key has been set, as SetPubKeyDecorator // is called before all signature verification decorators. - acc1 := suite.accountKeeper.GetAccount(suite.ctx, accounts[1].acc.GetAddress()) - suite.Require().Equal(acc1.GetPubKey(), accounts[1].priv.PubKey()) + acc1 = suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress()) + require.Equal(t, acc1.GetPubKey(), accs[1].priv.PubKey()) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: accNums, + accSeqs: accSeqs, + msgs: msgs, + privs: privs, + } }, false, false, @@ -889,11 +1225,15 @@ func (suite *AnteTestSuite) TestAnteHandlerSetPubKey() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.chainID = suite.ctx.ChainID() + args.feeAmount = feeAmount + args.gasLimit = gasLimit - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } @@ -925,9 +1265,9 @@ func expectedGasCostByKeys(pubkeys []cryptotypes.PubKey) uint64 { pubkeyType := strings.ToLower(fmt.Sprintf("%T", pubkey)) switch { case strings.Contains(pubkeyType, "ed25519"): - cost += types.DefaultParams().SigVerifyCostED25519 + cost += authtypes.DefaultParams().SigVerifyCostED25519 case strings.Contains(pubkeyType, "secp256k1"): - cost += types.DefaultParams().SigVerifyCostSecp256k1 + cost += authtypes.DefaultParams().SigVerifyCostSecp256k1 default: panic("unexpected key type") } @@ -969,26 +1309,30 @@ func TestCountSubkeys(t *testing.T) { } } -func (suite *AnteTestSuite) TestAnteHandlerSigLimitExceeded() { - suite.SetupTest(false) // setup - - // Same data for every test cases - accounts := suite.CreateTestAccounts(8) - var addrs []sdk.AccAddress - var privs []cryptotypes.PrivKey - for i := 0; i < 8; i++ { - addrs = append(addrs, accounts[i].acc.GetAddress()) - privs = append(privs, accounts[i].priv) - } - msgs := []sdk.Msg{testdata.NewTestMsg(addrs...)} - accNums, accSeqs := []uint64{0, 1, 2, 3, 4, 5, 6, 7}, []uint64{0, 0, 0, 0, 0, 0, 0, 0} - feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - +func TestAnteHandlerSigLimitExceeded(t *testing.T) { testCases := []TestCase{ { "test rejection logic", - func() {}, + func(suite *AnteTestSuite) TestCaseArgs { + accs := suite.CreateTestAccounts(8) + var ( + addrs []sdk.AccAddress + privs []cryptotypes.PrivKey + ) + for i := 0; i < 8; i++ { + addrs = append(addrs, accs[i].acc.GetAddress()) + privs = append(privs, accs[i].priv) + } + + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0, 1, 2, 3, 4, 5, 6, 7}, + accSeqs: []uint64{0, 0, 0, 0, 0, 0, 0, 0}, + msgs: []sdk.Msg{testdata.NewTestMsg(addrs...)}, + privs: privs, + } + }, false, false, sdkerrors.ErrTooManySignatures, @@ -996,60 +1340,55 @@ func (suite *AnteTestSuite) TestAnteHandlerSigLimitExceeded() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.chainID = suite.ctx.ChainID() + args.feeAmount = testdata.NewTestFeeAmount() + args.gasLimit = testdata.NewTestGasLimit() - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } // Test custom SignatureVerificationGasConsumer -func (suite *AnteTestSuite) TestCustomSignatureVerificationGasConsumer() { - suite.SetupTest(false) // setup - - // setup an ante handler that only accepts PubKeyEd25519 - anteHandler, err := ante.NewAnteHandler( - ante.HandlerOptions{ - AccountKeeper: suite.accountKeeper, - BankKeeper: suite.bankKeeper, - FeegrantKeeper: suite.feeGrantKeeper, - SignModeHandler: suite.clientCtx.TxConfig.SignModeHandler(), - SigGasConsumer: func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error { - switch pubkey := sig.PubKey.(type) { - case *ed25519.PubKey: - meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") - return nil - default: - return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "unrecognized public key type: %T", pubkey) - } - }, - }, - ) - - suite.Require().NoError(err) - suite.anteHandler = anteHandler - - // Same data for every test cases - accounts := suite.CreateTestAccounts(1) - feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - - // Variable data per test case - var ( - accNums []uint64 - msgs []sdk.Msg - privs []cryptotypes.PrivKey - accSeqs []uint64 - ) - +func TestCustomSignatureVerificationGasConsumer(t *testing.T) { testCases := []TestCase{ { "verify that an secp256k1 account gets rejected", - func() { - msgs = []sdk.Msg{testdata.NewTestMsg(accounts[0].acc.GetAddress())} - privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + func(suite *AnteTestSuite) TestCaseArgs { + // setup an ante handler that only accepts PubKeyEd25519 + anteHandler, err := ante.NewAnteHandler( + ante.HandlerOptions{ + AccountKeeper: suite.accountKeeper, + BankKeeper: suite.bankKeeper, + FeegrantKeeper: suite.feeGrantKeeper, + SignModeHandler: suite.clientCtx.TxConfig.SignModeHandler(), + SigGasConsumer: func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error { + switch pubkey := sig.PubKey.(type) { + case *ed25519.PubKey: + meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") + return nil + default: + return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "unrecognized public key type: %T", pubkey) + } + }, + }, + ) + require.NoError(t, err) + suite.anteHandler = anteHandler + + accs := suite.CreateTestAccounts(1) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + return TestCaseArgs{ + accNums: []uint64{0}, + accSeqs: []uint64{0}, + msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].acc.GetAddress())}, + privs: []cryptotypes.PrivKey{accs[0].priv}, + } }, false, false, @@ -1058,77 +1397,85 @@ func (suite *AnteTestSuite) TestCustomSignatureVerificationGasConsumer() { } for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + t.Run(fmt.Sprintf("Case %s", tc.desc), func(t *testing.T) { + suite := SetupTestSuite(t, false) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - tc.malleate() + args := tc.malleate(suite) + args.chainID = suite.ctx.ChainID() + args.feeAmount = testdata.NewTestFeeAmount() + args.gasLimit = testdata.NewTestGasLimit() - suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + suite.RunTestCase(t, tc, args) }) } } -func (suite *AnteTestSuite) TestAnteHandlerReCheck() { - suite.SetupTest(false) // setup +func TestAnteHandlerReCheck(t *testing.T) { + suite := SetupTestSuite(t, false) // Set recheck=true suite.ctx = suite.ctx.WithIsReCheckTx(true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - // Same data for every test cases - accounts := suite.CreateTestAccounts(1) + // Same data for every test case + accs := suite.CreateTestAccounts(1) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) - msg := testdata.NewTestMsg(accounts[0].acc.GetAddress()) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) msgs := []sdk.Msg{msg} - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) suite.txBuilder.SetMemo("thisisatestmemo") // test that operations skipped on recheck do not run - privs, accNums, accSeqs := []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) // make signature array empty which would normally cause ValidateBasicDecorator and SigVerificationDecorator fail // since these decorators don't run on recheck, the tx should pass the antehandler txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx) - suite.Require().NoError(err) + require.NoError(t, err) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) _, err = suite.anteHandler(suite.ctx, txBuilder.GetTx(), false) - suite.Require().Nil(err, "AnteHandler errored on recheck unexpectedly: %v", err) + require.Nil(t, err, "AnteHandler errored on recheck unexpectedly: %v", err) tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) txBytes, err := json.Marshal(tx) - suite.Require().Nil(err, "Error marshalling tx: %v", err) + require.Nil(t, err, "Error marshalling tx: %v", err) suite.ctx = suite.ctx.WithTxBytes(txBytes) // require that state machine param-dependent checking is still run on recheck since parameters can change between check and recheck testCases := []struct { name string - params types.Params + params authtypes.Params }{ - {"memo size check", types.NewParams(1, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1)}, - {"txsize check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 10000000, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1)}, - {"sig verify cost check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, 100000000)}, + {"memo size check", authtypes.NewParams(1, authtypes.DefaultTxSigLimit, authtypes.DefaultTxSizeCostPerByte, authtypes.DefaultSigVerifyCostED25519, authtypes.DefaultSigVerifyCostSecp256k1)}, + {"txsize check", authtypes.NewParams(authtypes.DefaultMaxMemoCharacters, authtypes.DefaultTxSigLimit, 10000000, authtypes.DefaultSigVerifyCostED25519, authtypes.DefaultSigVerifyCostSecp256k1)}, + {"sig verify cost check", authtypes.NewParams(authtypes.DefaultMaxMemoCharacters, authtypes.DefaultTxSigLimit, authtypes.DefaultTxSizeCostPerByte, authtypes.DefaultSigVerifyCostED25519, 100000000)}, } + for _, tc := range testCases { + // set testcase parameters err := suite.accountKeeper.SetParams(suite.ctx, tc.params) - suite.Require().NoError(err) + require.NoError(t, err) _, err = suite.anteHandler(suite.ctx, tx, false) - suite.Require().NotNil(err, "tx does not fail on recheck with updated params in test case: %s", tc.name) + require.NotNil(t, err, "tx does not fail on recheck with updated params in test case: %s", tc.name) // reset parameters to default values - err = suite.accountKeeper.SetParams(suite.ctx, types.DefaultParams()) - suite.Require().NoError(err) + err = suite.accountKeeper.SetParams(suite.ctx, authtypes.DefaultParams()) + require.NoError(t, err) } + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(sdkerrors.ErrInsufficientFee) // require that local mempool fee check is still run on recheck since validator may change minFee between check and recheck // create new minimum gas price so antehandler fails on recheck suite.ctx = suite.ctx.WithMinGasPrices([]sdk.DecCoin{{ @@ -1136,16 +1483,13 @@ func (suite *AnteTestSuite) TestAnteHandlerReCheck() { Amount: sdk.NewDec(5), }}) _, err = suite.anteHandler(suite.ctx, tx, false) - suite.Require().NotNil(err, "antehandler on recheck did not fail when mingasPrice was changed") + require.NotNil(t, err, "antehandler on recheck did not fail when mingasPrice was changed") // reset min gasprice suite.ctx = suite.ctx.WithMinGasPrices(sdk.DecCoins{}) // remove funds for account so antehandler fails on recheck - suite.accountKeeper.SetAccount(suite.ctx, accounts[0].acc) - balances := suite.bankKeeper.GetAllBalances(suite.ctx, accounts[0].acc.GetAddress()) - err = suite.bankKeeper.SendCoinsFromAccountToModule(suite.ctx, accounts[0].acc.GetAddress(), minttypes.ModuleName, balances) - suite.Require().NoError(err) + suite.accountKeeper.SetAccount(suite.ctx, accs[0].acc) _, err = suite.anteHandler(suite.ctx, tx, false) - suite.Require().NotNil(err, "antehandler on recheck did not fail once feePayer no longer has sufficient funds") + require.NotNil(t, err, "antehandler on recheck did not fail once feePayer no longer has sufficient funds") } diff --git a/x/auth/ante/basic_test.go b/x/auth/ante/basic_test.go index 11e57f1ebd..8bf7b7abbb 100644 --- a/x/auth/ante/basic_test.go +++ b/x/auth/ante/basic_test.go @@ -2,17 +2,20 @@ package ante_test import ( "strings" + "testing" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" "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/cosmos/cosmos-sdk/x/auth/ante" + "github.com/stretchr/testify/require" ) -func (suite *AnteTestSuite) TestValidateBasic() { - suite.SetupTest(true) // setup +func TestValidateBasic(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // keys and addresses @@ -22,26 +25,26 @@ func (suite *AnteTestSuite) TestValidateBasic() { msg := testdata.NewTestMsg(addr1) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + require.NoError(t, suite.txBuilder.SetMsgs(msg)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) privs, accNums, accSeqs := []cryptotypes.PrivKey{}, []uint64{}, []uint64{} invalidTx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) vbd := ante.NewValidateBasicDecorator() antehandler := sdk.ChainAnteDecorators(vbd) _, err = antehandler(suite.ctx, invalidTx, false) - suite.Require().NotNil(err, "Did not error on invalid tx") + require.ErrorIs(t, err, sdkerrors.ErrNoSignatures, "Did not error on invalid tx") privs, accNums, accSeqs = []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} validTx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) _, err = antehandler(suite.ctx, validTx, false) - suite.Require().Nil(err, "ValidateBasicDecorator returned error on valid tx. err: %v", err) + require.Nil(t, err, "ValidateBasicDecorator returned error on valid tx. err: %v", err) // test decorator skips on recheck suite.ctx = suite.ctx.WithIsReCheckTx(true) @@ -49,11 +52,11 @@ func (suite *AnteTestSuite) TestValidateBasic() { // decorator should skip processing invalidTx on recheck and thus return nil-error _, err = antehandler(suite.ctx, invalidTx, false) - suite.Require().Nil(err, "ValidateBasicDecorator ran on ReCheck") + require.Nil(t, err, "ValidateBasicDecorator ran on ReCheck") } -func (suite *AnteTestSuite) TestValidateMemo() { - suite.SetupTest(true) // setup +func TestValidateMemo(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // keys and addresses @@ -63,33 +66,33 @@ func (suite *AnteTestSuite) TestValidateMemo() { msg := testdata.NewTestMsg(addr1) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + require.NoError(t, suite.txBuilder.SetMsgs(msg)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} suite.txBuilder.SetMemo(strings.Repeat("01234567890", 500)) invalidTx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) // require that long memos get rejected vmd := ante.NewValidateMemoDecorator(suite.accountKeeper) antehandler := sdk.ChainAnteDecorators(vmd) _, err = antehandler(suite.ctx, invalidTx, false) - suite.Require().NotNil(err, "Did not error on tx with high memo") + require.ErrorIs(t, err, sdkerrors.ErrMemoTooLarge, "Did not error on tx with high memo") suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10)) validTx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) // require small memos pass ValidateMemo Decorator _, err = antehandler(suite.ctx, validTx, false) - suite.Require().Nil(err, "ValidateBasicDecorator returned error on valid tx. err: %v", err) + require.Nil(t, err, "ValidateBasicDecorator returned error on valid tx. err: %v", err) } -func (suite *AnteTestSuite) TestConsumeGasForTxSize() { - suite.SetupTest(true) // setup +func TestConsumeGasForTxSize(t *testing.T) { + suite := SetupTestSuite(t, true) // keys and addresses priv1, _, addr1 := testdata.KeyTestPubAddr() @@ -111,19 +114,19 @@ func (suite *AnteTestSuite) TestConsumeGasForTxSize() { } for _, tc := range testCases { - suite.Run(tc.name, func() { + t.Run(tc.name, func(t *testing.T) { suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + require.NoError(t, suite.txBuilder.SetMsgs(msg)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10)) privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) txBytes, err := suite.clientCtx.TxConfig.TxJSONEncoder()(tx) - suite.Require().Nil(err, "Cannot marshal tx: %v", err) + require.Nil(t, err, "Cannot marshal tx: %v", err) params := suite.accountKeeper.GetParams(suite.ctx) expectedGas := sdk.Gas(len(txBytes)) * params.TxSizeCostPerByte @@ -139,22 +142,22 @@ func (suite *AnteTestSuite) TestConsumeGasForTxSize() { beforeGas = suite.ctx.GasMeter().GasConsumed() suite.ctx, err = antehandler(suite.ctx, tx, false) - suite.Require().Nil(err, "ConsumeTxSizeGasDecorator returned error: %v", err) + require.Nil(t, err, "ConsumeTxSizeGasDecorator returned error: %v", err) // require that decorator consumes expected amount of gas consumedGas := suite.ctx.GasMeter().GasConsumed() - beforeGas - suite.Require().Equal(expectedGas, consumedGas, "Decorator did not consume the correct amount of gas") + require.Equal(t, expectedGas, consumedGas, "Decorator did not consume the correct amount of gas") // simulation must not underestimate gas of this decorator even with nil signatures txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx) - suite.Require().NoError(err) - suite.Require().NoError(txBuilder.SetSignatures(tc.sigV2)) + require.NoError(t, err) + require.NoError(t, txBuilder.SetSignatures(tc.sigV2)) tx = txBuilder.GetTx() simTxBytes, err := suite.clientCtx.TxConfig.TxJSONEncoder()(tx) - suite.Require().Nil(err, "Cannot marshal tx: %v", err) + require.Nil(t, err, "Cannot marshal tx: %v", err) // require that simulated tx is smaller than tx with signatures - suite.Require().True(len(simTxBytes) < len(txBytes), "simulated tx still has signatures") + require.True(t, len(simTxBytes) < len(txBytes), "simulated tx still has signatures") // Set suite.ctx with smaller simulated TxBytes manually suite.ctx = suite.ctx.WithTxBytes(simTxBytes) @@ -166,14 +169,14 @@ func (suite *AnteTestSuite) TestConsumeGasForTxSize() { consumedSimGas := suite.ctx.GasMeter().GasConsumed() - beforeSimGas // require that antehandler passes and does not underestimate decorator cost - suite.Require().Nil(err, "ConsumeTxSizeGasDecorator returned error: %v", err) - suite.Require().True(consumedSimGas >= expectedGas, "Simulate mode underestimates gas on AnteDecorator. Simulated cost: %d, expected cost: %d", consumedSimGas, expectedGas) + require.Nil(t, err, "ConsumeTxSizeGasDecorator returned error: %v", err) + require.True(t, consumedSimGas >= expectedGas, "Simulate mode underestimates gas on AnteDecorator. Simulated cost: %d, expected cost: %d", consumedSimGas, expectedGas) }) } } -func (suite *AnteTestSuite) TestTxHeightTimeoutDecorator() { - suite.SetupTest(true) +func TestTxHeightTimeoutDecorator(t *testing.T) { + suite := SetupTestSuite(t, true) antehandler := sdk.ChainAnteDecorators(ante.NewTxTimeoutHeightDecorator()) @@ -186,24 +189,24 @@ func (suite *AnteTestSuite) TestTxHeightTimeoutDecorator() { gasLimit := testdata.NewTestGasLimit() testCases := []struct { - name string - timeout uint64 - height int64 - expectErr bool + name string + timeout uint64 + height int64 + expectedErr error }{ - {"default value", 0, 10, false}, - {"no timeout (greater height)", 15, 10, false}, - {"no timeout (same height)", 10, 10, false}, - {"timeout (smaller height)", 9, 10, true}, + {"default value", 0, 10, nil}, + {"no timeout (greater height)", 15, 10, nil}, + {"no timeout (same height)", 10, 10, nil}, + {"timeout (smaller height)", 9, 10, sdkerrors.ErrTxTimeoutHeight}, } for _, tc := range testCases { tc := tc - suite.Run(tc.name, func() { + t.Run(tc.name, func(t *testing.T) { suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() - suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + require.NoError(t, suite.txBuilder.SetMsgs(msg)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) @@ -212,11 +215,11 @@ func (suite *AnteTestSuite) TestTxHeightTimeoutDecorator() { privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) ctx := suite.ctx.WithBlockHeight(tc.height) _, err = antehandler(ctx, tx, true) - suite.Require().Equal(tc.expectErr, err != nil, err) + require.ErrorIs(t, err, tc.expectedErr) }) } } diff --git a/x/auth/ante/ext_test.go b/x/auth/ante/ext_test.go index 3bd0f8f602..8230b5205e 100644 --- a/x/auth/ante/ext_test.go +++ b/x/auth/ante/ext_test.go @@ -1,15 +1,18 @@ package ante_test import ( + "testing" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/tx" + "github.com/stretchr/testify/require" ) -func (suite *AnteTestSuite) TestRejectExtensionOptionsDecorator() { - suite.SetupTest(true) // setup +func TestRejectExtensionOptionsDecorator(t *testing.T) { + suite := SetupTestSuite(t, true) testCases := []struct { msg string @@ -19,7 +22,7 @@ func (suite *AnteTestSuite) TestRejectExtensionOptionsDecorator() { {"reject extension", false}, } for _, tc := range testCases { - suite.Run(tc.msg, func() { + t.Run(tc.msg, func(t *testing.T) { txBuilder := suite.clientCtx.TxConfig.NewTxBuilder() reod := ante.NewExtensionOptionsDecorator(func(_ *codectypes.Any) bool { @@ -30,7 +33,7 @@ func (suite *AnteTestSuite) TestRejectExtensionOptionsDecorator() { // no extension options should not trigger an error theTx := txBuilder.GetTx() _, err := antehandler(suite.ctx, theTx, false) - suite.Require().NoError(err) + require.NoError(t, err) extOptsTxBldr, ok := txBuilder.(tx.ExtensionOptionsTxBuilder) if !ok { @@ -40,14 +43,14 @@ func (suite *AnteTestSuite) TestRejectExtensionOptionsDecorator() { // set an extension option and check any, err := codectypes.NewAnyWithValue(testdata.NewTestMsg()) - suite.Require().NoError(err) + require.NoError(t, err) extOptsTxBldr.SetExtensionOptions(any) theTx = txBuilder.GetTx() _, err = antehandler(suite.ctx, theTx, false) if tc.allow { - suite.Require().NoError(err) + require.NoError(t, err) } else { - suite.Require().EqualError(err, "unknown extension options") + require.EqualError(t, err, "unknown extension options") } }) } diff --git a/x/auth/ante/fee_test.go b/x/auth/ante/fee_test.go index 4d2fdac56e..62f93ac0d8 100644 --- a/x/auth/ante/fee_test.go +++ b/x/auth/ante/fee_test.go @@ -1,70 +1,73 @@ package ante_test import ( + "testing" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "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/x/auth/ante" - "github.com/cosmos/cosmos-sdk/x/bank/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" ) -func (s *AnteTestSuite) TestDeductFeeDecorator_ZeroGas() { - s.SetupTest(true) // setup +func TestDeductFeeDecorator_ZeroGas(t *testing.T) { + s := SetupTestSuite(t, true) s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() mfd := ante.NewDeductFeeDecorator(s.accountKeeper, s.bankKeeper, s.feeGrantKeeper, nil) antehandler := sdk.ChainAnteDecorators(mfd) // keys and addresses - priv1, _, addr1 := testdata.KeyTestPubAddr() - coins := sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(300))) - testutil.FundAccount(s.bankKeeper, s.ctx, addr1, coins) + accs := s.CreateTestAccounts(1) // msg and signatures - msg := testdata.NewTestMsg(addr1) - s.Require().NoError(s.txBuilder.SetMsgs(msg)) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + require.NoError(t, s.txBuilder.SetMsgs(msg)) // set zero gas s.txBuilder.SetGasLimit(0) - privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) - s.Require().NoError(err) + require.NoError(t, err) // Set IsCheckTx to true s.ctx = s.ctx.WithIsCheckTx(true) _, err = antehandler(s.ctx, tx, false) - s.Require().Error(err) + require.Error(t, err) // zero gas is accepted in simulation mode _, err = antehandler(s.ctx, tx, true) - s.Require().NoError(err) + require.NoError(t, err) } -func (s *AnteTestSuite) TestEnsureMempoolFees() { - s.SetupTest(true) // setup +func TestEnsureMempoolFees(t *testing.T) { + s := SetupTestSuite(t, true) // setup s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() mfd := ante.NewDeductFeeDecorator(s.accountKeeper, s.bankKeeper, s.feeGrantKeeper, nil) antehandler := sdk.ChainAnteDecorators(mfd) // keys and addresses - priv1, _, addr1 := testdata.KeyTestPubAddr() - coins := sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(300))) - testutil.FundAccount(s.bankKeeper, s.ctx, addr1, coins) + accs := s.CreateTestAccounts(1) // msg and signatures - msg := testdata.NewTestMsg(addr1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - s.Require().NoError(s.txBuilder.SetMsgs(msg)) + require.NoError(t, s.txBuilder.SetMsgs(msg)) s.txBuilder.SetFeeAmount(feeAmount) s.txBuilder.SetGasLimit(gasLimit) - privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, feeAmount).Return(nil).Times(3) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) - s.Require().NoError(err) + require.NoError(t, err) // Set high gas price so standard test fee fails atomPrice := sdk.NewDecCoinFromDec("atom", sdk.NewDec(200).Quo(sdk.NewDec(100000))) @@ -76,19 +79,19 @@ func (s *AnteTestSuite) TestEnsureMempoolFees() { // antehandler errors with insufficient fees _, err = antehandler(s.ctx, tx, false) - s.Require().NotNil(err, "Decorator should have errored on too low fee for local gasPrice") + require.NotNil(t, err, "Decorator should have errored on too low fee for local gasPrice") // antehandler should not error since we do not check minGasPrice in simulation mode cacheCtx, _ := s.ctx.CacheContext() _, err = antehandler(cacheCtx, tx, true) - s.Require().Nil(err, "Decorator should not have errored in simulation mode") + require.Nil(t, err, "Decorator should not have errored in simulation mode") // Set IsCheckTx to false s.ctx = s.ctx.WithIsCheckTx(false) // antehandler should not error since we do not check minGasPrice in DeliverTx _, err = antehandler(s.ctx, tx, false) - s.Require().Nil(err, "MempoolFeeDecorator returned error in DeliverTx") + require.Nil(t, err, "MempoolFeeDecorator returned error in DeliverTx") // Set IsCheckTx back to true for testing sufficient mempool fee s.ctx = s.ctx.WithIsCheckTx(true) @@ -98,51 +101,41 @@ func (s *AnteTestSuite) TestEnsureMempoolFees() { s.ctx = s.ctx.WithMinGasPrices(lowGasPrice) newCtx, err := antehandler(s.ctx, tx, false) - s.Require().Nil(err, "Decorator should not have errored on fee higher than local gasPrice") + require.Nil(t, err, "Decorator should not have errored on fee higher than local gasPrice") // Priority is the smallest amount in any denom. Since we have only 1 fee // of 150atom, the priority here is 150. - s.Require().Equal(feeAmount.AmountOf("atom").Int64(), newCtx.Priority()) + require.Equal(t, feeAmount.AmountOf("atom").Int64(), newCtx.Priority()) } -func (s *AnteTestSuite) TestDeductFees() { - s.SetupTest(false) // setup +func TestDeductFees(t *testing.T) { + s := SetupTestSuite(t, false) s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() // keys and addresses - priv1, _, addr1 := testdata.KeyTestPubAddr() + accs := s.CreateTestAccounts(1) // msg and signatures - msg := testdata.NewTestMsg(addr1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - s.Require().NoError(s.txBuilder.SetMsgs(msg)) + require.NoError(t, s.txBuilder.SetMsgs(msg)) s.txBuilder.SetFeeAmount(feeAmount) s.txBuilder.SetGasLimit(gasLimit) - privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0} tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) - s.Require().NoError(err) - - // Set account with insufficient funds - acc := s.accountKeeper.NewAccountWithAddress(s.ctx, addr1) - s.accountKeeper.SetAccount(s.ctx, acc) - coins := sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(10))) - err = testutil.FundAccount(s.bankKeeper, s.ctx, addr1, coins) - s.Require().NoError(err) + require.NoError(t, err) dfd := ante.NewDeductFeeDecorator(s.accountKeeper, s.bankKeeper, nil, nil) antehandler := sdk.ChainAnteDecorators(dfd) + s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(sdkerrors.ErrInsufficientFunds) _, err = antehandler(s.ctx, tx, false) - s.Require().NotNil(err, "Tx did not error when fee payer had insufficient funds") - - // Set account with sufficient funds - s.accountKeeper.SetAccount(s.ctx, acc) - err = testutil.FundAccount(s.bankKeeper, s.ctx, addr1, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(200)))) - s.Require().NoError(err) + require.NotNil(t, err, "Tx did not error when fee payer had insufficient funds") + s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) _, err = antehandler(s.ctx, tx, false) - s.Require().Nil(err, "Tx errored after account has been set with sufficient funds") + require.Nil(t, err, "Tx errored after account has been set with sufficient funds") } diff --git a/x/auth/ante/feegrant_test.go b/x/auth/ante/feegrant_test.go index 1874945d85..9729b14c68 100644 --- a/x/auth/ante/feegrant_test.go +++ b/x/auth/ante/feegrant_test.go @@ -5,157 +5,177 @@ import ( "testing" "time" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "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/simulation" "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/ante" authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/bank/testutil" "github.com/cosmos/cosmos-sdk/x/feegrant" ) -func (suite *AnteTestSuite) TestDeductFeesNoDelegation() { - suite.SetupTest(false) - - protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(suite.interfaceRegistry), tx.DefaultSignModes) - - // this just tests our handler - dfd := ante.NewDeductFeeDecorator(suite.accountKeeper, suite.bankKeeper, suite.feeGrantKeeper, nil) - feeAnteHandler := sdk.ChainAnteDecorators(dfd) - - // this tests the whole stack - anteHandlerStack := suite.anteHandler - - // keys and addresses - priv1, _, addr1 := testdata.KeyTestPubAddr() - priv2, _, addr2 := testdata.KeyTestPubAddr() - priv3, _, addr3 := testdata.KeyTestPubAddr() - priv4, _, addr4 := testdata.KeyTestPubAddr() - priv5, _, addr5 := testdata.KeyTestPubAddr() - - // Set addr1 with insufficient funds - err := testutil.FundAccount(suite.bankKeeper, suite.ctx, addr1, []sdk.Coin{sdk.NewCoin("atom", sdk.NewInt(10))}) - suite.Require().NoError(err) - - // Set addr2 with more funds - err = testutil.FundAccount(suite.bankKeeper, suite.ctx, addr2, []sdk.Coin{sdk.NewCoin("atom", sdk.NewInt(99999))}) - suite.Require().NoError(err) - - // grant fee allowance from `addr2` to `addr3` (plenty to pay) - err = suite.feeGrantKeeper.GrantAllowance(suite.ctx, addr2, addr3, &feegrant.BasicAllowance{ - SpendLimit: sdk.NewCoins(sdk.NewInt64Coin("atom", 500)), - }) - suite.Require().NoError(err) - - // grant low fee allowance (20atom), to check the tx requesting more than allowed. - err = suite.feeGrantKeeper.GrantAllowance(suite.ctx, addr2, addr4, &feegrant.BasicAllowance{ - SpendLimit: sdk.NewCoins(sdk.NewInt64Coin("atom", 20)), - }) - suite.Require().NoError(err) - +func TestDeductFeesNoDelegation(t *testing.T) { cases := map[string]struct { - signerKey cryptotypes.PrivKey - signer sdk.AccAddress - feeAccount sdk.AccAddress - fee int64 - valid bool - }{ - "paying with low funds": { - signerKey: priv1, - signer: addr1, - fee: 50, - valid: false, + fee int64 + valid bool + err error + malleate func(*AnteTestSuite) (signer TestAccount, feeAcc sdk.AccAddress) + }{"paying with low funds": { + fee: 50, + valid: false, + err: sdkerrors.ErrInsufficientFunds, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(1) + // 2 calls are needed because we run the ante twice + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, gomock.Any()).Return(sdkerrors.ErrInsufficientFunds).Times(2) + return accs[0], nil }, + }, "paying with good funds": { - signerKey: priv2, - signer: addr2, - fee: 50, - valid: true, + fee: 50, + valid: true, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(1) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, gomock.Any()).Return(nil).Times(2) + return accs[0], nil + }, }, "paying with no account": { - signerKey: priv3, - signer: addr3, - fee: 1, - valid: false, + fee: 1, + valid: false, + err: sdkerrors.ErrUnknownAddress, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + // Do not register the account + priv, _, addr := testdata.KeyTestPubAddr() + return TestAccount{ + acc: authtypes.NewBaseAccountWithAddress(addr), + priv: priv, + }, nil + }, }, "no fee with real account": { - signerKey: priv1, - signer: addr1, - fee: 0, - valid: true, + fee: 0, + valid: true, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(1) + return accs[0], nil + }, }, "no fee with no account": { - signerKey: priv5, - signer: addr5, - fee: 0, - valid: false, + fee: 0, + valid: false, + err: sdkerrors.ErrUnknownAddress, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + // Do not register the account + priv, _, addr := testdata.KeyTestPubAddr() + return TestAccount{ + acc: authtypes.NewBaseAccountWithAddress(addr), + priv: priv, + }, nil + }, }, - "valid fee grant without account": { - signerKey: priv3, - signer: addr3, - feeAccount: addr2, - fee: 50, - valid: true, + "valid fee grant": { + // note: the original test said "valid fee grant with no account". + // this is impossible given that feegrant.GrantAllowance calls + // SetAccount for the grantee. + fee: 50, + valid: true, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(2) + suite.feeGrantKeeper.EXPECT().UseGrantedFees(gomock.Any(), accs[1].acc.GetAddress(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[1].acc.GetAddress(), authtypes.FeeCollectorName, gomock.Any()).Return(nil).Times(2) + + return accs[0], accs[1].acc.GetAddress() + }, }, "no fee grant": { - signerKey: priv3, - signer: addr3, - feeAccount: addr1, - fee: 2, - valid: false, + fee: 2, + valid: false, + err: sdkerrors.ErrNotFound, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(2) + suite.feeGrantKeeper.EXPECT(). + UseGrantedFees(gomock.Any(), accs[1].acc.GetAddress(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()). + Return(sdkerrors.ErrNotFound.Wrap("fee-grant not found")). + Times(2) + return accs[0], accs[1].acc.GetAddress() + }, }, "allowance smaller than requested fee": { - signerKey: priv4, - signer: addr4, - feeAccount: addr2, - fee: 50, - valid: false, + fee: 50, + valid: false, + err: feegrant.ErrFeeLimitExceeded, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(2) + suite.feeGrantKeeper.EXPECT(). + UseGrantedFees(gomock.Any(), accs[1].acc.GetAddress(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()). + Return(feegrant.ErrFeeLimitExceeded.Wrap("basic allowance")). + Times(2) + return accs[0], accs[1].acc.GetAddress() + }, }, "granter cannot cover allowed fee grant": { - signerKey: priv4, - signer: addr4, - feeAccount: addr1, - fee: 50, - valid: false, + fee: 50, + valid: false, + err: sdkerrors.ErrInsufficientFunds, + malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) { + accs := suite.CreateTestAccounts(2) + suite.feeGrantKeeper.EXPECT().UseGrantedFees(gomock.Any(), accs[1].acc.GetAddress(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil).Times(2) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[1].acc.GetAddress(), authtypes.FeeCollectorName, gomock.Any()).Return(sdkerrors.ErrInsufficientFunds).Times(2) + return accs[0], accs[1].acc.GetAddress() + }, }, } for name, stc := range cases { tc := stc // to make scopelint happy - suite.T().Run(name, func(t *testing.T) { - fee := sdk.NewCoins(sdk.NewInt64Coin("atom", tc.fee)) - msgs := []sdk.Msg{testdata.NewTestMsg(tc.signer)} + t.Run(name, func(t *testing.T) { + suite := SetupTestSuite(t, false) + protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(suite.encCfg.InterfaceRegistry), tx.DefaultSignModes) + // this just tests our handler + dfd := ante.NewDeductFeeDecorator(suite.accountKeeper, suite.bankKeeper, suite.feeGrantKeeper, nil) + feeAnteHandler := sdk.ChainAnteDecorators(dfd) - acc := suite.accountKeeper.GetAccount(suite.ctx, tc.signer) - privs, accNums, seqs := []cryptotypes.PrivKey{tc.signerKey}, []uint64{0}, []uint64{0} + // this tests the whole stack + anteHandlerStack := suite.anteHandler + + signer, feeAcc := stc.malleate(suite) + + fee := sdk.NewCoins(sdk.NewInt64Coin("atom", tc.fee)) + msgs := []sdk.Msg{testdata.NewTestMsg(signer.acc.GetAddress())} + + acc := suite.accountKeeper.GetAccount(suite.ctx, signer.acc.GetAddress()) + privs, accNums, seqs := []cryptotypes.PrivKey{signer.priv}, []uint64{0}, []uint64{0} if acc != nil { accNums, seqs = []uint64{acc.GetAccountNumber()}, []uint64{acc.GetSequence()} } - tx, err := genTxWithFeeGranter(protoTxCfg, msgs, fee, simtestutil.DefaultGenTxGas, suite.ctx.ChainID(), accNums, seqs, tc.feeAccount, privs...) - suite.Require().NoError(err) + var defaultGenTxGas uint64 = 10000000 + tx, err := genTxWithFeeGranter(protoTxCfg, msgs, fee, defaultGenTxGas, suite.ctx.ChainID(), accNums, seqs, feeAcc, privs...) + require.NoError(t, err) _, err = feeAnteHandler(suite.ctx, tx, false) // tests only feegrant ante if tc.valid { - suite.Require().NoError(err) + require.NoError(t, err) } else { - suite.Require().Error(err) + require.ErrorIs(t, err, tc.err) } _, err = anteHandlerStack(suite.ctx, tx, false) // tests while stack if tc.valid { - suite.Require().NoError(err) + require.NoError(t, err) } else { - suite.Require().Error(err) + require.ErrorIs(t, err, tc.err) } }) } diff --git a/x/auth/ante/setup_test.go b/x/auth/ante/setup_test.go index ed4e543b56..e7138af70e 100644 --- a/x/auth/ante/setup_test.go +++ b/x/auth/ante/setup_test.go @@ -1,15 +1,18 @@ package ante_test import ( + "testing" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "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/x/auth/ante" + "github.com/stretchr/testify/require" ) -func (suite *AnteTestSuite) TestSetup() { - suite.SetupTest(true) // setup +func TestSetup(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // keys and addresses @@ -19,13 +22,13 @@ func (suite *AnteTestSuite) TestSetup() { msg := testdata.NewTestMsg(addr1) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + require.NoError(t, suite.txBuilder.SetMsgs(msg)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) sud := ante.NewSetUpContextDecorator() antehandler := sdk.ChainAnteDecorators(sud) @@ -34,17 +37,17 @@ func (suite *AnteTestSuite) TestSetup() { suite.ctx = suite.ctx.WithBlockHeight(1).WithGasMeter(sdk.NewGasMeter(0)) // Context GasMeter Limit not set - suite.Require().Equal(uint64(0), suite.ctx.GasMeter().Limit(), "GasMeter set with limit before setup") + require.Equal(t, uint64(0), suite.ctx.GasMeter().Limit(), "GasMeter set with limit before setup") newCtx, err := antehandler(suite.ctx, tx, false) - suite.Require().Nil(err, "SetUpContextDecorator returned error") + require.Nil(t, err, "SetUpContextDecorator returned error") // Context GasMeter Limit should be set after SetUpContextDecorator runs - suite.Require().Equal(gasLimit, newCtx.GasMeter().Limit(), "GasMeter not set correctly") + require.Equal(t, gasLimit, newCtx.GasMeter().Limit(), "GasMeter not set correctly") } -func (suite *AnteTestSuite) TestRecoverPanic() { - suite.SetupTest(true) // setup +func TestRecoverPanic(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // keys and addresses @@ -54,13 +57,13 @@ func (suite *AnteTestSuite) TestRecoverPanic() { msg := testdata.NewTestMsg(addr1) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() - suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + require.NoError(t, suite.txBuilder.SetMsgs(msg)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) sud := ante.NewSetUpContextDecorator() antehandler := sdk.ChainAnteDecorators(sud, OutOfGasDecorator{}) @@ -70,13 +73,13 @@ func (suite *AnteTestSuite) TestRecoverPanic() { newCtx, err := antehandler(suite.ctx, tx, false) - suite.Require().NotNil(err, "Did not return error on OutOfGas panic") + require.NotNil(t, err, "Did not return error on OutOfGas panic") - suite.Require().True(sdkerrors.ErrOutOfGas.Is(err), "Returned error is not an out of gas error") - suite.Require().Equal(gasLimit, newCtx.GasMeter().Limit()) + require.True(t, sdkerrors.ErrOutOfGas.Is(err), "Returned error is not an out of gas error") + require.Equal(t, gasLimit, newCtx.GasMeter().Limit()) antehandler = sdk.ChainAnteDecorators(sud, PanicDecorator{}) - suite.Require().Panics(func() { antehandler(suite.ctx, tx, false) }, "Recovered from non-Out-of-Gas panic") // nolint:errcheck + require.Panics(t, func() { antehandler(suite.ctx, tx, false) }, "Recovered from non-Out-of-Gas panic") // nolint:errcheck } type OutOfGasDecorator struct{} diff --git a/x/auth/ante/sigverify_test.go b/x/auth/ante/sigverify_test.go index d398357eb9..9f7a14f5e9 100644 --- a/x/auth/ante/sigverify_test.go +++ b/x/auth/ante/sigverify_test.go @@ -2,6 +2,7 @@ package ante_test import ( "fmt" + "testing" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -17,17 +18,17 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/require" ) -func (suite *AnteTestSuite) TestSetPubKey() { - suite.SetupTest(true) // setup - require := suite.Require() +func TestSetPubKey(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // keys and addresses priv1, pub1, addr1 := testdata.KeyTestPubAddr() priv2, pub2, addr2 := testdata.KeyTestPubAddr() - priv3, pub3, addr3 := testdata.KeyTestPubAddrSecp256R1(require) + priv3, pub3, addr3 := testdata.KeyTestPubAddrSecp256R1(require.New(t)) addrs := []sdk.AccAddress{addr1, addr2, addr3} pubs := []cryptotypes.PubKey{pub1, pub2, pub3} @@ -36,34 +37,35 @@ func (suite *AnteTestSuite) TestSetPubKey() { // set accounts and create msg for each address for i, addr := range addrs { acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) - require.NoError(acc.SetAccountNumber(uint64(i))) + require.NoError(t, acc.SetAccountNumber(uint64(i))) suite.accountKeeper.SetAccount(suite.ctx, acc) msgs[i] = testdata.NewTestMsg(addr) } - require.NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) suite.txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) suite.txBuilder.SetGasLimit(testdata.NewTestGasLimit()) privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0} tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - require.NoError(err) + require.NoError(t, err) spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper) antehandler := sdk.ChainAnteDecorators(spkd) ctx, err := antehandler(suite.ctx, tx, false) - require.NoError(err) + require.NoError(t, err) // Require that all accounts have pubkey set after Decorator runs for i, addr := range addrs { pk, err := suite.accountKeeper.GetPubKey(ctx, addr) - require.NoError(err, "Error on retrieving pubkey from account") - require.True(pubs[i].Equals(pk), + require.NoError(t, err, "Error on retrieving pubkey from account") + require.True(t, pubs[i].Equals(pk), "Wrong Pubkey retrieved from AccountKeeper, idx=%d\nexpected=%s\n got=%s", i, pubs[i], pk) } } -func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() { +func TestConsumeSignatureVerificationGas(t *testing.T) { + suite := SetupTestSuite(t, true) params := types.DefaultParams() msg := []byte{1, 2, 3, 4} @@ -76,9 +78,9 @@ func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() { for i := 0; i < len(pkSet1); i++ { stdSig := legacytx.StdSignature{PubKey: pkSet1[i], Signature: sigSet1[i]} sigV2, err := legacytx.StdSignatureToSignatureV2(suite.clientCtx.LegacyAmino, stdSig) - suite.Require().NoError(err) + require.NoError(t, err) err = multisig.AddSignatureV2(multisignature1, sigV2, pkSet1) - suite.Require().NoError(err) + require.NoError(t, err) } type args struct { @@ -108,16 +110,16 @@ func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() { err := ante.DefaultSigVerificationGasConsumer(tt.args.meter, sigV2, tt.args.params) if tt.shouldErr { - suite.Require().NotNil(err) + require.NotNil(t, err) } else { - suite.Require().Nil(err) - suite.Require().Equal(tt.gasConsumed, tt.args.meter.GasConsumed(), fmt.Sprintf("%d != %d", tt.gasConsumed, tt.args.meter.GasConsumed())) + require.Nil(t, err) + require.Equal(t, tt.gasConsumed, tt.args.meter.GasConsumed(), fmt.Sprintf("%d != %d", tt.gasConsumed, tt.args.meter.GasConsumed())) } } } -func (suite *AnteTestSuite) TestSigVerification() { - suite.SetupTest(true) // setup +func TestSigVerification(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // make block height non-zero to ensure account numbers part of signBytes @@ -134,7 +136,7 @@ func (suite *AnteTestSuite) TestSigVerification() { // set accounts and create msg for each address for i, addr := range addrs { acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) - suite.Require().NoError(acc.SetAccountNumber(uint64(i))) + require.NoError(t, acc.SetAccountNumber(uint64(i))) suite.accountKeeper.SetAccount(suite.ctx, acc) msgs[i] = testdata.NewTestMsg(addr) } @@ -169,12 +171,12 @@ func (suite *AnteTestSuite) TestSigVerification() { suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) tx, err := suite.CreateTestTx(tc.privs, tc.accNums, tc.accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) if tc.invalidSigs { txSigs, _ := tx.GetSignaturesV2() badSig, _ := tc.privs[0].Sign([]byte("unrelated message")) @@ -192,9 +194,9 @@ func (suite *AnteTestSuite) TestSigVerification() { _, err = antehandler(suite.ctx, tx, false) if tc.shouldErr { - suite.Require().NotNil(err, "TestCase %d: %s did not error as expected", i, tc.name) + require.NotNil(t, err, "TestCase %d: %s did not error as expected", i, tc.name) } else { - suite.Require().Nil(err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) + require.Nil(t, err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) } } } @@ -205,7 +207,8 @@ func (suite *AnteTestSuite) TestSigVerification() { // this, since it'll be handled by the test matrix. // In the meantime, we want to make double-sure amino compatibility works. // ref: https://github.com/cosmos/cosmos-sdk/issues/7229 -func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() { +func TestSigVerification_ExplicitAmino(t *testing.T) { + suite := SetupTestSuite(t, true) // Set up TxConfig. aminoCdc := codec.NewLegacyAmino() // We're using TestMsg amino encoding in some tests, so register it here. @@ -224,7 +227,7 @@ func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() { }, ) - suite.Require().NoError(err) + require.NoError(t, err) suite.anteHandler = anteHandler suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() @@ -243,7 +246,7 @@ func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() { // set accounts and create msg for each address for i, addr := range addrs { acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) - suite.Require().NoError(acc.SetAccountNumber(uint64(i))) + require.NoError(t, acc.SetAccountNumber(uint64(i))) suite.accountKeeper.SetAccount(suite.ctx, acc) msgs[i] = testdata.NewTestMsg(addr) } @@ -276,23 +279,23 @@ func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() { suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) suite.txBuilder.SetFeeAmount(feeAmount) suite.txBuilder.SetGasLimit(gasLimit) tx, err := suite.CreateTestTx(tc.privs, tc.accNums, tc.accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) _, err = antehandler(suite.ctx, tx, false) if tc.shouldErr { - suite.Require().NotNil(err, "TestCase %d: %s did not error as expected", i, tc.name) + require.NotNil(t, err, "TestCase %d: %s did not error as expected", i, tc.name) } else { - suite.Require().Nil(err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) + require.Nil(t, err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) } } } -func (suite *AnteTestSuite) TestSigIntegration() { +func TestSigIntegration(t *testing.T) { // generate private keys privs := []cryptotypes.PrivKey{ secp256k1.GenPrivKey(), @@ -302,24 +305,24 @@ func (suite *AnteTestSuite) TestSigIntegration() { params := types.DefaultParams() initialSigCost := params.SigVerifyCostSecp256k1 - initialCost, err := suite.runSigDecorators(params, false, privs...) - suite.Require().Nil(err) + initialCost, err := runSigDecorators(t, params, false, privs...) + require.Nil(t, err) params.SigVerifyCostSecp256k1 *= 2 - doubleCost, err := suite.runSigDecorators(params, false, privs...) - suite.Require().Nil(err) + doubleCost, err := runSigDecorators(t, params, false, privs...) + require.Nil(t, err) - suite.Require().Equal(initialSigCost*uint64(len(privs)), doubleCost-initialCost) + require.Equal(t, initialSigCost*uint64(len(privs)), doubleCost-initialCost) } -func (suite *AnteTestSuite) runSigDecorators(params types.Params, _ bool, privs ...cryptotypes.PrivKey) (sdk.Gas, error) { - suite.SetupTest(true) // setup +func runSigDecorators(t *testing.T, params types.Params, _ bool, privs ...cryptotypes.PrivKey) (sdk.Gas, error) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Make block-height non-zero to include accNum in SignBytes suite.ctx = suite.ctx.WithBlockHeight(1) err := suite.accountKeeper.SetParams(suite.ctx, params) - suite.Require().NoError(err) + require.NoError(t, err) msgs := make([]sdk.Msg, len(privs)) accNums := make([]uint64, len(privs)) @@ -328,13 +331,13 @@ func (suite *AnteTestSuite) runSigDecorators(params types.Params, _ bool, privs for i, priv := range privs { addr := sdk.AccAddress(priv.PubKey().Address()) acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) - suite.Require().NoError(acc.SetAccountNumber(uint64(i))) + require.NoError(t, acc.SetAccountNumber(uint64(i))) suite.accountKeeper.SetAccount(suite.ctx, acc) msgs[i] = testdata.NewTestMsg(addr) accNums[i] = uint64(i) accSeqs[i] = uint64(0) } - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() @@ -342,7 +345,7 @@ func (suite *AnteTestSuite) runSigDecorators(params types.Params, _ bool, privs suite.txBuilder.SetGasLimit(gasLimit) tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper) svgc := ante.NewSigGasConsumeDecorator(suite.accountKeeper, ante.DefaultSigVerificationGasConsumer) @@ -357,17 +360,17 @@ func (suite *AnteTestSuite) runSigDecorators(params types.Params, _ bool, privs return after - before, err } -func (suite *AnteTestSuite) TestIncrementSequenceDecorator() { - suite.SetupTest(true) // setup +func TestIncrementSequenceDecorator(t *testing.T) { + suite := SetupTestSuite(t, true) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() priv, _, addr := testdata.KeyTestPubAddr() acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) - suite.Require().NoError(acc.SetAccountNumber(uint64(50))) + require.NoError(t, acc.SetAccountNumber(uint64(50))) suite.accountKeeper.SetAccount(suite.ctx, acc) msgs := []sdk.Msg{testdata.NewTestMsg(addr)} - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) privs := []cryptotypes.PrivKey{priv} accNums := []uint64{suite.accountKeeper.GetAccount(suite.ctx, addr).GetAccountNumber()} accSeqs := []uint64{suite.accountKeeper.GetAccount(suite.ctx, addr).GetSequence()} @@ -377,7 +380,7 @@ func (suite *AnteTestSuite) TestIncrementSequenceDecorator() { suite.txBuilder.SetGasLimit(gasLimit) tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) - suite.Require().NoError(err) + require.NoError(t, err) isd := ante.NewIncrementSequenceDecorator(suite.accountKeeper) antehandler := sdk.ChainAnteDecorators(isd) @@ -396,7 +399,7 @@ func (suite *AnteTestSuite) TestIncrementSequenceDecorator() { for i, tc := range testCases { _, err := antehandler(tc.ctx, tx, tc.simulate) - suite.Require().NoError(err, "unexpected error; tc #%d, %v", i, tc) - suite.Require().Equal(tc.expectedSeq, suite.accountKeeper.GetAccount(suite.ctx, addr).GetSequence()) + require.NoError(t, err, "unexpected error; tc #%d, %v", i, tc) + require.Equal(t, tc.expectedSeq, suite.accountKeeper.GetAccount(suite.ctx, addr).GetSequence()) } } diff --git a/x/auth/ante/testutil/expected_keepers_mocks.go b/x/auth/ante/testutil/expected_keepers_mocks.go new file mode 100644 index 0000000000..ff2803af07 --- /dev/null +++ b/x/auth/ante/testutil/expected_keepers_mocks.go @@ -0,0 +1,127 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/auth/ante/expected_keepers.go + +// Package testutil is a generated GoMock package. +package testutil + +import ( + reflect "reflect" + + types "github.com/cosmos/cosmos-sdk/types" + types0 "github.com/cosmos/cosmos-sdk/x/auth/types" + gomock "github.com/golang/mock/gomock" +) + +// MockAccountKeeper is a mock of AccountKeeper interface. +type MockAccountKeeper struct { + ctrl *gomock.Controller + recorder *MockAccountKeeperMockRecorder +} + +// MockAccountKeeperMockRecorder is the mock recorder for MockAccountKeeper. +type MockAccountKeeperMockRecorder struct { + mock *MockAccountKeeper +} + +// NewMockAccountKeeper creates a new mock instance. +func NewMockAccountKeeper(ctrl *gomock.Controller) *MockAccountKeeper { + mock := &MockAccountKeeper{ctrl: ctrl} + mock.recorder = &MockAccountKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder { + return m.recorder +} + +// GetAccount mocks base method. +func (m *MockAccountKeeper) GetAccount(ctx types.Context, addr types.AccAddress) types0.AccountI { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccount", ctx, addr) + ret0, _ := ret[0].(types0.AccountI) + return ret0 +} + +// GetAccount indicates an expected call of GetAccount. +func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetAccount), ctx, addr) +} + +// GetModuleAddress mocks base method. +func (m *MockAccountKeeper) GetModuleAddress(moduleName string) types.AccAddress { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetModuleAddress", moduleName) + ret0, _ := ret[0].(types.AccAddress) + return ret0 +} + +// GetModuleAddress indicates an expected call of GetModuleAddress. +func (mr *MockAccountKeeperMockRecorder) GetModuleAddress(moduleName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetModuleAddress", reflect.TypeOf((*MockAccountKeeper)(nil).GetModuleAddress), moduleName) +} + +// GetParams mocks base method. +func (m *MockAccountKeeper) GetParams(ctx types.Context) types0.Params { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetParams", ctx) + ret0, _ := ret[0].(types0.Params) + return ret0 +} + +// GetParams indicates an expected call of GetParams. +func (mr *MockAccountKeeperMockRecorder) GetParams(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParams", reflect.TypeOf((*MockAccountKeeper)(nil).GetParams), ctx) +} + +// SetAccount mocks base method. +func (m *MockAccountKeeper) SetAccount(ctx types.Context, acc types0.AccountI) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetAccount", ctx, acc) +} + +// SetAccount indicates an expected call of SetAccount. +func (mr *MockAccountKeeperMockRecorder) SetAccount(ctx, acc interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).SetAccount), ctx, acc) +} + +// MockFeegrantKeeper is a mock of FeegrantKeeper interface. +type MockFeegrantKeeper struct { + ctrl *gomock.Controller + recorder *MockFeegrantKeeperMockRecorder +} + +// MockFeegrantKeeperMockRecorder is the mock recorder for MockFeegrantKeeper. +type MockFeegrantKeeperMockRecorder struct { + mock *MockFeegrantKeeper +} + +// NewMockFeegrantKeeper creates a new mock instance. +func NewMockFeegrantKeeper(ctrl *gomock.Controller) *MockFeegrantKeeper { + mock := &MockFeegrantKeeper{ctrl: ctrl} + mock.recorder = &MockFeegrantKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFeegrantKeeper) EXPECT() *MockFeegrantKeeperMockRecorder { + return m.recorder +} + +// UseGrantedFees mocks base method. +func (m *MockFeegrantKeeper) UseGrantedFees(ctx types.Context, granter, grantee types.AccAddress, fee types.Coins, msgs []types.Msg) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UseGrantedFees", ctx, granter, grantee, fee, msgs) + ret0, _ := ret[0].(error) + return ret0 +} + +// UseGrantedFees indicates an expected call of UseGrantedFees. +func (mr *MockFeegrantKeeperMockRecorder) UseGrantedFees(ctx, granter, grantee, fee, msgs interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseGrantedFees", reflect.TypeOf((*MockFeegrantKeeper)(nil).UseGrantedFees), ctx, granter, grantee, fee, msgs) +} diff --git a/x/auth/ante/testutil_test.go b/x/auth/ante/testutil_test.go index 5167dac536..d996dcc3bd 100644 --- a/x/auth/ante/testutil_test.go +++ b/x/auth/ante/testutil_test.go @@ -1,33 +1,27 @@ package ante_test import ( - "errors" - "fmt" "testing" - "github.com/cosmos/cosmos-sdk/codec" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - - "github.com/stretchr/testify/suite" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/cosmos/cosmos-sdk/testutil" "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" "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/testutil" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + antetestutil "github.com/cosmos/cosmos-sdk/x/auth/ante/testutil" xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil" "github.com/cosmos/cosmos-sdk/x/auth/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" ) // TestAccount represents an account used in the tests in x/auth/ante. @@ -38,91 +32,148 @@ type TestAccount struct { // AnteTestSuite is a test suite to be used with ante handler tests. type AnteTestSuite struct { - suite.Suite - - interfaceRegistry codectypes.InterfaceRegistry - anteHandler sdk.AnteHandler - ctx sdk.Context - clientCtx client.Context - txBuilder client.TxBuilder - accountKeeper keeper.AccountKeeper - bankKeeper bankkeeper.Keeper - feeGrantKeeper feegrantkeeper.Keeper -} - -func TestAnteTestSuite(t *testing.T) { - suite.Run(t, new(AnteTestSuite)) + anteHandler sdk.AnteHandler + ctx sdk.Context + clientCtx client.Context + txBuilder client.TxBuilder + accountKeeper keeper.AccountKeeper + bankKeeper *authtestutil.MockBankKeeper + feeGrantKeeper *antetestutil.MockFeegrantKeeper + encCfg moduletestutil.TestEncodingConfig } // SetupTest setups a new test, with new app, context, and anteHandler. -func (suite *AnteTestSuite) SetupTest(isCheckTx bool) { - var ( - txConfig client.TxConfig - legacyAmino *codec.LegacyAmino - ) +func SetupTestSuite(t *testing.T, isCheckTx bool) *AnteTestSuite { + suite := &AnteTestSuite{} + ctrl := gomock.NewController(t) + suite.bankKeeper = authtestutil.NewMockBankKeeper(ctrl) - app, err := simtestutil.Setup( - testutil.AppConfig, - &suite.accountKeeper, - &suite.bankKeeper, - &suite.feeGrantKeeper, - &suite.interfaceRegistry, - &txConfig, - &legacyAmino, - ) - suite.Require().NoError(err) + suite.feeGrantKeeper = antetestutil.NewMockFeegrantKeeper(ctrl) - suite.ctx = app.BaseApp.NewContext(isCheckTx, tmproto.Header{}).WithBlockHeight(1) - err = suite.accountKeeper.SetParams(suite.ctx, authtypes.DefaultParams()) - suite.Require().NoError(err) + key := sdk.NewKVStoreKey(types.StoreKey) + testCtx := testutil.DefaultContextWithDB(t, key, sdk.NewTransientStoreKey("transient_test")) + suite.ctx = testCtx.Ctx.WithIsCheckTx(isCheckTx).WithBlockHeight(1) //app.BaseApp.NewContext(isCheckTx, tmproto.Header{}).WithBlockHeight(1) + suite.encCfg = moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}) + + maccPerms := map[string][]string{ + "fee_collector": nil, + "mint": {"minter"}, + "bonded_tokens_pool": {"burner", "staking"}, + "not_bonded_tokens_pool": {"burner", "staking"}, + "multiPerm": {"burner", "minter", "staking"}, + "random": {"random"}, + } + + suite.accountKeeper = keeper.NewAccountKeeper( + suite.encCfg.Codec, key, types.ProtoBaseAccount, maccPerms, sdk.Bech32MainPrefix, types.NewModuleAddress("gov").String(), + ) + suite.accountKeeper.GetModuleAccount(suite.ctx, types.FeeCollectorName) + err := suite.accountKeeper.SetParams(suite.ctx, types.DefaultParams()) + require.NoError(t, err) // We're using TestMsg encoding in some tests, so register it here. - legacyAmino.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) - testdata.RegisterInterfaces(suite.interfaceRegistry) + suite.encCfg.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) + testdata.RegisterInterfaces(suite.encCfg.InterfaceRegistry) suite.clientCtx = client.Context{}. - WithTxConfig(txConfig) + WithTxConfig(suite.encCfg.TxConfig) anteHandler, err := ante.NewAnteHandler( ante.HandlerOptions{ AccountKeeper: suite.accountKeeper, BankKeeper: suite.bankKeeper, FeegrantKeeper: suite.feeGrantKeeper, - SignModeHandler: txConfig.SignModeHandler(), + SignModeHandler: suite.encCfg.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, ) - suite.Require().NoError(err) + require.NoError(t, err) suite.anteHandler = anteHandler + + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + return suite } -// CreateTestAccounts creates `numAccs` accounts, and return all relevant -// information about them including their private keys. func (suite *AnteTestSuite) CreateTestAccounts(numAccs int) []TestAccount { var accounts []TestAccount for i := 0; i < numAccs; i++ { priv, _, addr := testdata.KeyTestPubAddr() acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr) - err := acc.SetAccountNumber(uint64(i)) - suite.Require().NoError(err) + acc.SetAccountNumber(uint64(i)) suite.accountKeeper.SetAccount(suite.ctx, acc) - someCoins := sdk.Coins{ - sdk.NewInt64Coin("atom", 10000000), - } - err = suite.bankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, someCoins) - suite.Require().NoError(err) - - err = suite.bankKeeper.SendCoinsFromModuleToAccount(suite.ctx, minttypes.ModuleName, addr, someCoins) - suite.Require().NoError(err) - accounts = append(accounts, TestAccount{acc, priv}) } return accounts } +// TestCase represents a test case used in test tables. +type TestCase struct { + desc string + malleate func(*AnteTestSuite) TestCaseArgs + simulate bool + expPass bool + expErr error +} + +type TestCaseArgs struct { + chainID string + accNums []uint64 + accSeqs []uint64 + feeAmount sdk.Coins + gasLimit uint64 + msgs []sdk.Msg + privs []cryptotypes.PrivKey +} + +// DeliverMsgs constructs a tx and runs it through the ante handler. This is used to set the context for a test case, for +// example to test for replay protection. +func (suite *AnteTestSuite) DeliverMsgs(t *testing.T, privs []cryptotypes.PrivKey, msgs []sdk.Msg, feeAmount sdk.Coins, gasLimit uint64, accNums, accSeqs []uint64, chainID string, simulate bool) (sdk.Context, error) { + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + tx, txErr := suite.CreateTestTx(privs, accNums, accSeqs, chainID) + require.NoError(t, txErr) + return suite.anteHandler(suite.ctx, tx, simulate) +} + +func (suite *AnteTestSuite) RunTestCase(t *testing.T, tc TestCase, args TestCaseArgs) { + require.NoError(t, suite.txBuilder.SetMsgs(args.msgs...)) + suite.txBuilder.SetFeeAmount(args.feeAmount) + suite.txBuilder.SetGasLimit(args.gasLimit) + + // Theoretically speaking, ante handler unit tests should only test + // ante handlers, but here we sometimes also test the tx creation + // process. + tx, txErr := suite.CreateTestTx(args.privs, args.accNums, args.accSeqs, args.chainID) + newCtx, anteErr := suite.anteHandler(suite.ctx, tx, tc.simulate) + + if tc.expPass { + require.NoError(t, txErr) + require.NoError(t, anteErr) + require.NotNil(t, newCtx) + + suite.ctx = newCtx + } else { + switch { + case txErr != nil: + require.Error(t, txErr) + require.ErrorIs(t, txErr, tc.expErr) + + case anteErr != nil: + require.Error(t, anteErr) + require.ErrorIs(t, anteErr, tc.expErr) + + default: + t.Fatal("expected one of txErr, anteErr to be an error") + } + } +} + // 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) (xauthsigning.Tx, error) { // First round: we gather all the signer infos. We use the "set empty @@ -169,48 +220,3 @@ func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums [] return suite.txBuilder.GetTx(), nil } - -// TestCase represents a test case used in test tables. -type TestCase struct { - desc string - malleate func() - simulate bool - expPass bool - expErr error -} - -// CreateTestTx is a helper function to create a tx given multiple inputs. -func (suite *AnteTestSuite) RunTestCase(privs []cryptotypes.PrivKey, msgs []sdk.Msg, feeAmount sdk.Coins, gasLimit uint64, accNums, accSeqs []uint64, chainID string, tc TestCase) { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) - suite.txBuilder.SetFeeAmount(feeAmount) - suite.txBuilder.SetGasLimit(gasLimit) - - // Theoretically speaking, ante handler unit tests should only test - // ante handlers, but here we sometimes also test the tx creation - // process. - tx, txErr := suite.CreateTestTx(privs, accNums, accSeqs, chainID) - newCtx, anteErr := suite.anteHandler(suite.ctx, tx, tc.simulate) - - if tc.expPass { - suite.Require().NoError(txErr) - suite.Require().NoError(anteErr) - suite.Require().NotNil(newCtx) - - suite.ctx = newCtx - } else { - switch { - case txErr != nil: - suite.Require().Error(txErr) - suite.Require().True(errors.Is(txErr, tc.expErr)) - - case anteErr != nil: - suite.Require().Error(anteErr) - suite.Require().True(errors.Is(anteErr, tc.expErr)) - - default: - suite.Fail("expected one of txErr,anteErr to be an error") - } - } - }) -} diff --git a/x/auth/keeper/grpc_query_test.go b/x/auth/keeper/grpc_query_test.go index 3ecdcfe86f..8b7f69e113 100644 --- a/x/auth/keeper/grpc_query_test.go +++ b/x/auth/keeper/grpc_query_test.go @@ -41,7 +41,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryAccounts() { addresses := make([]sdk.AccAddress, len(res.Accounts)) for i, acc := range res.Accounts { var account types.AccountI - err := suite.interfaceRegistry.UnpackAny(acc, &account) + err := suite.encCfg.InterfaceRegistry.UnpackAny(acc, &account) suite.Require().NoError(err) addresses[i] = account.GetAddress() } @@ -124,7 +124,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryAccount() { true, func(res *types.QueryAccountResponse) { var newAccount types.AccountI - err := suite.interfaceRegistry.UnpackAny(res.Account, &newAccount) + err := suite.encCfg.InterfaceRegistry.UnpackAny(res.Account, &newAccount) suite.Require().NoError(err) suite.Require().NotNil(newAccount) suite.Require().True(addr.Equals(newAccount.GetAddress())) @@ -277,7 +277,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryModuleAccounts() { mintModuleExists := false for _, acc := range res.Accounts { var account types.AccountI - err := suite.interfaceRegistry.UnpackAny(acc, &account) + err := suite.encCfg.InterfaceRegistry.UnpackAny(acc, &account) suite.Require().NoError(err) moduleAccount, ok := account.(types.ModuleAccountI) @@ -300,7 +300,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryModuleAccounts() { mintModuleExists := false for _, acc := range res.Accounts { var account types.AccountI - err := suite.interfaceRegistry.UnpackAny(acc, &account) + err := suite.encCfg.InterfaceRegistry.UnpackAny(acc, &account) suite.Require().NoError(err) moduleAccount, ok := account.(types.ModuleAccountI) @@ -331,7 +331,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryModuleAccounts() { var moduleNames []string for _, any := range res.Accounts { var account types.AccountI - err := suite.interfaceRegistry.UnpackAny(any, &account) + err := suite.encCfg.InterfaceRegistry.UnpackAny(any, &account) suite.Require().NoError(err) moduleAccount, ok := account.(types.ModuleAccountI) suite.Require().True(ok) diff --git a/x/auth/keeper/keeper_test.go b/x/auth/keeper/keeper_test.go index d1f135ee90..bc77a26484 100644 --- a/x/auth/keeper/keeper_test.go +++ b/x/auth/keeper/keeper_test.go @@ -6,13 +6,11 @@ import ( "github.com/stretchr/testify/suite" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/runtime" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/testutil" "github.com/cosmos/cosmos-sdk/x/auth/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -33,29 +31,39 @@ type KeeperTestSuite struct { ctx sdk.Context - app *runtime.App - queryClient types.QueryClient - legacyAmino *codec.LegacyAmino - interfaceRegistry codectypes.InterfaceRegistry - accountKeeper keeper.AccountKeeper - msgServer types.MsgServer + queryClient types.QueryClient + accountKeeper keeper.AccountKeeper + msgServer types.MsgServer + encCfg moduletestutil.TestEncodingConfig } func (suite *KeeperTestSuite) SetupTest() { - app, err := simtestutil.Setup( - testutil.AppConfig, - &suite.legacyAmino, - &suite.interfaceRegistry, - &suite.accountKeeper, - &suite.interfaceRegistry, + suite.encCfg = moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}) + + key := sdk.NewKVStoreKey(types.StoreKey) + testCtx := testutil.DefaultContextWithDB(suite.T(), key, sdk.NewTransientStoreKey("transient_test")) + suite.ctx = testCtx.Ctx.WithBlockHeader(tmproto.Header{}) + + maccPerms := map[string][]string{ + "fee_collector": nil, + "mint": {"minter"}, + "bonded_tokens_pool": {"burner", "staking"}, + "not_bonded_tokens_pool": {"burner", "staking"}, + multiPerm: {"burner", "minter", "staking"}, + randomPerm: {"random"}, + } + + suite.accountKeeper = keeper.NewAccountKeeper( + suite.encCfg.Codec, + key, + types.ProtoBaseAccount, + maccPerms, + "cosmos", + types.NewModuleAddress("gov").String(), ) - suite.Require().NoError(err) - suite.app = app - suite.ctx = app.BaseApp.NewContext(true, tmproto.Header{}) suite.msgServer = keeper.NewMsgServerImpl(suite.accountKeeper) - - queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.interfaceRegistry) + queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.encCfg.InterfaceRegistry) types.RegisterQueryServer(queryHelper, suite.accountKeeper) suite.queryClient = types.NewQueryClient(queryHelper) } diff --git a/x/auth/keeper/querier_test.go b/x/auth/keeper/querier_test.go index 7eef9c3b2e..7239d18df9 100644 --- a/x/auth/keeper/querier_test.go +++ b/x/auth/keeper/querier_test.go @@ -14,7 +14,7 @@ import ( func (suite *KeeperTestSuite) TestQueryAccount() { ctx := suite.ctx - legacyQuerierCdc := codec.NewAminoCodec(suite.legacyAmino) + legacyQuerierCdc := codec.NewAminoCodec(suite.encCfg.Amino) req := abci.RequestQuery{ Path: "", diff --git a/x/auth/signing/verify_test.go b/x/auth/signing/verify_test.go index 6e5d8f4f9f..fa06ef5720 100644 --- a/x/auth/signing/verify_test.go +++ b/x/auth/signing/verify_test.go @@ -5,22 +5,20 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/codec" kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/testutil" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/signing" - authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil" "github.com/cosmos/cosmos-sdk/x/auth/types" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - "github.com/cosmos/cosmos-sdk/x/bank/testutil" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -33,29 +31,36 @@ func TestVerifySignature(t *testing.T) { chainId = "test-chain" ) - var ( - accountKeeper keeper.AccountKeeper - bankKeeper bankkeeper.Keeper + encCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}) + key := sdk.NewKVStoreKey(types.StoreKey) + + maccPerms := map[string][]string{ + "fee_collector": nil, + "mint": {"minter"}, + "bonded_tokens_pool": {"burner", "staking"}, + "not_bonded_tokens_pool": {"burner", "staking"}, + "multiPerm": {"burner", "minter", "staking"}, + "random": {"random"}, + } + + accountKeeper := keeper.NewAccountKeeper( + encCfg.Codec, + key, + types.ProtoBaseAccount, + maccPerms, + "cosmos", + types.NewModuleAddress("gov").String(), ) - app, err := simtestutil.Setup(authtestutil.AppConfig, &accountKeeper, &bankKeeper) - require.NoError(t, err) - - ctx := app.BaseApp.NewContext(false, tmproto.Header{}).WithBlockHeight(1) - - cdc := codec.NewLegacyAmino() - sdk.RegisterLegacyAminoCodec(cdc) - types.RegisterLegacyAminoCodec(cdc) - cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil) + testCtx := testutil.DefaultContextWithDB(t, key, sdk.NewTransientStoreKey("transient_test")) + ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{}) + encCfg.Amino.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil) acc1 := accountKeeper.NewAccountWithAddress(ctx, addr) _ = accountKeeper.NewAccountWithAddress(ctx, addr1) accountKeeper.SetAccount(ctx, acc1) - balances := sdk.NewCoins(sdk.NewInt64Coin("atom", 200)) - require.NoError(t, testutil.FundAccount(bankKeeper, ctx, addr, balances)) acc, err := ante.GetSignerAcc(ctx, accountKeeper, addr) require.NoError(t, err) - require.NoError(t, testutil.FundAccount(bankKeeper, ctx, addr, balances)) msgs := []sdk.Msg{testdata.NewTestMsg(addr)} fee := legacytx.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) @@ -71,7 +76,7 @@ func TestVerifySignature(t *testing.T) { require.NoError(t, err) stdSig := legacytx.StdSignature{PubKey: pubKey, Signature: signature} - sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig) + sigV2, err := legacytx.StdSignatureToSignatureV2(encCfg.Amino, stdSig) require.NoError(t, err) handler := MakeTestHandlerMap() @@ -89,13 +94,13 @@ func TestVerifySignature(t *testing.T) { sig1, err := priv.Sign(multiSignBytes) require.NoError(t, err) stdSig1 := legacytx.StdSignature{PubKey: pubKey, Signature: sig1} - sig1V2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig1) + sig1V2, err := legacytx.StdSignatureToSignatureV2(encCfg.Amino, stdSig1) require.NoError(t, err) sig2, err := priv1.Sign(multiSignBytes) require.NoError(t, err) stdSig2 := legacytx.StdSignature{PubKey: pubKey, Signature: sig2} - sig2V2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig2) + sig2V2, err := legacytx.StdSignatureToSignatureV2(encCfg.Amino, stdSig2) require.NoError(t, err) err = multisig.AddSignatureFromPubKey(multisignature, sig1V2.Data, pkSet[0], pkSet) diff --git a/x/auth/testutil/expected_keepers_mocks.go b/x/auth/testutil/expected_keepers_mocks.go new file mode 100644 index 0000000000..97c2beed47 --- /dev/null +++ b/x/auth/testutil/expected_keepers_mocks.go @@ -0,0 +1,63 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/auth/types/expected_keepers.go + +// Package testutil is a generated GoMock package. +package testutil + +import ( + reflect "reflect" + + types "github.com/cosmos/cosmos-sdk/types" + gomock "github.com/golang/mock/gomock" +) + +// MockBankKeeper is a mock of BankKeeper interface. +type MockBankKeeper struct { + ctrl *gomock.Controller + recorder *MockBankKeeperMockRecorder +} + +// MockBankKeeperMockRecorder is the mock recorder for MockBankKeeper. +type MockBankKeeperMockRecorder struct { + mock *MockBankKeeper +} + +// NewMockBankKeeper creates a new mock instance. +func NewMockBankKeeper(ctrl *gomock.Controller) *MockBankKeeper { + mock := &MockBankKeeper{ctrl: ctrl} + mock.recorder = &MockBankKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder { + return m.recorder +} + +// SendCoins mocks base method. +func (m *MockBankKeeper) SendCoins(ctx types.Context, from, to types.AccAddress, amt types.Coins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendCoins", ctx, from, to, amt) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendCoins indicates an expected call of SendCoins. +func (mr *MockBankKeeperMockRecorder) SendCoins(ctx, from, to, amt interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoins", reflect.TypeOf((*MockBankKeeper)(nil).SendCoins), ctx, from, to, amt) +} + +// SendCoinsFromAccountToModule mocks base method. +func (m *MockBankKeeper) SendCoinsFromAccountToModule(ctx types.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendCoinsFromAccountToModule", ctx, senderAddr, recipientModule, amt) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendCoinsFromAccountToModule indicates an expected call of SendCoinsFromAccountToModule. +func (mr *MockBankKeeperMockRecorder) SendCoinsFromAccountToModule(ctx, senderAddr, recipientModule, amt interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromAccountToModule", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromAccountToModule), ctx, senderAddr, recipientModule, amt) +} diff --git a/x/auth/vesting/types/vesting_account_test.go b/x/auth/vesting/types/vesting_account_test.go index b00e8af358..8a773efa87 100644 --- a/x/auth/vesting/types/vesting_account_test.go +++ b/x/auth/vesting/types/vesting_account_test.go @@ -10,12 +10,13 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/auth/vesting/testutil" + "github.com/cosmos/cosmos-sdk/x/auth/vesting" "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" ) @@ -32,10 +33,29 @@ type VestingAccountTestSuite struct { } func (s *VestingAccountTestSuite) SetupTest() { - app, err := simtestutil.Setup(testutil.AppConfig, &s.accountKeeper) - require.NoError(s.T(), err) + encCfg := moduletestutil.MakeTestEncodingConfig(vesting.AppModuleBasic{}) - s.ctx = app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) + key := sdk.NewKVStoreKey(authtypes.StoreKey) + testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test")) + s.ctx = testCtx.Ctx.WithBlockHeader(tmproto.Header{}) + + maccPerms := map[string][]string{ + "fee_collector": nil, + "mint": {"minter"}, + "bonded_tokens_pool": {"burner", "staking"}, + "not_bonded_tokens_pool": {"burner", "staking"}, + "multiPerm": {"burner", "minter", "staking"}, + "random": {"random"}, + } + + s.accountKeeper = keeper.NewAccountKeeper( + encCfg.Codec, + key, + authtypes.ProtoBaseAccount, + maccPerms, + "cosmos", + authtypes.NewModuleAddress("gov").String(), + ) } func TestGetVestedCoinsContVestingAcc(t *testing.T) {