github.com/cosmos/cosmos-sdk@v0.50.10/x/auth/tx/testutil/suite.go (about) 1 package testutil 2 3 import ( 4 "bytes" 5 "context" 6 7 "github.com/stretchr/testify/suite" 8 9 signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" 10 11 "github.com/cosmos/cosmos-sdk/client" 12 kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" 13 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 14 "github.com/cosmos/cosmos-sdk/crypto/types/multisig" 15 "github.com/cosmos/cosmos-sdk/testutil/testdata" 16 sdk "github.com/cosmos/cosmos-sdk/types" 17 signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" 18 "github.com/cosmos/cosmos-sdk/x/auth/signing" 19 ) 20 21 // TxConfigTestSuite provides a test suite that can be used to test that a TxConfig implementation is correct. 22 type TxConfigTestSuite struct { 23 suite.Suite 24 TxConfig client.TxConfig 25 } 26 27 // NewTxConfigTestSuite returns a new TxConfigTestSuite with the provided TxConfig implementation 28 func NewTxConfigTestSuite(txConfig client.TxConfig) *TxConfigTestSuite { 29 return &TxConfigTestSuite{TxConfig: txConfig} 30 } 31 32 func (s *TxConfigTestSuite) TestTxBuilderGetTx() { 33 txBuilder := s.TxConfig.NewTxBuilder() 34 tx := txBuilder.GetTx() 35 s.Require().NotNil(tx) 36 s.Require().Equal(len(tx.GetMsgs()), 0) 37 } 38 39 func (s *TxConfigTestSuite) TestTxBuilderSetFeeAmount() { 40 txBuilder := s.TxConfig.NewTxBuilder() 41 feeAmount := sdk.Coins{ 42 sdk.NewInt64Coin("atom", 20000000), 43 } 44 txBuilder.SetFeeAmount(feeAmount) 45 feeTx := txBuilder.GetTx() 46 s.Require().Equal(feeAmount, feeTx.GetFee()) 47 } 48 49 func (s *TxConfigTestSuite) TestTxBuilderSetGasLimit() { 50 const newGas uint64 = 300000 51 txBuilder := s.TxConfig.NewTxBuilder() 52 txBuilder.SetGasLimit(newGas) 53 feeTx := txBuilder.GetTx() 54 s.Require().Equal(newGas, feeTx.GetGas()) 55 } 56 57 func (s *TxConfigTestSuite) TestTxBuilderSetMemo() { 58 const newMemo string = "newfoomemo" 59 txBuilder := s.TxConfig.NewTxBuilder() 60 txBuilder.SetMemo(newMemo) 61 txWithMemo := txBuilder.GetTx() 62 s.Require().Equal(txWithMemo.GetMemo(), newMemo) 63 } 64 65 func (s *TxConfigTestSuite) TestTxBuilderSetMsgs() { 66 _, _, addr1 := testdata.KeyTestPubAddr() 67 _, _, addr2 := testdata.KeyTestPubAddr() 68 msg1 := testdata.NewTestMsg(addr1) 69 msg2 := testdata.NewTestMsg(addr2) 70 msgs := []sdk.Msg{msg1, msg2} 71 72 txBuilder := s.TxConfig.NewTxBuilder() 73 74 err := txBuilder.SetMsgs(msgs...) 75 s.Require().NoError(err) 76 tx := txBuilder.GetTx() 77 s.Require().Equal(msgs, tx.GetMsgs()) 78 signers, err := tx.GetSigners() 79 s.Require().NoError(err) 80 s.Require().Equal([][]byte{addr1, addr2}, signers) 81 s.Require().Equal([]byte(addr1), tx.FeePayer()) 82 s.Require().Error(tx.ValidateBasic()) // should fail because of no signatures 83 } 84 85 func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { 86 privKey, pubkey, addr := testdata.KeyTestPubAddr() 87 privKey2, pubkey2, _ := testdata.KeyTestPubAddr() 88 multisigPk := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{pubkey, pubkey2}) 89 90 txBuilder := s.TxConfig.NewTxBuilder() 91 92 // set test msg 93 msg := testdata.NewTestMsg(addr) 94 msigAddr := sdk.AccAddress(multisigPk.Address()) 95 msg2 := testdata.NewTestMsg(msigAddr) 96 err := txBuilder.SetMsgs(msg, msg2) 97 txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) 98 s.Require().NoError(err) 99 100 // check that validation fails 101 s.Require().Error(txBuilder.GetTx().ValidateBasic()) 102 103 signModeHandler := s.TxConfig.SignModeHandler() 104 s.Require().Contains(signModeHandler.SupportedModes(), signingv1beta1.SignMode_SIGN_MODE_DIRECT) 105 defaultSignMode, err := signing.APISignModeToInternal(s.TxConfig.SignModeHandler().DefaultMode()) 106 s.Require().NoError(err) 107 108 // set SignatureV2 without actual signature bytes 109 seq1 := uint64(2) // Arbitrary account sequence 110 sigData1 := &signingtypes.SingleSignatureData{SignMode: defaultSignMode} 111 sig1 := signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1, Sequence: seq1} 112 113 mseq := uint64(4) // Arbitrary account sequence 114 msigData := multisig.NewMultisig(2) 115 multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: defaultSignMode}, 0) 116 multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: defaultSignMode}, 1) 117 msig := signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData, Sequence: mseq} 118 119 // fail validation without required signers 120 err = txBuilder.SetSignatures(sig1) 121 s.Require().NoError(err) 122 sigTx := txBuilder.GetTx() 123 s.Require().Error(sigTx.ValidateBasic()) 124 125 err = txBuilder.SetSignatures(sig1, msig) 126 s.Require().NoError(err) 127 sigTx = txBuilder.GetTx() 128 sigsV2, err := sigTx.GetSignaturesV2() 129 s.Require().NoError(err) 130 s.Require().Len(sigsV2, 2) 131 s.Require().True(sigEquals(sig1, sigsV2[0])) 132 s.Require().True(sigEquals(msig, sigsV2[1])) 133 signers, err := sigTx.GetSigners() 134 s.Require().NoError(err) 135 s.Require().Equal([][]byte{addr, msigAddr}, signers) 136 s.Require().NoError(sigTx.ValidateBasic()) 137 138 // sign transaction 139 signerData := signing.SignerData{ 140 Address: addr.String(), 141 ChainID: "test", 142 AccountNumber: 1, 143 Sequence: seq1, 144 PubKey: pubkey, 145 } 146 signBytes, err := signing.GetSignBytesAdapter(context.Background(), 147 s.TxConfig.SignModeHandler(), defaultSignMode, signerData, sigTx) 148 s.Require().NoError(err) 149 sigBz, err := privKey.Sign(signBytes) 150 s.Require().NoError(err) 151 152 signerData = signing.SignerData{ 153 Address: msigAddr.String(), 154 ChainID: "test", 155 AccountNumber: 3, 156 Sequence: mseq, 157 PubKey: multisigPk, 158 } 159 mSignBytes, err := signing.GetSignBytesAdapter(context.Background(), 160 s.TxConfig.SignModeHandler(), defaultSignMode, signerData, sigTx) 161 s.Require().NoError(err) 162 mSigBz1, err := privKey.Sign(mSignBytes) 163 s.Require().NoError(err) 164 mSigBz2, err := privKey2.Sign(mSignBytes) 165 s.Require().NoError(err) 166 msigData = multisig.NewMultisig(2) 167 multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{ 168 SignMode: defaultSignMode, Signature: mSigBz1, 169 }, 0) 170 multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{ 171 SignMode: defaultSignMode, Signature: mSigBz2, 172 }, 0) 173 174 // set signature 175 sigData1.Signature = sigBz 176 sig1 = signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1, Sequence: seq1} 177 msig = signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData, Sequence: mseq} 178 err = txBuilder.SetSignatures(sig1, msig) 179 s.Require().NoError(err) 180 sigTx = txBuilder.GetTx() 181 sigsV2, err = sigTx.GetSignaturesV2() 182 s.Require().NoError(err) 183 s.Require().Len(sigsV2, 2) 184 s.Require().True(sigEquals(sig1, sigsV2[0])) 185 s.Require().True(sigEquals(msig, sigsV2[1])) 186 signers, err = sigTx.GetSigners() 187 s.Require().NoError(err) 188 s.Require().Equal([][]byte{addr, msigAddr}, signers) 189 s.Require().NoError(sigTx.ValidateBasic()) 190 } 191 192 func sigEquals(sig1, sig2 signingtypes.SignatureV2) bool { 193 if !sig1.PubKey.Equals(sig2.PubKey) { 194 return false 195 } 196 197 if sig1.Data == nil && sig2.Data == nil { 198 return true 199 } 200 201 return sigDataEquals(sig1.Data, sig2.Data) 202 } 203 204 func sigDataEquals(data1, data2 signingtypes.SignatureData) bool { 205 switch data1 := data1.(type) { 206 case *signingtypes.SingleSignatureData: 207 data2, ok := data2.(*signingtypes.SingleSignatureData) 208 if !ok { 209 return false 210 } 211 212 if data1.SignMode != data2.SignMode { 213 return false 214 } 215 216 return bytes.Equal(data1.Signature, data2.Signature) 217 case *signingtypes.MultiSignatureData: 218 data2, ok := data2.(*signingtypes.MultiSignatureData) 219 if !ok { 220 return false 221 } 222 if !data1.BitArray.Equal(data2.BitArray) || len(data1.Signatures) != len(data2.Signatures) { 223 return false 224 } 225 226 for i, s := range data1.Signatures { 227 if !sigDataEquals(s, data2.Signatures[i]) { 228 return false 229 } 230 } 231 232 return true 233 default: 234 return false 235 } 236 } 237 238 func (s *TxConfigTestSuite) TestTxEncodeDecode() { 239 log := s.T().Log 240 _, pubkey, addr := testdata.KeyTestPubAddr() 241 feeAmount := sdk.Coins{sdk.NewInt64Coin("atom", 150)} 242 gasLimit := uint64(50000) 243 memo := "foomemo" 244 msg := testdata.NewTestMsg(addr) 245 dummySig := []byte("dummySig") 246 sig := signingtypes.SignatureV2{ 247 PubKey: pubkey, 248 Data: &signingtypes.SingleSignatureData{ 249 SignMode: signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, 250 Signature: dummySig, 251 }, 252 } 253 254 txBuilder := s.TxConfig.NewTxBuilder() 255 txBuilder.SetFeeAmount(feeAmount) 256 txBuilder.SetGasLimit(gasLimit) 257 txBuilder.SetMemo(memo) 258 err := txBuilder.SetMsgs(msg) 259 s.Require().NoError(err) 260 err = txBuilder.SetSignatures(sig) 261 s.Require().NoError(err) 262 tx := txBuilder.GetTx() 263 264 log("encode transaction") 265 txBytes, err := s.TxConfig.TxEncoder()(tx) 266 s.Require().NoError(err) 267 s.Require().NotNil(txBytes) 268 log("decode transaction", s.TxConfig) 269 tx2, err := s.TxConfig.TxDecoder()(txBytes) 270 271 s.Require().NoError(err) 272 tx3, ok := tx2.(signing.Tx) 273 s.Require().True(ok) 274 s.Require().Equal([]sdk.Msg{msg}, tx3.GetMsgs()) 275 s.Require().Equal(feeAmount, tx3.GetFee()) 276 s.Require().Equal(gasLimit, tx3.GetGas()) 277 s.Require().Equal(memo, tx3.GetMemo()) 278 tx3Sigs, err := tx3.GetSignaturesV2() 279 s.Require().NoError(err) 280 s.Require().Equal([]signingtypes.SignatureV2{sig}, tx3Sigs) 281 pks, err := tx3.GetPubKeys() 282 s.Require().NoError(err) 283 s.Require().Equal([]cryptotypes.PubKey{pubkey}, pks) 284 285 log("JSON encode transaction") 286 jsonTxBytes, err := s.TxConfig.TxJSONEncoder()(tx) 287 s.Require().NoError(err) 288 s.Require().NotNil(jsonTxBytes) 289 290 log("JSON decode transaction") 291 tx2, err = s.TxConfig.TxJSONDecoder()(jsonTxBytes) 292 s.Require().NoError(err) 293 tx3, ok = tx2.(signing.Tx) 294 s.Require().True(ok) 295 s.Require().Equal([]sdk.Msg{msg}, tx3.GetMsgs()) 296 s.Require().Equal(feeAmount, tx3.GetFee()) 297 s.Require().Equal(gasLimit, tx3.GetGas()) 298 s.Require().Equal(memo, tx3.GetMemo()) 299 tx3Sigs, err = tx3.GetSignaturesV2() 300 s.Require().NoError(err) 301 s.Require().Equal([]signingtypes.SignatureV2{sig}, tx3Sigs) 302 pks, err = tx3.GetPubKeys() 303 s.Require().NoError(err) 304 s.Require().Equal([]cryptotypes.PubKey{pubkey}, pks) 305 } 306 307 func (s *TxConfigTestSuite) TestWrapTxBuilder() { 308 _, _, addr := testdata.KeyTestPubAddr() 309 feeAmount := sdk.Coins{sdk.NewInt64Coin("atom", 150)} 310 gasLimit := uint64(50000) 311 memo := "foomemo" 312 msg := testdata.NewTestMsg(addr) 313 314 txBuilder := s.TxConfig.NewTxBuilder() 315 txBuilder.SetFeeAmount(feeAmount) 316 txBuilder.SetGasLimit(gasLimit) 317 txBuilder.SetMemo(memo) 318 err := txBuilder.SetMsgs(msg) 319 s.Require().NoError(err) 320 321 newTxBldr, err := s.TxConfig.WrapTxBuilder(txBuilder.GetTx()) 322 s.Require().NoError(err) 323 s.Require().Equal(txBuilder, newTxBldr) 324 }