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 }