github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/tx_init.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package avm
     5  
     6  import (
     7  	"reflect"
     8  
     9  	"github.com/MetalBlockchain/metalgo/snow"
    10  	"github.com/MetalBlockchain/metalgo/vms/avm/fxs"
    11  	"github.com/MetalBlockchain/metalgo/vms/avm/txs"
    12  )
    13  
    14  var _ txs.Visitor = (*txInit)(nil)
    15  
    16  // Init initializes FxID where required
    17  type txInit struct {
    18  	tx            *txs.Tx
    19  	ctx           *snow.Context
    20  	typeToFxIndex map[reflect.Type]int
    21  	fxs           []*fxs.ParsedFx
    22  }
    23  
    24  func (t *txInit) getFx(val interface{}) (int, error) {
    25  	valType := reflect.TypeOf(val)
    26  	fx, exists := t.typeToFxIndex[valType]
    27  	if !exists {
    28  		return 0, errUnknownFx
    29  	}
    30  	return fx, nil
    31  }
    32  
    33  // getParsedFx returns the parsedFx object for a given TransferableInput
    34  // or TransferableOutput object
    35  func (t *txInit) getParsedFx(val interface{}) (*fxs.ParsedFx, error) {
    36  	idx, err := t.getFx(val)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	return t.fxs[idx], nil
    41  }
    42  
    43  func (t *txInit) init() error {
    44  	t.tx.Unsigned.InitCtx(t.ctx)
    45  
    46  	for _, cred := range t.tx.Creds {
    47  		fx, err := t.getParsedFx(cred.Credential)
    48  		if err != nil {
    49  			return err
    50  		}
    51  		cred.FxID = fx.ID
    52  	}
    53  	return nil
    54  }
    55  
    56  func (t *txInit) BaseTx(tx *txs.BaseTx) error {
    57  	if err := t.init(); err != nil {
    58  		return err
    59  	}
    60  
    61  	for _, in := range tx.Ins {
    62  		fx, err := t.getParsedFx(in.In)
    63  		if err != nil {
    64  			return err
    65  		}
    66  		in.FxID = fx.ID
    67  	}
    68  
    69  	for _, out := range tx.Outs {
    70  		fx, err := t.getParsedFx(out.Out)
    71  		if err != nil {
    72  			return err
    73  		}
    74  		out.FxID = fx.ID
    75  	}
    76  	return nil
    77  }
    78  
    79  func (t *txInit) CreateAssetTx(tx *txs.CreateAssetTx) error {
    80  	if err := t.init(); err != nil {
    81  		return err
    82  	}
    83  
    84  	for _, state := range tx.States {
    85  		fx := t.fxs[state.FxIndex]
    86  		state.FxID = fx.ID
    87  	}
    88  
    89  	for _, in := range tx.Ins {
    90  		fx, err := t.getParsedFx(in.In)
    91  		if err != nil {
    92  			return err
    93  		}
    94  		in.FxID = fx.ID
    95  	}
    96  	return t.BaseTx(&tx.BaseTx)
    97  }
    98  
    99  func (t *txInit) ImportTx(tx *txs.ImportTx) error {
   100  	if err := t.init(); err != nil {
   101  		return err
   102  	}
   103  
   104  	for _, in := range tx.ImportedIns {
   105  		fx, err := t.getParsedFx(in.In)
   106  		if err != nil {
   107  			return err
   108  		}
   109  		in.FxID = fx.ID
   110  	}
   111  	return t.BaseTx(&tx.BaseTx)
   112  }
   113  
   114  func (t *txInit) ExportTx(tx *txs.ExportTx) error {
   115  	if err := t.init(); err != nil {
   116  		return err
   117  	}
   118  
   119  	for _, out := range tx.ExportedOuts {
   120  		fx, err := t.getParsedFx(out.Out)
   121  		if err != nil {
   122  			return err
   123  		}
   124  		out.FxID = fx.ID
   125  	}
   126  	return t.BaseTx(&tx.BaseTx)
   127  }
   128  
   129  func (t *txInit) OperationTx(tx *txs.OperationTx) error {
   130  	if err := t.init(); err != nil {
   131  		return err
   132  	}
   133  
   134  	for _, op := range tx.Ops {
   135  		fx, err := t.getParsedFx(op.Op)
   136  		if err != nil {
   137  			return err
   138  		}
   139  		op.FxID = fx.ID
   140  	}
   141  	return t.BaseTx(&tx.BaseTx)
   142  }