github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/txs/import_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  	"fmt"
     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/set"
    14  	"github.com/MetalBlockchain/metalgo/vms/components/avax"
    15  	"github.com/MetalBlockchain/metalgo/vms/secp256k1fx"
    16  )
    17  
    18  var (
    19  	_ UnsignedTx = (*ImportTx)(nil)
    20  
    21  	errNoImportInputs = errors.New("tx has no imported inputs")
    22  )
    23  
    24  // ImportTx is an unsigned importTx
    25  type ImportTx struct {
    26  	BaseTx `serialize:"true"`
    27  
    28  	// Which chain to consume the funds from
    29  	SourceChain ids.ID `serialize:"true" json:"sourceChain"`
    30  
    31  	// Inputs that consume UTXOs produced on the chain
    32  	ImportedInputs []*avax.TransferableInput `serialize:"true" json:"importedInputs"`
    33  }
    34  
    35  // InitCtx sets the FxID fields in the inputs and outputs of this
    36  // [ImportTx]. Also sets the [ctx] to the given [vm.ctx] so that
    37  // the addresses can be json marshalled into human readable format
    38  func (tx *ImportTx) InitCtx(ctx *snow.Context) {
    39  	tx.BaseTx.InitCtx(ctx)
    40  	for _, in := range tx.ImportedInputs {
    41  		in.FxID = secp256k1fx.ID
    42  	}
    43  }
    44  
    45  // InputUTXOs returns the UTXOIDs of the imported funds
    46  func (tx *ImportTx) InputUTXOs() set.Set[ids.ID] {
    47  	set := set.NewSet[ids.ID](len(tx.ImportedInputs))
    48  	for _, in := range tx.ImportedInputs {
    49  		set.Add(in.InputID())
    50  	}
    51  	return set
    52  }
    53  
    54  func (tx *ImportTx) InputIDs() set.Set[ids.ID] {
    55  	inputs := tx.BaseTx.InputIDs()
    56  	atomicInputs := tx.InputUTXOs()
    57  	inputs.Union(atomicInputs)
    58  	return inputs
    59  }
    60  
    61  // SyntacticVerify this transaction is well-formed
    62  func (tx *ImportTx) SyntacticVerify(ctx *snow.Context) error {
    63  	switch {
    64  	case tx == nil:
    65  		return ErrNilTx
    66  	case tx.SyntacticallyVerified: // already passed syntactic verification
    67  		return nil
    68  	case len(tx.ImportedInputs) == 0:
    69  		return errNoImportInputs
    70  	}
    71  
    72  	if err := tx.BaseTx.SyntacticVerify(ctx); err != nil {
    73  		return err
    74  	}
    75  
    76  	for _, in := range tx.ImportedInputs {
    77  		if err := in.Verify(); err != nil {
    78  			return fmt.Errorf("input failed verification: %w", err)
    79  		}
    80  	}
    81  	if !utils.IsSortedAndUnique(tx.ImportedInputs) {
    82  		return errInputsNotSortedUnique
    83  	}
    84  
    85  	tx.SyntacticallyVerified = true
    86  	return nil
    87  }
    88  
    89  func (tx *ImportTx) Visit(visitor Visitor) error {
    90  	return visitor.ImportTx(tx)
    91  }