github.com/Finschia/finschia-sdk@v0.49.1/x/auth/legacy/legacytx/stdtx_test.go (about)

     1  package legacytx
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/Finschia/ostracon/libs/log"
     8  	"github.com/stretchr/testify/require"
     9  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    10  
    11  	"github.com/Finschia/finschia-sdk/codec"
    12  	cryptocodec "github.com/Finschia/finschia-sdk/crypto/codec"
    13  	"github.com/Finschia/finschia-sdk/crypto/keys/ed25519"
    14  	kmultisig "github.com/Finschia/finschia-sdk/crypto/keys/multisig"
    15  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
    16  	"github.com/Finschia/finschia-sdk/testutil/testdata"
    17  	sdk "github.com/Finschia/finschia-sdk/types"
    18  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    19  	"github.com/Finschia/finschia-sdk/types/tx/signing"
    20  )
    21  
    22  var (
    23  	priv = ed25519.GenPrivKey()
    24  	addr = sdk.AccAddress(priv.PubKey().Address())
    25  )
    26  
    27  func init() {
    28  	amino := codec.NewLegacyAmino()
    29  	RegisterLegacyAminoCodec(amino)
    30  }
    31  
    32  // Deprecated: use fee amount and gas limit separately on TxBuilder.
    33  func NewTestStdFee() StdFee {
    34  	return NewStdFee(100000,
    35  		sdk.NewCoins(sdk.NewInt64Coin("atom", 150)),
    36  	)
    37  }
    38  
    39  // Deprecated: use TxBuilder.
    40  func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []cryptotypes.PrivKey, accNums, seqs []uint64, timeout uint64, fee StdFee) sdk.Tx {
    41  	sigs := make([]StdSignature, len(privs))
    42  	for i, priv := range privs {
    43  		signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], timeout, fee, msgs, "")
    44  
    45  		sig, err := priv.Sign(signBytes)
    46  		if err != nil {
    47  			panic(err)
    48  		}
    49  
    50  		sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
    51  	}
    52  
    53  	tx := NewStdTx(msgs, fee, sigs, "")
    54  	return tx
    55  }
    56  
    57  func TestStdTx(t *testing.T) {
    58  	msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
    59  	fee := NewTestStdFee()
    60  	sigs := []StdSignature{}
    61  
    62  	tx := NewStdTx(msgs, fee, sigs, "")
    63  	require.Equal(t, msgs, tx.GetMsgs())
    64  	require.Equal(t, sigs, tx.Signatures)
    65  
    66  	feePayer := tx.GetSigners()[0]
    67  	require.Equal(t, addr, feePayer)
    68  
    69  	feeGranter := tx.FeeGranter()
    70  	require.Empty(t, feeGranter)
    71  }
    72  
    73  func TestStdSignBytes(t *testing.T) {
    74  	type args struct {
    75  		chainID       string
    76  		accnum        uint64
    77  		sequence      uint64
    78  		timeoutHeight uint64
    79  		fee           StdFee
    80  		msgs          []sdk.Msg
    81  		memo          string
    82  	}
    83  	defaultFee := NewTestStdFee()
    84  	tests := []struct {
    85  		args args
    86  		want string
    87  	}{
    88  		{
    89  			args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"},
    90  			fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\",\"timeout_height\":\"10\"}", addr),
    91  		},
    92  		{
    93  			args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"},
    94  			fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\"}", addr),
    95  		},
    96  	}
    97  	for i, tc := range tests {
    98  		got := string(StdSignBytes(tc.args.chainID, tc.args.accnum, tc.args.sequence, tc.args.timeoutHeight, tc.args.fee, tc.args.msgs, tc.args.memo))
    99  		require.Equal(t, tc.want, got, "Got unexpected result on test case i: %d", i)
   100  	}
   101  }
   102  
   103  func TestTxValidateBasic(t *testing.T) {
   104  	ctx := sdk.NewContext(nil, tmproto.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
   105  
   106  	// keys and addresses
   107  	priv1, _, addr1 := testdata.KeyTestPubAddr()
   108  	priv2, _, addr2 := testdata.KeyTestPubAddr()
   109  
   110  	// msg and signatures
   111  	msg1 := testdata.NewTestMsg(addr1, addr2)
   112  	fee := NewTestStdFee()
   113  
   114  	msgs := []sdk.Msg{msg1}
   115  
   116  	// require to fail validation upon invalid fee
   117  	badFee := NewTestStdFee()
   118  	badFee.Amount[0].Amount = sdk.NewInt(-5)
   119  	tx := NewTestTx(ctx, nil, nil, nil, nil, 0, badFee)
   120  
   121  	err := tx.ValidateBasic()
   122  	require.Error(t, err)
   123  	_, code, _ := sdkerrors.ABCIInfo(err, false)
   124  	require.Equal(t, sdkerrors.ErrInsufficientFee.ABCICode(), code)
   125  
   126  	// require to fail validation when no signatures exist
   127  	privs, accNums, seqs := []cryptotypes.PrivKey{}, []uint64{}, []uint64{}
   128  	tx = NewTestTx(ctx, msgs, privs, accNums, seqs, 0, fee)
   129  
   130  	err = tx.ValidateBasic()
   131  	require.Error(t, err)
   132  	_, code, _ = sdkerrors.ABCIInfo(err, false)
   133  	require.Equal(t, sdkerrors.ErrNoSignatures.ABCICode(), code)
   134  
   135  	// require to fail validation when signatures do not match expected signers
   136  	privs, accNums, seqs = []cryptotypes.PrivKey{priv1}, []uint64{0, 1}, []uint64{0, 0}
   137  	tx = NewTestTx(ctx, msgs, privs, accNums, seqs, 0, fee)
   138  
   139  	err = tx.ValidateBasic()
   140  	require.Error(t, err)
   141  	_, code, _ = sdkerrors.ABCIInfo(err, false)
   142  	require.Equal(t, sdkerrors.ErrUnauthorized.ABCICode(), code)
   143  
   144  	// require to fail with invalid gas supplied
   145  	badFee = NewTestStdFee()
   146  	badFee.Gas = 9223372036854775808
   147  	tx = NewTestTx(ctx, nil, nil, nil, nil, 0, badFee)
   148  
   149  	err = tx.ValidateBasic()
   150  	require.Error(t, err)
   151  	_, code, _ = sdkerrors.ABCIInfo(err, false)
   152  	require.Equal(t, sdkerrors.ErrInvalidRequest.ABCICode(), code)
   153  
   154  	// require to pass when above criteria are matched
   155  	privs, accNums, seqs = []cryptotypes.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}
   156  	tx = NewTestTx(ctx, msgs, privs, accNums, seqs, 0, fee)
   157  
   158  	err = tx.ValidateBasic()
   159  	require.NoError(t, err)
   160  }
   161  
   162  func TestDefaultTxEncoder(t *testing.T) {
   163  	cdc := codec.NewLegacyAmino()
   164  	sdk.RegisterLegacyAminoCodec(cdc)
   165  	cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
   166  	encoder := DefaultTxEncoder(cdc)
   167  
   168  	msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
   169  	fee := NewTestStdFee()
   170  	sigs := []StdSignature{}
   171  
   172  	tx := NewStdTx(msgs, fee, sigs, "")
   173  
   174  	cdcBytes, err := cdc.Marshal(tx)
   175  
   176  	require.NoError(t, err)
   177  	encoderBytes, err := encoder(tx)
   178  
   179  	require.NoError(t, err)
   180  	require.Equal(t, cdcBytes, encoderBytes)
   181  }
   182  
   183  func TestSignatureV2Conversions(t *testing.T) {
   184  	_, pubKey, _ := testdata.KeyTestPubAddr()
   185  	cdc := codec.NewLegacyAmino()
   186  	sdk.RegisterLegacyAminoCodec(cdc)
   187  	dummy := []byte("dummySig")
   188  	sig := StdSignature{PubKey: pubKey, Signature: dummy}
   189  
   190  	sigV2, err := StdSignatureToSignatureV2(cdc, sig)
   191  	require.NoError(t, err)
   192  	require.Equal(t, pubKey, sigV2.PubKey)
   193  	require.Equal(t, &signing.SingleSignatureData{
   194  		SignMode:  signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
   195  		Signature: dummy,
   196  	}, sigV2.Data)
   197  
   198  	sigBz, err := SignatureDataToAminoSignature(cdc, sigV2.Data)
   199  	require.NoError(t, err)
   200  	require.Equal(t, dummy, sigBz)
   201  
   202  	// multisigs
   203  	_, pubKey2, _ := testdata.KeyTestPubAddr()
   204  	multiPK := kmultisig.NewLegacyAminoPubKey(1, []cryptotypes.PubKey{
   205  		pubKey, pubKey2,
   206  	})
   207  	dummy2 := []byte("dummySig2")
   208  	bitArray := cryptotypes.NewCompactBitArray(2)
   209  	bitArray.SetIndex(0, true)
   210  	bitArray.SetIndex(1, true)
   211  	msigData := &signing.MultiSignatureData{
   212  		BitArray: bitArray,
   213  		Signatures: []signing.SignatureData{
   214  			&signing.SingleSignatureData{
   215  				SignMode:  signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
   216  				Signature: dummy,
   217  			},
   218  			&signing.SingleSignatureData{
   219  				SignMode:  signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
   220  				Signature: dummy2,
   221  			},
   222  		},
   223  	}
   224  
   225  	msig, err := SignatureDataToAminoSignature(cdc, msigData)
   226  	require.NoError(t, err)
   227  
   228  	sigV2, err = StdSignatureToSignatureV2(cdc, StdSignature{
   229  		PubKey:    multiPK,
   230  		Signature: msig,
   231  	})
   232  	require.NoError(t, err)
   233  	require.Equal(t, multiPK, sigV2.PubKey)
   234  	require.Equal(t, msigData, sigV2.Data)
   235  }
   236  
   237  func TestGetSignaturesV2(t *testing.T) {
   238  	_, pubKey, _ := testdata.KeyTestPubAddr()
   239  	dummy := []byte("dummySig")
   240  
   241  	cdc := codec.NewLegacyAmino()
   242  	sdk.RegisterLegacyAminoCodec(cdc)
   243  	cryptocodec.RegisterCrypto(cdc)
   244  
   245  	fee := NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)})
   246  	sig := StdSignature{PubKey: pubKey, Signature: dummy}
   247  	stdTx := NewStdTx([]sdk.Msg{testdata.NewTestMsg()}, fee, []StdSignature{sig}, "testsigs")
   248  
   249  	sigs, err := stdTx.GetSignaturesV2()
   250  	require.Nil(t, err)
   251  	require.Equal(t, len(sigs), 1)
   252  
   253  	require.Equal(t, cdc.MustMarshal(sigs[0].PubKey), cdc.MustMarshal(sig.GetPubKey()))
   254  	require.Equal(t, sigs[0].Data, &signing.SingleSignatureData{
   255  		SignMode:  signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
   256  		Signature: sig.GetSignature(),
   257  	})
   258  }