github.com/dim4egster/coreth@v0.10.2/plugin/evm/codec.go (about)

     1  // (c) 2019-2021, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package evm
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/dim4egster/qmallgo/codec"
    10  	"github.com/dim4egster/qmallgo/codec/linearcodec"
    11  	"github.com/dim4egster/qmallgo/utils/wrappers"
    12  	"github.com/dim4egster/qmallgo/vms/secp256k1fx"
    13  )
    14  
    15  // Codec does serialization and deserialization
    16  var Codec codec.Manager
    17  
    18  func init() {
    19  	Codec = codec.NewDefaultManager()
    20  	c := linearcodec.NewDefault()
    21  
    22  	errs := wrappers.Errs{}
    23  	errs.Add(
    24  		c.RegisterType(&UnsignedImportTx{}),
    25  		c.RegisterType(&UnsignedExportTx{}),
    26  	)
    27  	c.SkipRegistrations(3)
    28  	errs.Add(
    29  		c.RegisterType(&secp256k1fx.TransferInput{}),
    30  		c.RegisterType(&secp256k1fx.MintOutput{}),
    31  		c.RegisterType(&secp256k1fx.TransferOutput{}),
    32  		c.RegisterType(&secp256k1fx.MintOperation{}),
    33  		c.RegisterType(&secp256k1fx.Credential{}),
    34  		c.RegisterType(&secp256k1fx.Input{}),
    35  		c.RegisterType(&secp256k1fx.OutputOwners{}),
    36  		Codec.RegisterCodec(codecVersion, c),
    37  	)
    38  
    39  	if errs.Errored() {
    40  		panic(errs.Err)
    41  	}
    42  }
    43  
    44  // extractAtomicTxs returns the atomic transactions in [atomicTxBytes] if
    45  // they exist.
    46  // if [batch] is true, it attempts to unmarshal [atomicTxBytes] as a slice of
    47  // transactions (post-ApricotPhase5), and if it is false, then it unmarshals
    48  // it as a single atomic transaction.
    49  func ExtractAtomicTxs(atomicTxBytes []byte, batch bool, codec codec.Manager) ([]*Tx, error) {
    50  	if len(atomicTxBytes) == 0 {
    51  		return nil, nil
    52  	}
    53  
    54  	if !batch {
    55  		tx, err := ExtractAtomicTx(atomicTxBytes, codec)
    56  		if err != nil {
    57  			return nil, err
    58  		}
    59  		return []*Tx{tx}, err
    60  	}
    61  	return ExtractAtomicTxsBatch(atomicTxBytes, codec)
    62  }
    63  
    64  // [ExtractAtomicTx] extracts a singular atomic transaction from [atomicTxBytes]
    65  // and returns a slice of atomic transactions for compatibility with the type returned post
    66  // ApricotPhase5.
    67  // Note: this function assumes [atomicTxBytes] is non-empty.
    68  func ExtractAtomicTx(atomicTxBytes []byte, codec codec.Manager) (*Tx, error) {
    69  	atomicTx := new(Tx)
    70  	if _, err := codec.Unmarshal(atomicTxBytes, atomicTx); err != nil {
    71  		return nil, fmt.Errorf("failed to unmarshal atomic transaction (pre-AP5): %w", err)
    72  	}
    73  	if err := atomicTx.Sign(codec, nil); err != nil {
    74  		return nil, fmt.Errorf("failed to initialize singleton atomic tx due to: %w", err)
    75  	}
    76  	return atomicTx, nil
    77  }
    78  
    79  // [ExtractAtomicTxsBatch] extracts a slice of atomic transactions from [atomicTxBytes].
    80  // Note: this function assumes [atomicTxBytes] is non-empty.
    81  func ExtractAtomicTxsBatch(atomicTxBytes []byte, codec codec.Manager) ([]*Tx, error) {
    82  	var atomicTxs []*Tx
    83  	if _, err := codec.Unmarshal(atomicTxBytes, &atomicTxs); err != nil {
    84  		return nil, fmt.Errorf("failed to unmarshal atomic tx (AP5) due to %w", err)
    85  	}
    86  
    87  	// Do not allow non-empty extra data field to contain zero atomic transactions. This would allow
    88  	// people to construct a block that contains useless data.
    89  	if len(atomicTxs) == 0 {
    90  		return nil, errMissingAtomicTxs
    91  	}
    92  
    93  	for index, atx := range atomicTxs {
    94  		if err := atx.Sign(codec, nil); err != nil {
    95  			return nil, fmt.Errorf("failed to initialize atomic tx at index %d: %w", index, err)
    96  		}
    97  	}
    98  	return atomicTxs, nil
    99  }