github.com/cosmos/cosmos-sdk@v0.50.10/client/tx/aux_builder_test.go (about)

     1  package tx_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	"github.com/cosmos/cosmos-sdk/client/tx"
     9  	"github.com/cosmos/cosmos-sdk/codec"
    10  	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    11  	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
    12  	"github.com/cosmos/cosmos-sdk/testutil/testdata"
    13  	sdk "github.com/cosmos/cosmos-sdk/types"
    14  	moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
    15  	typestx "github.com/cosmos/cosmos-sdk/types/tx"
    16  	"github.com/cosmos/cosmos-sdk/types/tx/signing"
    17  	"github.com/cosmos/cosmos-sdk/x/bank"
    18  	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
    19  )
    20  
    21  const (
    22  	memo          = "waboom"
    23  	timeoutHeight = uint64(5)
    24  )
    25  
    26  var (
    27  	_, pub1, addr1 = testdata.KeyTestPubAddr()
    28  	_, _, addr2    = testdata.KeyTestPubAddr()
    29  	rawSig         = []byte("dummy")
    30  	msg1           = banktypes.NewMsgSend(addr1, addr2, sdk.NewCoins(sdk.NewInt64Coin("wack", 2)))
    31  
    32  	chainID = "test-chain"
    33  )
    34  
    35  func TestAuxTxBuilder(t *testing.T) {
    36  	bankModule := bank.AppModuleBasic{}
    37  	cdc := moduletestutil.MakeTestEncodingConfig(bankModule).Codec
    38  	reg := codectypes.NewInterfaceRegistry()
    39  
    40  	testdata.RegisterInterfaces(reg)
    41  	// required for test case: "GetAuxSignerData works for DIRECT_AUX"
    42  	bankModule.RegisterInterfaces(reg)
    43  
    44  	var b tx.AuxTxBuilder
    45  
    46  	testcases := []struct {
    47  		name      string
    48  		malleate  func() error
    49  		expErr    bool
    50  		expErrStr string
    51  	}{
    52  		{
    53  			"cannot set SIGN_MODE_DIRECT",
    54  			func() error {
    55  				return b.SetSignMode(signing.SignMode_SIGN_MODE_DIRECT)
    56  			},
    57  			true, "AuxTxBuilder can only sign with SIGN_MODE_DIRECT_AUX or SIGN_MODE_LEGACY_AMINO_JSON",
    58  		},
    59  		{
    60  			"cannot set invalid pubkey",
    61  			func() error {
    62  				return b.SetPubKey(cryptotypes.PubKey(nil))
    63  			},
    64  			true, "failed packing protobuf message to Any",
    65  		},
    66  		{
    67  			"cannot set invalid Msg",
    68  			func() error {
    69  				return b.SetMsgs(sdk.Msg(nil))
    70  			},
    71  			true, "failed packing protobuf message to Any",
    72  		},
    73  		{
    74  			"GetSignBytes body should not be nil",
    75  			func() error {
    76  				_, err := b.GetSignBytes()
    77  				return err
    78  			},
    79  			true, "aux tx is nil, call setters on AuxTxBuilder first",
    80  		},
    81  		{
    82  			"GetSignBytes pubkey should not be nil",
    83  			func() error {
    84  				require.NoError(t, b.SetMsgs(msg1))
    85  
    86  				_, err := b.GetSignBytes()
    87  				return err
    88  			},
    89  			true, "public key cannot be empty: invalid pubkey",
    90  		},
    91  		{
    92  			"GetSignBytes invalid sign mode",
    93  			func() error {
    94  				require.NoError(t, b.SetMsgs(msg1))
    95  				require.NoError(t, b.SetPubKey(pub1))
    96  
    97  				_, err := b.GetSignBytes()
    98  				return err
    99  			},
   100  			true, "got unknown sign mode SIGN_MODE_UNSPECIFIED",
   101  		},
   102  		{
   103  			"GetSignBytes works for DIRECT_AUX",
   104  			func() error {
   105  				require.NoError(t, b.SetMsgs(msg1))
   106  				require.NoError(t, b.SetPubKey(pub1))
   107  				require.NoError(t, b.SetSignMode(signing.SignMode_SIGN_MODE_DIRECT_AUX))
   108  
   109  				_, err := b.GetSignBytes()
   110  				return err
   111  			},
   112  			false, "",
   113  		},
   114  		{
   115  			"GetAuxSignerData address should not be empty",
   116  			func() error {
   117  				require.NoError(t, b.SetMsgs(msg1))
   118  				require.NoError(t, b.SetPubKey(pub1))
   119  				require.NoError(t, b.SetSignMode(signing.SignMode_SIGN_MODE_DIRECT_AUX))
   120  
   121  				_, err := b.GetSignBytes()
   122  				require.NoError(t, err)
   123  
   124  				_, err = b.GetAuxSignerData()
   125  				return err
   126  			},
   127  			true, "address cannot be empty: invalid request",
   128  		},
   129  		{
   130  			"GetAuxSignerData signature should not be empty",
   131  			func() error {
   132  				require.NoError(t, b.SetMsgs(msg1))
   133  				require.NoError(t, b.SetPubKey(pub1))
   134  				b.SetAddress(addr1.String())
   135  				require.NoError(t, b.SetSignMode(signing.SignMode_SIGN_MODE_DIRECT_AUX))
   136  
   137  				_, err := b.GetSignBytes()
   138  				require.NoError(t, err)
   139  
   140  				_, err = b.GetAuxSignerData()
   141  				return err
   142  			},
   143  			true, "signature cannot be empty: no signatures supplied",
   144  		},
   145  		{
   146  			"GetAuxSignerData works for DIRECT_AUX",
   147  			func() error {
   148  				b.SetAccountNumber(1)
   149  				b.SetSequence(2)
   150  				b.SetTimeoutHeight(timeoutHeight)
   151  				b.SetMemo(memo)
   152  				b.SetChainID(chainID)
   153  				require.NoError(t, b.SetMsgs(msg1))
   154  				require.NoError(t, b.SetPubKey(pub1))
   155  				b.SetAddress(addr1.String())
   156  				err := b.SetSignMode(signing.SignMode_SIGN_MODE_DIRECT_AUX)
   157  				require.NoError(t, err)
   158  
   159  				_, err = b.GetSignBytes()
   160  				require.NoError(t, err)
   161  				b.SetSignature(rawSig)
   162  
   163  				auxSignerData, err := b.GetAuxSignerData()
   164  
   165  				// Make sure auxSignerData is correctly populated
   166  				checkCorrectData(t, cdc, auxSignerData, signing.SignMode_SIGN_MODE_DIRECT_AUX)
   167  
   168  				return err
   169  			},
   170  			false, "",
   171  		},
   172  		{
   173  			"GetSignBytes works for LEGACY_AMINO_JSON",
   174  			func() error {
   175  				require.NoError(t, b.SetMsgs(msg1))
   176  				require.NoError(t, b.SetPubKey(pub1))
   177  				b.SetAddress(addr1.String())
   178  				err := b.SetSignMode(signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   179  				require.NoError(t, err)
   180  
   181  				_, err = b.GetSignBytes()
   182  				return err
   183  			},
   184  			false, "",
   185  		},
   186  		{
   187  			"GetAuxSignerData works for LEGACY_AMINO_JSON",
   188  			func() error {
   189  				b.SetAccountNumber(1)
   190  				b.SetSequence(2)
   191  				b.SetTimeoutHeight(timeoutHeight)
   192  				b.SetMemo(memo)
   193  				b.SetChainID(chainID)
   194  				require.NoError(t, b.SetMsgs(msg1))
   195  				require.NoError(t, b.SetPubKey(pub1))
   196  				b.SetAddress(addr1.String())
   197  				err := b.SetSignMode(signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   198  				require.NoError(t, err)
   199  
   200  				_, err = b.GetSignBytes()
   201  				require.NoError(t, err)
   202  				b.SetSignature(rawSig)
   203  
   204  				auxSignerData, err := b.GetAuxSignerData()
   205  
   206  				// Make sure auxSignerData is correctly populated
   207  				checkCorrectData(t, cdc, auxSignerData, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
   208  
   209  				return err
   210  			},
   211  			false, "",
   212  		},
   213  	}
   214  
   215  	for _, tc := range testcases {
   216  		tc := tc
   217  		t.Run(tc.name, func(t *testing.T) {
   218  			b = tx.NewAuxTxBuilder()
   219  			err := tc.malleate()
   220  
   221  			if tc.expErr {
   222  				require.Error(t, err)
   223  				require.Contains(t, err.Error(), tc.expErrStr)
   224  			} else {
   225  				require.NoError(t, err)
   226  			}
   227  		})
   228  	}
   229  }
   230  
   231  // checkCorrectData that the auxSignerData's content matches the inputs we gave.
   232  func checkCorrectData(t *testing.T, cdc codec.Codec, auxSignerData typestx.AuxSignerData, signMode signing.SignMode) {
   233  	pkAny, err := codectypes.NewAnyWithValue(pub1)
   234  	require.NoError(t, err)
   235  	msgAny, err := codectypes.NewAnyWithValue(msg1)
   236  	require.NoError(t, err)
   237  
   238  	var body typestx.TxBody
   239  	err = cdc.Unmarshal(auxSignerData.SignDoc.BodyBytes, &body)
   240  	require.NoError(t, err)
   241  
   242  	require.Equal(t, uint64(1), auxSignerData.SignDoc.AccountNumber)
   243  	require.Equal(t, uint64(2), auxSignerData.SignDoc.Sequence)
   244  	require.Equal(t, timeoutHeight, body.TimeoutHeight)
   245  	require.Equal(t, memo, body.Memo)
   246  	require.Equal(t, chainID, auxSignerData.SignDoc.ChainId)
   247  	require.Equal(t, msgAny, body.GetMessages()[0])
   248  	require.Equal(t, pkAny, auxSignerData.SignDoc.PublicKey)
   249  	require.Equal(t, signMode, auxSignerData.Mode)
   250  	require.Equal(t, rawSig, auxSignerData.Sig)
   251  }