Skip to content

Commit

Permalink
RLP: remove allocations, replace buff with pooled buff (#12869)
Browse files Browse the repository at this point in the history
Preparation for RLP gen package. For now replacing stack allocations
with pooled buff, and removing other allocations in RLP encoding logic
  • Loading branch information
racytech authored Dec 3, 2024
1 parent 541a135 commit 2c8003c
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 114 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 2c8003c

Please sign in to comment.