github.com/Finschia/finschia-sdk@v0.49.1/x/auth/ante/testutil_test.go (about) 1 package ante_test 2 3 import ( 4 "errors" 5 "fmt" 6 "testing" 7 8 "github.com/stretchr/testify/suite" 9 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 10 11 "github.com/Finschia/finschia-sdk/client" 12 "github.com/Finschia/finschia-sdk/client/tx" 13 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 14 "github.com/Finschia/finschia-sdk/simapp" 15 "github.com/Finschia/finschia-sdk/testutil/testdata" 16 sdk "github.com/Finschia/finschia-sdk/types" 17 "github.com/Finschia/finschia-sdk/types/tx/signing" 18 "github.com/Finschia/finschia-sdk/x/auth/ante" 19 xauthsigning "github.com/Finschia/finschia-sdk/x/auth/signing" 20 authtypes "github.com/Finschia/finschia-sdk/x/auth/types" 21 minttypes "github.com/Finschia/finschia-sdk/x/mint/types" 22 ) 23 24 // TestAccount represents an account used in the tests in x/auth/ante. 25 type TestAccount struct { 26 acc authtypes.AccountI 27 priv cryptotypes.PrivKey 28 } 29 30 // AnteTestSuite is a test suite to be used with ante handler tests. 31 type AnteTestSuite struct { 32 suite.Suite 33 34 app *simapp.SimApp 35 anteHandler sdk.AnteHandler 36 ctx sdk.Context 37 clientCtx client.Context 38 txBuilder client.TxBuilder 39 } 40 41 // returns context and app with params set on account keeper 42 func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { 43 app := simapp.Setup(isCheckTx) 44 ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) 45 app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams()) 46 47 return app, ctx 48 } 49 50 // SetupTest setups a new test, with new app, context, and anteHandler. 51 func (suite *AnteTestSuite) SetupTest(isCheckTx bool) { 52 suite.app, suite.ctx = createTestApp(isCheckTx) 53 suite.ctx = suite.ctx.WithBlockHeight(1) 54 55 // Set up TxConfig. 56 encodingConfig := simapp.MakeTestEncodingConfig() 57 // We're using TestMsg encoding in some tests, so register it here. 58 encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) 59 testdata.RegisterInterfaces(encodingConfig.InterfaceRegistry) 60 61 suite.clientCtx = client.Context{}. 62 WithTxConfig(encodingConfig.TxConfig) 63 64 anteHandler, err := ante.NewAnteHandler( 65 ante.HandlerOptions{ 66 AccountKeeper: suite.app.AccountKeeper, 67 BankKeeper: suite.app.BankKeeper, 68 FeegrantKeeper: suite.app.FeeGrantKeeper, 69 SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), 70 SigGasConsumer: ante.DefaultSigVerificationGasConsumer, 71 }, 72 ) 73 74 suite.Require().NoError(err) 75 suite.anteHandler = anteHandler 76 } 77 78 // CreateTestAccounts creates `numAccs` accounts, and return all relevant 79 // information about them including their private keys. 80 func (suite *AnteTestSuite) CreateTestAccounts(numAccs int) []TestAccount { 81 var accounts []TestAccount 82 83 for i := 0; i < numAccs; i++ { 84 priv, _, addr := testdata.KeyTestPubAddr() 85 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr) 86 err := acc.SetAccountNumber(uint64(i)) 87 suite.Require().NoError(err) 88 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 89 someCoins := sdk.Coins{ 90 sdk.NewInt64Coin("atom", 10000000), 91 } 92 err = suite.app.BankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, someCoins) 93 suite.Require().NoError(err) 94 95 err = suite.app.BankKeeper.SendCoinsFromModuleToAccount(suite.ctx, minttypes.ModuleName, addr, someCoins) 96 suite.Require().NoError(err) 97 98 accounts = append(accounts, TestAccount{acc, priv}) 99 } 100 101 return accounts 102 } 103 104 // CreateTestTx is a helper function to create a tx given multiple inputs. 105 func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums, accSeqs []uint64, chainID string) (xauthsigning.Tx, error) { 106 // First round: we gather all the signer infos. We use the "set empty 107 // signature" hack to do that. 108 var sigsV2 []signing.SignatureV2 109 for i, priv := range privs { 110 sigV2 := signing.SignatureV2{ 111 PubKey: priv.PubKey(), 112 Data: &signing.SingleSignatureData{ 113 SignMode: suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), 114 Signature: nil, 115 }, 116 Sequence: accSeqs[i], 117 } 118 119 sigsV2 = append(sigsV2, sigV2) 120 } 121 err := suite.txBuilder.SetSignatures(sigsV2...) 122 if err != nil { 123 return nil, err 124 } 125 126 // Second round: all signer infos are set, so each signer can sign. 127 sigsV2 = []signing.SignatureV2{} 128 for i, priv := range privs { 129 signerData := xauthsigning.SignerData{ 130 ChainID: chainID, 131 AccountNumber: accNums[i], 132 Sequence: accSeqs[i], 133 } 134 sigV2, err := tx.SignWithPrivKey( 135 suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, 136 suite.txBuilder, priv, suite.clientCtx.TxConfig, accSeqs[i]) 137 if err != nil { 138 return nil, err 139 } 140 141 sigsV2 = append(sigsV2, sigV2) 142 } 143 err = suite.txBuilder.SetSignatures(sigsV2...) 144 if err != nil { 145 return nil, err 146 } 147 148 return suite.txBuilder.GetTx(), nil 149 } 150 151 // TestCase represents a test case used in test tables. 152 type TestCase struct { 153 desc string 154 malleate func() 155 simulate bool 156 expPass bool 157 expErr error 158 } 159 160 // CreateTestTx is a helper function to create a tx given multiple inputs. 161 func (suite *AnteTestSuite) RunTestCase(privs []cryptotypes.PrivKey, msgs []sdk.Msg, feeAmount sdk.Coins, gasLimit uint64, accNums, accSeqs []uint64, chainID string, tc TestCase) { 162 suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { 163 suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) 164 suite.txBuilder.SetFeeAmount(feeAmount) 165 suite.txBuilder.SetGasLimit(gasLimit) 166 167 // Theoretically speaking, ante handler unit tests should only test 168 // ante handlers, but here we sometimes also test the tx creation 169 // process. 170 tx, txErr := suite.CreateTestTx(privs, accNums, accSeqs, chainID) 171 newCtx, anteErr := suite.anteHandler(suite.ctx, tx, tc.simulate) 172 173 if tc.expPass { 174 suite.Require().NoError(txErr) 175 suite.Require().NoError(anteErr) 176 suite.Require().NotNil(newCtx) 177 178 suite.ctx = newCtx 179 } else { 180 switch { 181 case txErr != nil: 182 suite.Require().Error(txErr) 183 suite.Require().True(errors.Is(txErr, tc.expErr)) 184 185 case anteErr != nil: 186 suite.Require().Error(anteErr) 187 suite.Require().True(errors.Is(anteErr, tc.expErr)) 188 189 default: 190 suite.Fail("expected one of txErr,anteErr to be an error") 191 } 192 } 193 }) 194 } 195 196 func TestAnteTestSuite(t *testing.T) { 197 suite.Run(t, new(AnteTestSuite)) 198 }