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

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