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  }