github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/txs/create_chain_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/snow/snowtest" 13 "github.com/MetalBlockchain/metalgo/utils/constants" 14 "github.com/MetalBlockchain/metalgo/utils/crypto/secp256k1" 15 "github.com/MetalBlockchain/metalgo/vms/components/avax" 16 "github.com/MetalBlockchain/metalgo/vms/secp256k1fx" 17 ) 18 19 func TestUnsignedCreateChainTxVerify(t *testing.T) { 20 ctx := snowtest.Context(t, snowtest.PChainID) 21 testSubnet1ID := ids.GenerateTestID() 22 testSubnet1ControlKeys := []*secp256k1.PrivateKey{ 23 preFundedKeys[0], 24 preFundedKeys[1], 25 } 26 27 type test struct { 28 description string 29 subnetID ids.ID 30 genesisData []byte 31 vmID ids.ID 32 fxIDs []ids.ID 33 chainName string 34 keys []*secp256k1.PrivateKey 35 setup func(*CreateChainTx) *CreateChainTx 36 expectedErr error 37 } 38 39 tests := []test{ 40 { 41 description: "tx is nil", 42 subnetID: testSubnet1ID, 43 genesisData: nil, 44 vmID: constants.AVMID, 45 fxIDs: nil, 46 chainName: "yeet", 47 keys: []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, 48 setup: func(*CreateChainTx) *CreateChainTx { 49 return nil 50 }, 51 expectedErr: ErrNilTx, 52 }, 53 { 54 description: "vm ID is empty", 55 subnetID: testSubnet1ID, 56 genesisData: nil, 57 vmID: constants.AVMID, 58 fxIDs: nil, 59 chainName: "yeet", 60 keys: []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, 61 setup: func(tx *CreateChainTx) *CreateChainTx { 62 tx.VMID = ids.ID{} 63 return tx 64 }, 65 expectedErr: errInvalidVMID, 66 }, 67 { 68 description: "subnet ID is platform chain's ID", 69 subnetID: testSubnet1ID, 70 genesisData: nil, 71 vmID: constants.AVMID, 72 fxIDs: nil, 73 chainName: "yeet", 74 keys: []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, 75 setup: func(tx *CreateChainTx) *CreateChainTx { 76 tx.SubnetID = ctx.ChainID 77 return tx 78 }, 79 expectedErr: ErrCantValidatePrimaryNetwork, 80 }, 81 { 82 description: "chain name is too long", 83 subnetID: testSubnet1ID, 84 genesisData: nil, 85 vmID: constants.AVMID, 86 fxIDs: nil, 87 chainName: "yeet", 88 keys: []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, 89 setup: func(tx *CreateChainTx) *CreateChainTx { 90 tx.ChainName = string(make([]byte, MaxNameLen+1)) 91 return tx 92 }, 93 expectedErr: errNameTooLong, 94 }, 95 { 96 description: "chain name has invalid character", 97 subnetID: testSubnet1ID, 98 genesisData: nil, 99 vmID: constants.AVMID, 100 fxIDs: nil, 101 chainName: "yeet", 102 keys: []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, 103 setup: func(tx *CreateChainTx) *CreateChainTx { 104 tx.ChainName = "⌘" 105 return tx 106 }, 107 expectedErr: errIllegalNameCharacter, 108 }, 109 { 110 description: "genesis data is too long", 111 subnetID: testSubnet1ID, 112 genesisData: nil, 113 vmID: constants.AVMID, 114 fxIDs: nil, 115 chainName: "yeet", 116 keys: []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, 117 setup: func(tx *CreateChainTx) *CreateChainTx { 118 tx.GenesisData = make([]byte, MaxGenesisLen+1) 119 return tx 120 }, 121 expectedErr: errGenesisTooLong, 122 }, 123 } 124 125 for _, test := range tests { 126 t.Run(test.description, func(t *testing.T) { 127 require := require.New(t) 128 129 inputs := []*avax.TransferableInput{{ 130 UTXOID: avax.UTXOID{ 131 TxID: ids.ID{'t', 'x', 'I', 'D'}, 132 OutputIndex: 2, 133 }, 134 Asset: avax.Asset{ID: ids.ID{'a', 's', 's', 'e', 't'}}, 135 In: &secp256k1fx.TransferInput{ 136 Amt: uint64(5678), 137 Input: secp256k1fx.Input{SigIndices: []uint32{0}}, 138 }, 139 }} 140 outputs := []*avax.TransferableOutput{{ 141 Asset: avax.Asset{ID: ids.ID{'a', 's', 's', 'e', 't'}}, 142 Out: &secp256k1fx.TransferOutput{ 143 Amt: uint64(1234), 144 OutputOwners: secp256k1fx.OutputOwners{ 145 Threshold: 1, 146 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 147 }, 148 }, 149 }} 150 subnetAuth := &secp256k1fx.Input{ 151 SigIndices: []uint32{0, 1}, 152 } 153 154 createChainTx := &CreateChainTx{ 155 BaseTx: BaseTx{BaseTx: avax.BaseTx{ 156 NetworkID: ctx.NetworkID, 157 BlockchainID: ctx.ChainID, 158 Ins: inputs, 159 Outs: outputs, 160 }}, 161 SubnetID: test.subnetID, 162 ChainName: test.chainName, 163 VMID: test.vmID, 164 FxIDs: test.fxIDs, 165 GenesisData: test.genesisData, 166 SubnetAuth: subnetAuth, 167 } 168 169 signers := [][]*secp256k1.PrivateKey{preFundedKeys} 170 stx, err := NewSigned(createChainTx, Codec, signers) 171 require.NoError(err) 172 173 createChainTx.SyntacticallyVerified = false 174 stx.Unsigned = test.setup(createChainTx) 175 176 err = stx.SyntacticVerify(ctx) 177 require.ErrorIs(err, test.expectedErr) 178 }) 179 } 180 }