github.com/ava-labs/avalanchego@v1.11.11/vms/components/avax/base_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 avax
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  
    10  	"github.com/ava-labs/avalanchego/ids"
    11  	"github.com/ava-labs/avalanchego/snow"
    12  	"github.com/ava-labs/avalanchego/vms/types"
    13  )
    14  
    15  // MaxMemoSize is the maximum number of bytes in the memo field
    16  const MaxMemoSize = 256
    17  
    18  var (
    19  	ErrNilTx          = errors.New("nil tx is not valid")
    20  	ErrWrongNetworkID = errors.New("tx has wrong network ID")
    21  	ErrWrongChainID   = errors.New("tx has wrong chain ID")
    22  	ErrMemoTooLarge   = errors.New("memo exceeds maximum length")
    23  )
    24  
    25  // BaseTx is the basis of all standard transactions.
    26  type BaseTx struct {
    27  	NetworkID    uint32                `serialize:"true" json:"networkID"`    // ID of the network this chain lives on
    28  	BlockchainID ids.ID                `serialize:"true" json:"blockchainID"` // ID of the chain on which this transaction exists (prevents replay attacks)
    29  	Outs         []*TransferableOutput `serialize:"true" json:"outputs"`      // The outputs of this transaction
    30  	Ins          []*TransferableInput  `serialize:"true" json:"inputs"`       // The inputs to this transaction
    31  	Memo         types.JSONByteSlice   `serialize:"true" json:"memo"`         // Memo field contains arbitrary bytes, up to maxMemoSize
    32  }
    33  
    34  // InputUTXOs track which UTXOs this transaction is consuming.
    35  func (t *BaseTx) InputUTXOs() []*UTXOID {
    36  	utxos := make([]*UTXOID, len(t.Ins))
    37  	for i, in := range t.Ins {
    38  		utxos[i] = &in.UTXOID
    39  	}
    40  	return utxos
    41  }
    42  
    43  // NumCredentials returns the number of expected credentials
    44  func (t *BaseTx) NumCredentials() int {
    45  	return len(t.Ins)
    46  }
    47  
    48  // Verify ensures that transaction metadata is valid
    49  func (t *BaseTx) Verify(ctx *snow.Context) error {
    50  	switch {
    51  	case t == nil:
    52  		return ErrNilTx
    53  	case t.NetworkID != ctx.NetworkID:
    54  		return ErrWrongNetworkID
    55  	case t.BlockchainID != ctx.ChainID:
    56  		return ErrWrongChainID
    57  	case len(t.Memo) > MaxMemoSize:
    58  		return fmt.Errorf(
    59  			"%w: %d > %d",
    60  			ErrMemoTooLarge,
    61  			len(t.Memo),
    62  			MaxMemoSize,
    63  		)
    64  	default:
    65  		return nil
    66  	}
    67  }
    68  
    69  func VerifyMemoFieldLength(memo types.JSONByteSlice, isDurangoActive bool) error {
    70  	if !isDurangoActive {
    71  		// SyntacticVerify validates this field pre-Durango
    72  		return nil
    73  	}
    74  
    75  	if len(memo) != 0 {
    76  		return fmt.Errorf(
    77  			"%w: %d > %d",
    78  			ErrMemoTooLarge,
    79  			len(memo),
    80  			0,
    81  		)
    82  	}
    83  
    84  	return nil
    85  }