github.com/cosmos/cosmos-sdk@v0.50.10/testutil/sims/tx_helpers.go (about) 1 package sims 2 3 import ( 4 "context" 5 "math/rand" 6 "testing" 7 "time" 8 9 types2 "github.com/cometbft/cometbft/abci/types" 10 "github.com/cometbft/cometbft/proto/tendermint/types" 11 "github.com/stretchr/testify/require" 12 13 "cosmossdk.io/errors" 14 15 "github.com/cosmos/cosmos-sdk/baseapp" 16 "github.com/cosmos/cosmos-sdk/client" 17 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 18 sdk "github.com/cosmos/cosmos-sdk/types" 19 "github.com/cosmos/cosmos-sdk/types/simulation" 20 "github.com/cosmos/cosmos-sdk/types/tx/signing" 21 authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" 22 ) 23 24 // GenSignedMockTx generates a signed mock transaction. 25 func GenSignedMockTx(r *rand.Rand, txConfig client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey) (sdk.Tx, error) { 26 sigs := make([]signing.SignatureV2, len(priv)) 27 28 // create a random length memo 29 memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100)) 30 31 signMode, err := authsign.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode()) 32 if err != nil { 33 return nil, err 34 } 35 36 // 1st round: set SignatureV2 with empty signatures, to set correct 37 // signer infos. 38 for i, p := range priv { 39 sigs[i] = signing.SignatureV2{ 40 PubKey: p.PubKey(), 41 Data: &signing.SingleSignatureData{ 42 SignMode: signMode, 43 }, 44 Sequence: accSeqs[i], 45 } 46 } 47 48 tx := txConfig.NewTxBuilder() 49 err = tx.SetMsgs(msgs...) 50 if err != nil { 51 return nil, err 52 } 53 err = tx.SetSignatures(sigs...) 54 if err != nil { 55 return nil, err 56 } 57 tx.SetMemo(memo) 58 tx.SetFeeAmount(feeAmt) 59 tx.SetGasLimit(gas) 60 61 // 2nd round: once all signer infos are set, every signer can sign. 62 for i, p := range priv { 63 signerData := authsign.SignerData{ 64 Address: sdk.AccAddress(p.PubKey().Address()).String(), 65 ChainID: chainID, 66 AccountNumber: accNums[i], 67 Sequence: accSeqs[i], 68 PubKey: p.PubKey(), 69 } 70 71 signBytes, err := authsign.GetSignBytesAdapter( 72 context.Background(), txConfig.SignModeHandler(), signMode, signerData, 73 tx.GetTx()) 74 if err != nil { 75 panic(err) 76 } 77 sig, err := p.Sign(signBytes) 78 if err != nil { 79 panic(err) 80 } 81 sigs[i].Data.(*signing.SingleSignatureData).Signature = sig 82 } 83 err = tx.SetSignatures(sigs...) 84 if err != nil { 85 panic(err) 86 } 87 88 return tx.GetTx(), nil 89 } 90 91 // SignCheckDeliver checks a generated signed transaction and simulates a 92 // block commitment with the given transaction. A test assertion is made using 93 // the parameter 'expPass' against the result. A corresponding result is 94 // returned. 95 func SignCheckDeliver( 96 t *testing.T, txCfg client.TxConfig, app *baseapp.BaseApp, header types.Header, msgs []sdk.Msg, 97 chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, 98 ) (sdk.GasInfo, *sdk.Result, error) { 99 tx, err := GenSignedMockTx( 100 rand.New(rand.NewSource(time.Now().UnixNano())), 101 txCfg, 102 msgs, 103 sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, 104 DefaultGenTxGas, 105 chainID, 106 accNums, 107 accSeqs, 108 priv..., 109 ) 110 require.NoError(t, err) 111 txBytes, err := txCfg.TxEncoder()(tx) 112 require.Nil(t, err) 113 114 // Must simulate now as CheckTx doesn't run Msgs anymore 115 _, res, err := app.Simulate(txBytes) 116 117 if expSimPass { 118 require.NoError(t, err) 119 require.NotNil(t, res) 120 } else { 121 require.Error(t, err) 122 require.Nil(t, res) 123 } 124 125 bz, err := txCfg.TxEncoder()(tx) 126 require.NoError(t, err) 127 128 resBlock, err := app.FinalizeBlock(&types2.RequestFinalizeBlock{ 129 Height: header.Height, 130 Txs: [][]byte{bz}, 131 }) 132 require.NoError(t, err) 133 134 require.Equal(t, 1, len(resBlock.TxResults)) 135 txResult := resBlock.TxResults[0] 136 finalizeSuccess := txResult.Code == 0 137 if expPass { 138 require.True(t, finalizeSuccess) 139 } else { 140 require.False(t, finalizeSuccess) 141 } 142 143 app.Commit() 144 145 gInfo := sdk.GasInfo{GasWanted: uint64(txResult.GasWanted), GasUsed: uint64(txResult.GasUsed)} 146 txRes := sdk.Result{Data: txResult.Data, Log: txResult.Log, Events: txResult.Events} 147 if finalizeSuccess { 148 err = nil 149 } else { 150 err = errors.ABCIError(txResult.Codespace, txResult.Code, txResult.Log) 151 } 152 153 return gInfo, &txRes, err 154 }