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)
This commit is contained in:
Facundo Medica 2022-07-27 14:49:19 -03:00 committed by GitHub
parent 25929e3135
commit a8a52d0775
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1530 additions and 930 deletions

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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)
})
}
}

View File

@ -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")
}
})
}

View File

@ -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")
}

View File

@ -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)
}
})
}

View File

@ -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{}

View File

@ -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())
}
}

View File

@ -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)
}

View File

@ -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")
}
}
})
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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: "",

View File

@ -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)

View File

@ -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)
}

View File

@ -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) {