github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/txs/export_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/vms/components/avax"
    13  	"github.com/MetalBlockchain/metalgo/vms/platformvm/stakeable"
    14  	"github.com/MetalBlockchain/metalgo/vms/secp256k1fx"
    15  )
    16  
    17  var (
    18  	_ UnsignedTx = (*ExportTx)(nil)
    19  
    20  	ErrWrongLocktime   = errors.New("wrong locktime reported")
    21  	errNoExportOutputs = errors.New("no export outputs")
    22  )
    23  
    24  // ExportTx is an unsigned exportTx
    25  type ExportTx struct {
    26  	BaseTx `serialize:"true"`
    27  
    28  	// Which chain to send the funds to
    29  	DestinationChain ids.ID `serialize:"true" json:"destinationChain"`
    30  
    31  	// Outputs that are exported to the chain
    32  	ExportedOutputs []*avax.TransferableOutput `serialize:"true" json:"exportedOutputs"`
    33  }
    34  
    35  // InitCtx sets the FxID fields in the inputs and outputs of this
    36  // [UnsignedExportTx]. 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 *ExportTx) InitCtx(ctx *snow.Context) {
    39  	tx.BaseTx.InitCtx(ctx)
    40  	for _, out := range tx.ExportedOutputs {
    41  		out.FxID = secp256k1fx.ID
    42  		out.InitCtx(ctx)
    43  	}
    44  }
    45  
    46  // SyntacticVerify this transaction is well-formed
    47  func (tx *ExportTx) SyntacticVerify(ctx *snow.Context) error {
    48  	switch {
    49  	case tx == nil:
    50  		return ErrNilTx
    51  	case tx.SyntacticallyVerified: // already passed syntactic verification
    52  		return nil
    53  	case len(tx.ExportedOutputs) == 0:
    54  		return errNoExportOutputs
    55  	}
    56  
    57  	if err := tx.BaseTx.SyntacticVerify(ctx); err != nil {
    58  		return err
    59  	}
    60  
    61  	for _, out := range tx.ExportedOutputs {
    62  		if err := out.Verify(); err != nil {
    63  			return fmt.Errorf("output failed verification: %w", err)
    64  		}
    65  		if _, ok := out.Output().(*stakeable.LockOut); ok {
    66  			return ErrWrongLocktime
    67  		}
    68  	}
    69  	if !avax.IsSortedTransferableOutputs(tx.ExportedOutputs, Codec) {
    70  		return errOutputsNotSorted
    71  	}
    72  
    73  	tx.SyntacticallyVerified = true
    74  	return nil
    75  }
    76  
    77  func (tx *ExportTx) Visit(visitor Visitor) error {
    78  	return visitor.ExportTx(tx)
    79  }