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 }