github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/txs/create_chain_tx.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  	"errors"
     8  	"unicode"
     9  
    10  	"github.com/MetalBlockchain/metalgo/ids"
    11  	"github.com/MetalBlockchain/metalgo/snow"
    12  	"github.com/MetalBlockchain/metalgo/utils"
    13  	"github.com/MetalBlockchain/metalgo/utils/constants"
    14  	"github.com/MetalBlockchain/metalgo/utils/units"
    15  	"github.com/MetalBlockchain/metalgo/vms/components/verify"
    16  )
    17  
    18  const (
    19  	MaxNameLen    = 128
    20  	MaxGenesisLen = units.MiB
    21  )
    22  
    23  var (
    24  	_ UnsignedTx = (*CreateChainTx)(nil)
    25  
    26  	ErrCantValidatePrimaryNetwork = errors.New("new blockchain can't be validated by primary network")
    27  
    28  	errInvalidVMID             = errors.New("invalid VM ID")
    29  	errFxIDsNotSortedAndUnique = errors.New("feature extensions IDs must be sorted and unique")
    30  	errNameTooLong             = errors.New("name too long")
    31  	errGenesisTooLong          = errors.New("genesis too long")
    32  	errIllegalNameCharacter    = errors.New("illegal name character")
    33  )
    34  
    35  // CreateChainTx is an unsigned createChainTx
    36  type CreateChainTx struct {
    37  	// Metadata, inputs and outputs
    38  	BaseTx `serialize:"true"`
    39  	// ID of the Subnet that validates this blockchain
    40  	SubnetID ids.ID `serialize:"true" json:"subnetID"`
    41  	// A human readable name for the chain; need not be unique
    42  	ChainName string `serialize:"true" json:"chainName"`
    43  	// ID of the VM running on the new chain
    44  	VMID ids.ID `serialize:"true" json:"vmID"`
    45  	// IDs of the feature extensions running on the new chain
    46  	FxIDs []ids.ID `serialize:"true" json:"fxIDs"`
    47  	// Byte representation of genesis state of the new chain
    48  	GenesisData []byte `serialize:"true" json:"genesisData"`
    49  	// Authorizes this blockchain to be added to this subnet
    50  	SubnetAuth verify.Verifiable `serialize:"true" json:"subnetAuthorization"`
    51  }
    52  
    53  func (tx *CreateChainTx) SyntacticVerify(ctx *snow.Context) error {
    54  	switch {
    55  	case tx == nil:
    56  		return ErrNilTx
    57  	case tx.SyntacticallyVerified: // already passed syntactic verification
    58  		return nil
    59  	case tx.SubnetID == constants.PrimaryNetworkID:
    60  		return ErrCantValidatePrimaryNetwork
    61  	case len(tx.ChainName) > MaxNameLen:
    62  		return errNameTooLong
    63  	case tx.VMID == ids.Empty:
    64  		return errInvalidVMID
    65  	case !utils.IsSortedAndUnique(tx.FxIDs):
    66  		return errFxIDsNotSortedAndUnique
    67  	case len(tx.GenesisData) > MaxGenesisLen:
    68  		return errGenesisTooLong
    69  	}
    70  
    71  	for _, r := range tx.ChainName {
    72  		if r > unicode.MaxASCII || !(unicode.IsLetter(r) || unicode.IsNumber(r) || r == ' ') {
    73  			return errIllegalNameCharacter
    74  		}
    75  	}
    76  
    77  	if err := tx.BaseTx.SyntacticVerify(ctx); err != nil {
    78  		return err
    79  	}
    80  	if err := tx.SubnetAuth.Verify(); err != nil {
    81  		return err
    82  	}
    83  
    84  	tx.SyntacticallyVerified = true
    85  	return nil
    86  }
    87  
    88  func (tx *CreateChainTx) Visit(visitor Visitor) error {
    89  	return visitor.CreateChainTx(tx)
    90  }