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 }