github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/native/transaction_serializer.go (about) 1 package native 2 3 import ( 4 "errors" 5 "math/big" 6 7 "github.com/unicornultrafoundation/go-u2u/common" 8 "github.com/unicornultrafoundation/go-u2u/core/types" 9 10 "github.com/unicornultrafoundation/go-u2u/utils/cser" 11 ) 12 13 var ErrUnknownTxType = errors.New("unknown tx type") 14 15 func encodeSig(r, s *big.Int) (sig [64]byte) { 16 copy(sig[0:], cser.PaddedBytes(r.Bytes(), 32)[:32]) 17 copy(sig[32:], cser.PaddedBytes(s.Bytes(), 32)[:32]) 18 return sig 19 } 20 21 func decodeSig(sig [64]byte) (r, s *big.Int) { 22 r = new(big.Int).SetBytes(sig[:32]) 23 s = new(big.Int).SetBytes(sig[32:64]) 24 return 25 } 26 27 func TransactionMarshalCSER(w *cser.Writer, tx *types.Transaction) error { 28 if tx.Type() != types.LegacyTxType && tx.Type() != types.AccessListTxType && tx.Type() != types.DynamicFeeTxType { 29 return ErrUnknownTxType 30 } 31 if tx.Type() != types.LegacyTxType { 32 // marker of a non-standard tx 33 w.BitsW.Write(6, 0) 34 // tx type 35 w.U8(tx.Type()) 36 } else if tx.Gas() <= 0xff { 37 return errors.New("cannot serialize legacy tx with gasLimit <= 256") 38 } 39 w.U64(tx.Nonce()) 40 w.U64(tx.Gas()) 41 if tx.Type() == types.DynamicFeeTxType { 42 w.BigInt(tx.GasTipCap()) 43 w.BigInt(tx.GasFeeCap()) 44 } else { 45 w.BigInt(tx.GasPrice()) 46 } 47 w.BigInt(tx.Value()) 48 w.Bool(tx.To() != nil) 49 if tx.To() != nil { 50 w.FixedBytes(tx.To().Bytes()) 51 } 52 w.SliceBytes(tx.Data()) 53 v, r, s := tx.RawSignatureValues() 54 w.BigInt(v) 55 sig := encodeSig(r, s) 56 w.FixedBytes(sig[:]) 57 if tx.Type() == types.AccessListTxType || tx.Type() == types.DynamicFeeTxType { 58 w.BigInt(tx.ChainId()) 59 w.U32(uint32(len(tx.AccessList()))) 60 for _, tuple := range tx.AccessList() { 61 w.FixedBytes(tuple.Address.Bytes()) 62 w.U32(uint32(len(tuple.StorageKeys))) 63 for _, h := range tuple.StorageKeys { 64 w.FixedBytes(h.Bytes()) 65 } 66 } 67 } 68 return nil 69 } 70 71 func TransactionUnmarshalCSER(r *cser.Reader) (*types.Transaction, error) { 72 txType := uint8(types.LegacyTxType) 73 if r.BitsR.View(6) == 0 { 74 r.BitsR.Read(6) 75 txType = r.U8() 76 } 77 78 nonce := r.U64() 79 gasLimit := r.U64() 80 var gasPrice *big.Int 81 var gasTipCap *big.Int 82 var gasFeeCap *big.Int 83 if txType == types.DynamicFeeTxType { 84 gasTipCap = r.BigInt() 85 gasFeeCap = r.BigInt() 86 } else { 87 gasPrice = r.BigInt() 88 } 89 amount := r.BigInt() 90 toExists := r.Bool() 91 var to *common.Address 92 if toExists { 93 var _to common.Address 94 r.FixedBytes(_to[:]) 95 to = &_to 96 } 97 data := r.SliceBytes(ProtocolMaxMsgSize) 98 // sig 99 v := r.BigInt() 100 var sig [64]byte 101 r.FixedBytes(sig[:]) 102 _r, s := decodeSig(sig) 103 104 if txType == types.LegacyTxType { 105 return types.NewTx(&types.LegacyTx{ 106 Nonce: nonce, 107 GasPrice: gasPrice, 108 Gas: gasLimit, 109 To: to, 110 Value: amount, 111 Data: data, 112 V: v, 113 R: _r, 114 S: s, 115 }), nil 116 } else if txType == types.AccessListTxType || txType == types.DynamicFeeTxType { 117 chainID := r.BigInt() 118 accessListLen := r.U32() 119 if accessListLen > ProtocolMaxMsgSize/24 { 120 return nil, cser.ErrTooLargeAlloc 121 } 122 accessList := make(types.AccessList, accessListLen) 123 for i := range accessList { 124 r.FixedBytes(accessList[i].Address[:]) 125 keysLen := r.U32() 126 if keysLen > ProtocolMaxMsgSize/32 { 127 return nil, cser.ErrTooLargeAlloc 128 } 129 accessList[i].StorageKeys = make([]common.Hash, keysLen) 130 for j := range accessList[i].StorageKeys { 131 r.FixedBytes(accessList[i].StorageKeys[j][:]) 132 } 133 } 134 if txType == types.AccessListTxType { 135 return types.NewTx(&types.AccessListTx{ 136 ChainID: chainID, 137 Nonce: nonce, 138 GasPrice: gasPrice, 139 Gas: gasLimit, 140 To: to, 141 Value: amount, 142 Data: data, 143 AccessList: accessList, 144 V: v, 145 R: _r, 146 S: s, 147 }), nil 148 } else { 149 return types.NewTx(&types.DynamicFeeTx{ 150 ChainID: chainID, 151 Nonce: nonce, 152 GasTipCap: gasTipCap, 153 GasFeeCap: gasFeeCap, 154 Gas: gasLimit, 155 To: to, 156 Value: amount, 157 Data: data, 158 AccessList: accessList, 159 V: v, 160 R: _r, 161 S: s, 162 }), nil 163 } 164 } 165 return nil, ErrUnknownTxType 166 }