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