github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/txs/import_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 TestImportTxSerialization(t *testing.T) { 20 require := require.New(t) 21 22 expected := []byte{ 23 // Codec version 24 0x00, 0x00, 25 // txID: 26 0x00, 0x00, 0x00, 0x03, 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 base outs: 35 0x00, 0x00, 0x00, 0x00, 36 // number of base inputs: 37 0x00, 0x00, 0x00, 0x00, 38 // Memo length: 39 0x00, 0x00, 0x00, 0x04, 40 // Memo: 41 0x00, 0x01, 0x02, 0x03, 42 // Source Chain ID: 43 0x1f, 0x8f, 0x9f, 0x0f, 0x1e, 0x8e, 0x9e, 0x0e, 44 0x2d, 0x7d, 0xad, 0xfd, 0x2c, 0x7c, 0xac, 0xfc, 45 0x3b, 0x6b, 0xbb, 0xeb, 0x3a, 0x6a, 0xba, 0xea, 46 0x49, 0x59, 0xc9, 0xd9, 0x48, 0x58, 0xc8, 0xd8, 47 // number of inputs: 48 0x00, 0x00, 0x00, 0x01, 49 // utxoID: 50 0x0f, 0x2f, 0x4f, 0x6f, 0x8e, 0xae, 0xce, 0xee, 51 0x0d, 0x2d, 0x4d, 0x6d, 0x8c, 0xac, 0xcc, 0xec, 52 0x0b, 0x2b, 0x4b, 0x6b, 0x8a, 0xaa, 0xca, 0xea, 53 0x09, 0x29, 0x49, 0x69, 0x88, 0xa8, 0xc8, 0xe8, 54 // output index 55 0x00, 0x00, 0x00, 0x00, 56 // assetID: 57 0x1f, 0x3f, 0x5f, 0x7f, 0x9e, 0xbe, 0xde, 0xfe, 58 0x1d, 0x3d, 0x5d, 0x7d, 0x9c, 0xbc, 0xdc, 0xfc, 59 0x1b, 0x3b, 0x5b, 0x7b, 0x9a, 0xba, 0xda, 0xfa, 60 0x19, 0x39, 0x59, 0x79, 0x98, 0xb8, 0xd8, 0xf8, 61 // input: 62 // input ID: 63 0x00, 0x00, 0x00, 0x05, 64 // amount: 65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 66 // num sig indices: 67 0x00, 0x00, 0x00, 0x01, 68 // sig index[0]: 69 0x00, 0x00, 0x00, 0x00, 70 // number of credentials: 71 0x00, 0x00, 0x00, 0x00, 72 } 73 74 tx := &Tx{Unsigned: &ImportTx{ 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 Memo: []byte{0x00, 0x01, 0x02, 0x03}, 84 }}, 85 SourceChain: ids.ID{ 86 0x1f, 0x8f, 0x9f, 0x0f, 0x1e, 0x8e, 0x9e, 0x0e, 87 0x2d, 0x7d, 0xad, 0xfd, 0x2c, 0x7c, 0xac, 0xfc, 88 0x3b, 0x6b, 0xbb, 0xeb, 0x3a, 0x6a, 0xba, 0xea, 89 0x49, 0x59, 0xc9, 0xd9, 0x48, 0x58, 0xc8, 0xd8, 90 }, 91 ImportedIns: []*avax.TransferableInput{{ 92 UTXOID: avax.UTXOID{TxID: ids.ID{ 93 0x0f, 0x2f, 0x4f, 0x6f, 0x8e, 0xae, 0xce, 0xee, 94 0x0d, 0x2d, 0x4d, 0x6d, 0x8c, 0xac, 0xcc, 0xec, 95 0x0b, 0x2b, 0x4b, 0x6b, 0x8a, 0xaa, 0xca, 0xea, 96 0x09, 0x29, 0x49, 0x69, 0x88, 0xa8, 0xc8, 0xe8, 97 }}, 98 Asset: avax.Asset{ID: ids.ID{ 99 0x1f, 0x3f, 0x5f, 0x7f, 0x9e, 0xbe, 0xde, 0xfe, 100 0x1d, 0x3d, 0x5d, 0x7d, 0x9c, 0xbc, 0xdc, 0xfc, 101 0x1b, 0x3b, 0x5b, 0x7b, 0x9a, 0xba, 0xda, 0xfa, 102 0x19, 0x39, 0x59, 0x79, 0x98, 0xb8, 0xd8, 0xf8, 103 }}, 104 In: &secp256k1fx.TransferInput{ 105 Amt: 1000, 106 Input: secp256k1fx.Input{SigIndices: []uint32{0}}, 107 }, 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("9wdPb5rsThXYLX4WxkNeyYrNMfDE5cuWLgifSjxKiA2dCmgCZ", 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 0x8c, 0xc7, 0xdc, 0x8c, 0x11, 0xd3, 0x75, 0x9e, 0x16, 0xa5, 133 0x9f, 0xd2, 0x9c, 0x64, 0xd7, 0x1f, 0x9b, 0xad, 0x1a, 0x62, 134 0x33, 0x98, 0xc7, 0xaf, 0x67, 0x02, 0xc5, 0xe0, 0x75, 0x8e, 135 0x62, 0xcf, 0x15, 0x6d, 0x99, 0xf5, 0x4e, 0x71, 0xb8, 0xf4, 136 0x8b, 0x5b, 0xbf, 0x0c, 0x59, 0x62, 0x79, 0x34, 0x97, 0x1a, 137 0x1f, 0x49, 0x9b, 0x0a, 0x4f, 0xbf, 0x95, 0xfc, 0x31, 0x39, 138 0x46, 0x4e, 0xa1, 0xaf, 0x00, 139 140 // 65 bytes 141 0x8c, 0xc7, 0xdc, 0x8c, 0x11, 0xd3, 0x75, 0x9e, 0x16, 0xa5, 142 0x9f, 0xd2, 0x9c, 0x64, 0xd7, 0x1f, 0x9b, 0xad, 0x1a, 0x62, 143 0x33, 0x98, 0xc7, 0xaf, 0x67, 0x02, 0xc5, 0xe0, 0x75, 0x8e, 144 0x62, 0xcf, 0x15, 0x6d, 0x99, 0xf5, 0x4e, 0x71, 0xb8, 0xf4, 145 0x8b, 0x5b, 0xbf, 0x0c, 0x59, 0x62, 0x79, 0x34, 0x97, 0x1a, 146 0x1f, 0x49, 0x9b, 0x0a, 0x4f, 0xbf, 0x95, 0xfc, 0x31, 0x39, 147 0x46, 0x4e, 0xa1, 0xaf, 0x00, 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 0x8c, 0xc7, 0xdc, 0x8c, 0x11, 0xd3, 0x75, 0x9e, 0x16, 0xa5, 157 0x9f, 0xd2, 0x9c, 0x64, 0xd7, 0x1f, 0x9b, 0xad, 0x1a, 0x62, 158 0x33, 0x98, 0xc7, 0xaf, 0x67, 0x02, 0xc5, 0xe0, 0x75, 0x8e, 159 0x62, 0xcf, 0x15, 0x6d, 0x99, 0xf5, 0x4e, 0x71, 0xb8, 0xf4, 160 0x8b, 0x5b, 0xbf, 0x0c, 0x59, 0x62, 0x79, 0x34, 0x97, 0x1a, 161 0x1f, 0x49, 0x9b, 0x0a, 0x4f, 0xbf, 0x95, 0xfc, 0x31, 0x39, 162 0x46, 0x4e, 0xa1, 0xaf, 0x00, 163 164 // 65 bytes 165 0x8c, 0xc7, 0xdc, 0x8c, 0x11, 0xd3, 0x75, 0x9e, 0x16, 0xa5, 166 0x9f, 0xd2, 0x9c, 0x64, 0xd7, 0x1f, 0x9b, 0xad, 0x1a, 0x62, 167 0x33, 0x98, 0xc7, 0xaf, 0x67, 0x02, 0xc5, 0xe0, 0x75, 0x8e, 168 0x62, 0xcf, 0x15, 0x6d, 0x99, 0xf5, 0x4e, 0x71, 0xb8, 0xf4, 169 0x8b, 0x5b, 0xbf, 0x0c, 0x59, 0x62, 0x79, 0x34, 0x97, 0x1a, 170 0x1f, 0x49, 0x9b, 0x0a, 0x4f, 0xbf, 0x95, 0xfc, 0x31, 0x39, 171 0x46, 0x4e, 0xa1, 0xaf, 0x00, 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("pCW7sVBytzdZ1WrqzGY1DvA2S9UaMr72xpUMxVyx1QHBARNYx", 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 TestImportTxNotState(t *testing.T) { 190 require := require.New(t) 191 192 intf := interface{}(&ImportTx{}) 193 _, ok := intf.(verify.State) 194 require.False(ok, "should not be marked as state") 195 }