Skip to content

Commit

Permalink
rlp: introducing pooled buff, remove allocations from basic types
Browse files Browse the repository at this point in the history
  • Loading branch information
racytech committed Nov 25, 2024
1 parent 97e9dee commit ea473ed
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 119 deletions.
32 changes: 17 additions & 15 deletions core/types/access_list_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,34 +168,34 @@ func accessListSize(al AccessList) int {
}

func encodeAccessList(al AccessList, w io.Writer, b []byte) error {
for _, tuple := range al {
for i := 0; i < len(al); i++ {
tupleLen := 21
// Each storage key takes 33 bytes
storageLen := 33 * len(tuple.StorageKeys)
storageLen := 33 * len(al[i].StorageKeys)
tupleLen += rlp2.ListPrefixLen(storageLen) + storageLen
if err := EncodeStructSizePrefix(tupleLen, w, b); err != nil {
return err
}
if err := rlp.EncodeOptionalAddress(&tuple.Address, w, b); err != nil {
if err := rlp.EncodeOptionalAddress(&al[i].Address, w, b); err != nil { // TODO(racytech): change addr to []byte?
return err
}
if err := EncodeStructSizePrefix(storageLen, w, b); err != nil {
return err
}
b[0] = 128 + 32
for _, storageKey := range tuple.StorageKeys {
for idx := 0; idx < len(al[i].StorageKeys); idx++ {
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(storageKey.Bytes()); err != nil {
if _, err := w.Write(al[i].StorageKeys[idx][:]); err != nil {
return err
}
}
}
return nil
}

func EncodeStructSizePrefix(size int, w io.Writer, b []byte) error {
func EncodeStructSizePrefix(size int, w io.Writer, b []byte) error { // TODO(racytech): move it to rlp package?
if size >= 56 {
beSize := libcommon.BitLenToByteLen(bits.Len(uint(size)))
binary.BigEndian.PutUint64(b[1:], uint64(size))
Expand All @@ -217,7 +217,8 @@ func EncodeStructSizePrefix(size int, w io.Writer, b []byte) error {
// transactions, it returns the type and payload.
func (tx *AccessListTx) MarshalBinary(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen := tx.payloadSize()
var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)
// encode TxType
b[0] = AccessListTxType
if _, err := w.Write(b[:1]); err != nil {
Expand All @@ -235,15 +236,15 @@ func (tx *AccessListTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceL
return err
}
// encode ChainID
if err := tx.ChainID.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(tx.ChainID, w, b); err != nil {
return err
}
// encode Nonce
if err := rlp.EncodeInt(tx.Nonce, w, b); err != nil {
return err
}
// encode GasPrice
if err := tx.GasPrice.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(tx.GasPrice, w, b); err != nil {
return err
}
// encode Gas
Expand All @@ -260,12 +261,12 @@ func (tx *AccessListTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceL
return err
}
if tx.To != nil {
if _, err := w.Write(tx.To.Bytes()); err != nil {
if _, err := w.Write(tx.To[:]); err != nil {
return err
}
}
// encode Value
if err := tx.Value.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(tx.Value, w, b); err != nil {
return err
}
// encode Data
Expand All @@ -281,15 +282,15 @@ func (tx *AccessListTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceL
return err
}
// encode V
if err := tx.V.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&tx.V, w, b); err != nil {
return err
}
// encode R
if err := tx.R.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&tx.R, w, b); err != nil {
return err
}
// encode S
if err := tx.S.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&tx.S, w, b); err != nil {
return err
}
return nil
Expand All @@ -301,7 +302,8 @@ func (tx *AccessListTx) EncodeRLP(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen := tx.payloadSize()
// size of struct prefix and TxType
envelopeSize := 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)
// envelope
if err := rlp.EncodeStringSizePrefix(envelopeSize, w, b[:]); err != nil {
return err
Expand Down
18 changes: 8 additions & 10 deletions core/types/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,36 +182,34 @@ func decodeAuthorizations(auths *[]Authorization, s *rlp.Stream) error {
}

func encodeAuthorizations(authorizations []Authorization, w io.Writer, b []byte) error {
for _, auth := range authorizations {
// 0. encode length of individual Authorization
authLen := authorizationSize(auth)
for i := 0; i < len(authorizations); i++ {
authLen := authorizationSize(authorizations[i])
if err := EncodeStructSizePrefix(authLen, w, b); err != nil {
return err
}

// 1. encode ChainId
if err := rlp.EncodeInt(auth.ChainID, w, b); err != nil {
if err := rlp.EncodeInt(authorizations[i].ChainID, w, b); err != nil {
return err
}
// 2. encode Address
if err := rlp.EncodeOptionalAddress(&auth.Address, w, b); err != nil {
if err := rlp.EncodeOptionalAddress(&authorizations[i].Address, w, b); err != nil {
return err
}
// 3. encode Nonce
if err := rlp.EncodeInt(auth.Nonce, w, b); err != nil {
if err := rlp.EncodeInt(authorizations[i].Nonce, w, b); err != nil {
return err
}
// 4. encode YParity, R, S
if err := rlp.EncodeInt(uint64(auth.YParity), w, b); err != nil {
if err := rlp.EncodeInt(uint64(authorizations[i].YParity), w, b); err != nil {
return err
}
if err := auth.R.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&authorizations[i].R, w, b); err != nil {
return err
}
if err := auth.S.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&authorizations[i].S, w, b); err != nil {
return err
}
}

return nil
}
28 changes: 15 additions & 13 deletions core/types/blob_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ func blobVersionedHashesSize(hashes []libcommon.Hash) int {
}

func encodeBlobVersionedHashes(hashes []libcommon.Hash, w io.Writer, b []byte) error {
for _, h := range hashes {
if err := rlp.EncodeString(h[:], w, b); err != nil {
for i := 0; i < len(hashes); i++ {
if err := rlp.EncodeString(hashes[i][:], w, b); err != nil {
return err
}
}
Expand All @@ -192,19 +192,19 @@ func (stx *BlobTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceLen, g
return err
}
// encode ChainID
if err := stx.ChainID.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(stx.ChainID, w, b); err != nil {
return err
}
// encode Nonce
if err := rlp.EncodeInt(stx.Nonce, w, b); err != nil {
return err
}
// encode MaxPriorityFeePerGas
if err := stx.Tip.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(stx.Tip, w, b); err != nil {
return err
}
// encode MaxFeePerGas
if err := stx.FeeCap.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(stx.FeeCap, w, b); err != nil {
return err
}
// encode Gas
Expand All @@ -216,11 +216,11 @@ func (stx *BlobTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceLen, g
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(stx.To.Bytes()); err != nil {
if _, err := w.Write(stx.To[:]); err != nil {
return err
}
// encode Value
if err := stx.Value.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(stx.Value, w, b); err != nil {
return err
}
// encode Data
Expand All @@ -236,7 +236,7 @@ func (stx *BlobTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceLen, g
return err
}
// encode MaxFeePerBlobGas
if err := stx.MaxFeePerBlobGas.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(stx.MaxFeePerBlobGas, w, b); err != nil {
return err
}
// prefix
Expand All @@ -248,15 +248,15 @@ func (stx *BlobTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceLen, g
return err
}
// encode V
if err := stx.V.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&stx.V, w, b); err != nil {
return err
}
// encode R
if err := stx.R.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&stx.R, w, b); err != nil {
return err
}
// encode S
if err := stx.S.EncodeRLP(w); err != nil {
if err := rlp.EncodeUint256(&stx.S, w, b); err != nil {
return err
}
return nil
Expand All @@ -266,7 +266,8 @@ func (stx *BlobTx) EncodeRLP(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen, blobHashesLen := stx.payloadSize()
// size of struct prefix and TxType
envelopeSize := 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)
// envelope
if err := rlp.EncodeStringSizePrefix(envelopeSize, w, b[:]); err != nil {
return err
Expand All @@ -284,7 +285,8 @@ func (stx *BlobTx) EncodeRLP(w io.Writer) error {

func (stx *BlobTx) MarshalBinary(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen, blobHashesLen := stx.payloadSize()
var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)
// encode TxType
b[0] = BlobTxType
if _, err := w.Write(b[:1]); err != nil {
Expand Down
39 changes: 23 additions & 16 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ func (h *Header) EncodingSize() int {
func (h *Header) EncodeRLP(w io.Writer) error {
encodingSize := h.EncodingSize()

var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)
// Prefix
if err := EncodeStructSizePrefix(encodingSize, w, b[:]); err != nil {
return err
Expand All @@ -209,39 +210,39 @@ func (h *Header) EncodeRLP(w io.Writer) error {
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.ParentHash.Bytes()); err != nil {
if _, err := w.Write(h.ParentHash[:]); err != nil {
return err
}
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.UncleHash.Bytes()); err != nil {
if _, err := w.Write(h.UncleHash[:]); err != nil {
return err
}
b[0] = 128 + 20
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.Coinbase.Bytes()); err != nil {
if _, err := w.Write(h.Coinbase[:]); err != nil {
return err
}
b[0] = 128 + 32
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.Root.Bytes()); err != nil {
if _, err := w.Write(h.Root[:]); err != nil {
return err
}
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.TxHash.Bytes()); err != nil {
if _, err := w.Write(h.TxHash[:]); err != nil {
return err
}
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.ReceiptHash.Bytes()); err != nil {
if _, err := w.Write(h.ReceiptHash[:]); err != nil {
return err
}
b[0] = 183 + 2
Expand All @@ -250,7 +251,7 @@ func (h *Header) EncodeRLP(w io.Writer) error {
if _, err := w.Write(b[:3]); err != nil {
return err
}
if _, err := w.Write(h.Bloom.Bytes()); err != nil {
if _, err := w.Write(h.Bloom[:]); err != nil {
return err
}
if err := rlp.EncodeBigInt(h.Difficulty, w, b[:]); err != nil {
Expand Down Expand Up @@ -284,7 +285,7 @@ func (h *Header) EncodeRLP(w io.Writer) error {
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.MixDigest.Bytes()); err != nil {
if _, err := w.Write(h.MixDigest[:]); err != nil {
return err
}
b[0] = 128 + 8
Expand All @@ -307,7 +308,7 @@ func (h *Header) EncodeRLP(w io.Writer) error {
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.WithdrawalsHash.Bytes()); err != nil {
if _, err := w.Write(h.WithdrawalsHash[:]); err != nil {
return err
}
}
Expand All @@ -328,7 +329,7 @@ func (h *Header) EncodeRLP(w io.Writer) error {
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.ParentBeaconBlockRoot.Bytes()); err != nil {
if _, err := w.Write(h.ParentBeaconBlockRoot[:]); err != nil {
return err
}
}
Expand All @@ -338,7 +339,7 @@ func (h *Header) EncodeRLP(w io.Writer) error {
if _, err := w.Write(b[:1]); err != nil {
return err
}
if _, err := w.Write(h.RequestsHash.Bytes()); err != nil {
if _, err := w.Write(h.RequestsHash[:]); err != nil {
return err
}
}
Expand Down Expand Up @@ -788,7 +789,8 @@ func (rb RawBody) payloadSize() (payloadSize, txsLen, unclesLen, withdrawalsLen

func (rb RawBody) EncodeRLP(w io.Writer) error {
payloadSize, txsLen, unclesLen, withdrawalsLen := rb.payloadSize()
var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)
// prefix
if err := EncodeStructSizePrefix(payloadSize, w, b[:]); err != nil {
return err
Expand Down Expand Up @@ -873,7 +875,8 @@ func (bfs BodyForStorage) payloadSize() (payloadSize, unclesLen, withdrawalsLen

func (bfs BodyForStorage) EncodeRLP(w io.Writer) error {
payloadSize, unclesLen, withdrawalsLen := bfs.payloadSize()
var b [33]byte
b := newEncodingBuf()
defer pooledBuf.Put(b)

// prefix
if err := EncodeStructSizePrefix(payloadSize, w, b[:]); err != nil {
Expand Down Expand Up @@ -956,7 +959,9 @@ func (bb Body) payloadSize() (payloadSize int, txsLen, unclesLen, withdrawalsLen

func (bb Body) EncodeRLP(w io.Writer) error {
payloadSize, txsLen, unclesLen, withdrawalsLen := bb.payloadSize()
var b [33]byte

b := newEncodingBuf()
defer pooledBuf.Put(b)
// prefix
if err := EncodeStructSizePrefix(payloadSize, w, b[:]); err != nil {
return err
Expand Down Expand Up @@ -1201,7 +1206,9 @@ func (bb *Block) EncodingSize() int {
// EncodeRLP serializes b into the Ethereum RLP block format.
func (bb *Block) EncodeRLP(w io.Writer) error {
payloadSize, txsLen, unclesLen, withdrawalsLen := bb.payloadSize()
var b [33]byte

b := newEncodingBuf()
defer pooledBuf.Put(b)
// prefix
if err := EncodeStructSizePrefix(payloadSize, w, b[:]); err != nil {
return err
Expand Down
Loading

0 comments on commit ea473ed

Please sign in to comment.