github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/txs/export_tx_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package txs
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/MetalBlockchain/metalgo/ids"
    12  	"github.com/MetalBlockchain/metalgo/utils/crypto/secp256k1"
    13  	"github.com/MetalBlockchain/metalgo/vms/avm/fxs"
    14  	"github.com/MetalBlockchain/metalgo/vms/components/avax"
    15  	"github.com/MetalBlockchain/metalgo/vms/components/verify"
    16  	"github.com/MetalBlockchain/metalgo/vms/secp256k1fx"
    17  )
    18  
    19  func TestExportTxSerialization(t *testing.T) {
    20  	require := require.New(t)
    21  
    22  	expected := []byte{
    23  		// Codec version:
    24  		0x00, 0x00,
    25  		// txID:
    26  		0x00, 0x00, 0x00, 0x04,
    27  		// networkID:
    28  		0x00, 0x00, 0x00, 0x02,
    29  		// blockchainID:
    30  		0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee,
    31  		0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc,
    32  		0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa,
    33  		0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88,
    34  		// number of outs:
    35  		0x00, 0x00, 0x00, 0x00,
    36  		// number of inputs:
    37  		0x00, 0x00, 0x00, 0x01,
    38  		// utxoID:
    39  		0x0f, 0x2f, 0x4f, 0x6f, 0x8e, 0xae, 0xce, 0xee,
    40  		0x0d, 0x2d, 0x4d, 0x6d, 0x8c, 0xac, 0xcc, 0xec,
    41  		0x0b, 0x2b, 0x4b, 0x6b, 0x8a, 0xaa, 0xca, 0xea,
    42  		0x09, 0x29, 0x49, 0x69, 0x88, 0xa8, 0xc8, 0xe8,
    43  		// output index
    44  		0x00, 0x00, 0x00, 0x00,
    45  		// assetID:
    46  		0x1f, 0x3f, 0x5f, 0x7f, 0x9e, 0xbe, 0xde, 0xfe,
    47  		0x1d, 0x3d, 0x5d, 0x7d, 0x9c, 0xbc, 0xdc, 0xfc,
    48  		0x1b, 0x3b, 0x5b, 0x7b, 0x9a, 0xba, 0xda, 0xfa,
    49  		0x19, 0x39, 0x59, 0x79, 0x98, 0xb8, 0xd8, 0xf8,
    50  		// input:
    51  		// input ID:
    52  		0x00, 0x00, 0x00, 0x05,
    53  		// amount:
    54  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
    55  		// num sig indices:
    56  		0x00, 0x00, 0x00, 0x01,
    57  		// sig index[0]:
    58  		0x00, 0x00, 0x00, 0x00,
    59  		// Memo length:
    60  		0x00, 0x00, 0x00, 0x04,
    61  		// Memo:
    62  		0x00, 0x01, 0x02, 0x03,
    63  		// Destination Chain ID:
    64  		0x1f, 0x8f, 0x9f, 0x0f, 0x1e, 0x8e, 0x9e, 0x0e,
    65  		0x2d, 0x7d, 0xad, 0xfd, 0x2c, 0x7c, 0xac, 0xfc,
    66  		0x3b, 0x6b, 0xbb, 0xeb, 0x3a, 0x6a, 0xba, 0xea,
    67  		0x49, 0x59, 0xc9, 0xd9, 0x48, 0x58, 0xc8, 0xd8,
    68  		// number of exported outs:
    69  		0x00, 0x00, 0x00, 0x00,
    70  		// number of credentials:
    71  		0x00, 0x00, 0x00, 0x00,
    72  	}
    73  
    74  	tx := &Tx{Unsigned: &ExportTx{
    75  		BaseTx: BaseTx{BaseTx: avax.BaseTx{
    76  			NetworkID: 2,
    77  			BlockchainID: ids.ID{
    78  				0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee,
    79  				0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc,
    80  				0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa,
    81  				0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88,
    82  			},
    83  			Ins: []*avax.TransferableInput{{
    84  				UTXOID: avax.UTXOID{TxID: ids.ID{
    85  					0x0f, 0x2f, 0x4f, 0x6f, 0x8e, 0xae, 0xce, 0xee,
    86  					0x0d, 0x2d, 0x4d, 0x6d, 0x8c, 0xac, 0xcc, 0xec,
    87  					0x0b, 0x2b, 0x4b, 0x6b, 0x8a, 0xaa, 0xca, 0xea,
    88  					0x09, 0x29, 0x49, 0x69, 0x88, 0xa8, 0xc8, 0xe8,
    89  				}},
    90  				Asset: avax.Asset{ID: ids.ID{
    91  					0x1f, 0x3f, 0x5f, 0x7f, 0x9e, 0xbe, 0xde, 0xfe,
    92  					0x1d, 0x3d, 0x5d, 0x7d, 0x9c, 0xbc, 0xdc, 0xfc,
    93  					0x1b, 0x3b, 0x5b, 0x7b, 0x9a, 0xba, 0xda, 0xfa,
    94  					0x19, 0x39, 0x59, 0x79, 0x98, 0xb8, 0xd8, 0xf8,
    95  				}},
    96  				In: &secp256k1fx.TransferInput{
    97  					Amt:   1000,
    98  					Input: secp256k1fx.Input{SigIndices: []uint32{0}},
    99  				},
   100  			}},
   101  			Memo: []byte{0x00, 0x01, 0x02, 0x03},
   102  		}},
   103  		DestinationChain: ids.ID{
   104  			0x1f, 0x8f, 0x9f, 0x0f, 0x1e, 0x8e, 0x9e, 0x0e,
   105  			0x2d, 0x7d, 0xad, 0xfd, 0x2c, 0x7c, 0xac, 0xfc,
   106  			0x3b, 0x6b, 0xbb, 0xeb, 0x3a, 0x6a, 0xba, 0xea,
   107  			0x49, 0x59, 0xc9, 0xd9, 0x48, 0x58, 0xc8, 0xd8,
   108  		},
   109  	}}
   110  
   111  	parser, err := NewParser(
   112  		[]fxs.Fx{
   113  			&secp256k1fx.Fx{},
   114  		},
   115  	)
   116  	require.NoError(err)
   117  
   118  	require.NoError(tx.Initialize(parser.Codec()))
   119  	require.Equal("2PKJE4TrKYpgynBFCpNPpV3GHK7d9QTgrL5mpYG6abHKDvNBG3", tx.ID().String())
   120  
   121  	result := tx.Bytes()
   122  	require.Equal(expected, result)
   123  
   124  	credBytes := []byte{
   125  		// type id
   126  		0x00, 0x00, 0x00, 0x09,
   127  
   128  		// there are two signers (thus two signatures)
   129  		0x00, 0x00, 0x00, 0x02,
   130  
   131  		// 65 bytes
   132  		0x61, 0xdd, 0x9b, 0xff, 0xc0, 0x49, 0x95, 0x6e, 0xd7, 0xf8,
   133  		0xcd, 0x92, 0xec, 0xda, 0x03, 0x6e, 0xac, 0xb8, 0x16, 0x9e,
   134  		0x53, 0x83, 0xc0, 0x3a, 0x2e, 0x88, 0x5b, 0x5f, 0xc6, 0xef,
   135  		0x2e, 0xbe, 0x50, 0x59, 0x72, 0x8d, 0x0f, 0xa6, 0x59, 0x66,
   136  		0x93, 0x28, 0x88, 0xb4, 0x56, 0x3b, 0x77, 0x7c, 0x59, 0xa5,
   137  		0x8f, 0xe0, 0x2a, 0xf3, 0xcc, 0x31, 0x32, 0xef, 0xfe, 0x7d,
   138  		0x3d, 0x9f, 0x14, 0x94, 0x01,
   139  
   140  		// 65 bytes
   141  		0x61, 0xdd, 0x9b, 0xff, 0xc0, 0x49, 0x95, 0x6e, 0xd7, 0xf8,
   142  		0xcd, 0x92, 0xec, 0xda, 0x03, 0x6e, 0xac, 0xb8, 0x16, 0x9e,
   143  		0x53, 0x83, 0xc0, 0x3a, 0x2e, 0x88, 0x5b, 0x5f, 0xc6, 0xef,
   144  		0x2e, 0xbe, 0x50, 0x59, 0x72, 0x8d, 0x0f, 0xa6, 0x59, 0x66,
   145  		0x93, 0x28, 0x88, 0xb4, 0x56, 0x3b, 0x77, 0x7c, 0x59, 0xa5,
   146  		0x8f, 0xe0, 0x2a, 0xf3, 0xcc, 0x31, 0x32, 0xef, 0xfe, 0x7d,
   147  		0x3d, 0x9f, 0x14, 0x94, 0x01,
   148  
   149  		// type id
   150  		0x00, 0x00, 0x00, 0x09,
   151  
   152  		// there are two signers (thus two signatures)
   153  		0x00, 0x00, 0x00, 0x02,
   154  
   155  		// 65 bytes
   156  		0x61, 0xdd, 0x9b, 0xff, 0xc0, 0x49, 0x95, 0x6e, 0xd7, 0xf8,
   157  		0xcd, 0x92, 0xec, 0xda, 0x03, 0x6e, 0xac, 0xb8, 0x16, 0x9e,
   158  		0x53, 0x83, 0xc0, 0x3a, 0x2e, 0x88, 0x5b, 0x5f, 0xc6, 0xef,
   159  		0x2e, 0xbe, 0x50, 0x59, 0x72, 0x8d, 0x0f, 0xa6, 0x59, 0x66,
   160  		0x93, 0x28, 0x88, 0xb4, 0x56, 0x3b, 0x77, 0x7c, 0x59, 0xa5,
   161  		0x8f, 0xe0, 0x2a, 0xf3, 0xcc, 0x31, 0x32, 0xef, 0xfe, 0x7d,
   162  		0x3d, 0x9f, 0x14, 0x94, 0x01,
   163  
   164  		// 65 bytes
   165  		0x61, 0xdd, 0x9b, 0xff, 0xc0, 0x49, 0x95, 0x6e, 0xd7, 0xf8,
   166  		0xcd, 0x92, 0xec, 0xda, 0x03, 0x6e, 0xac, 0xb8, 0x16, 0x9e,
   167  		0x53, 0x83, 0xc0, 0x3a, 0x2e, 0x88, 0x5b, 0x5f, 0xc6, 0xef,
   168  		0x2e, 0xbe, 0x50, 0x59, 0x72, 0x8d, 0x0f, 0xa6, 0x59, 0x66,
   169  		0x93, 0x28, 0x88, 0xb4, 0x56, 0x3b, 0x77, 0x7c, 0x59, 0xa5,
   170  		0x8f, 0xe0, 0x2a, 0xf3, 0xcc, 0x31, 0x32, 0xef, 0xfe, 0x7d,
   171  		0x3d, 0x9f, 0x14, 0x94, 0x01,
   172  	}
   173  	require.NoError(tx.SignSECP256K1Fx(
   174  		parser.Codec(),
   175  		[][]*secp256k1.PrivateKey{
   176  			{keys[0], keys[0]},
   177  			{keys[0], keys[0]},
   178  		},
   179  	))
   180  	require.Equal("2oG52e7Cb7XF1yUzv3pRFndAypgbpswWRcSAKD5SH5VgaiTm5D", tx.ID().String())
   181  
   182  	// there are two credentials
   183  	expected[len(expected)-1] = 0x02
   184  	expected = append(expected, credBytes...)
   185  	result = tx.Bytes()
   186  	require.Equal(expected, result)
   187  }
   188  
   189  func TestExportTxNotState(t *testing.T) {
   190  	require := require.New(t)
   191  
   192  	intf := interface{}(&ExportTx{})
   193  	_, ok := intf.(verify.State)
   194  	require.False(ok, "should not be marked as state")
   195  }