Simplify RLP size calculations (#8506)

Use `ListPrefixLen` & `StringLen` from erigon-lib more
This commit is contained in:
Andrew Ashikhmin 2023-10-18 09:28:11 +02:00 committed by GitHub
parent 33d5399436
commit f26be2c4c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 261 deletions

View File

@ -28,6 +28,7 @@ import (
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
types2 "github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/erigon/common"
@ -93,13 +94,8 @@ func (tx *AccessListTx) Unwrap() Transaction {
// EncodingSize returns the RLP encoding size of the whole transaction envelope
func (tx AccessListTx) EncodingSize() int {
payloadSize, _, _, _ := tx.payloadSize()
envelopeSize := payloadSize
// Add envelope size and type size
if payloadSize >= 56 {
envelopeSize += libcommon.BitLenToByteLen(bits.Len(uint(payloadSize)))
}
envelopeSize += 2
return envelopeSize
return 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
}
// payloadSize calculates the RLP encoding size of transaction, without TxType and envelope
@ -127,26 +123,10 @@ func (tx AccessListTx) payloadSize() (payloadSize int, nonceLen, gasLen, accessL
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(tx.Value)
// size of Data
payloadSize++
switch len(tx.Data) {
case 0:
case 1:
if tx.Data[0] >= 128 {
payloadSize++
}
default:
if len(tx.Data) >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(len(tx.Data))))
}
payloadSize += len(tx.Data)
}
payloadSize += rlp2.StringLen(tx.Data)
// size of AccessList
payloadSize++
accessListLen = accessListSize(tx.AccessList)
if accessListLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(accessListLen)))
}
payloadSize += accessListLen
payloadSize += rlp2.ListPrefixLen(accessListLen) + accessListLen
// size of V
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(&tx.V)
@ -164,18 +144,10 @@ func accessListSize(al types2.AccessList) int {
for _, tuple := range al {
tupleLen := 21 // For the address
// size of StorageKeys
tupleLen++
// Each storage key takes 33 bytes
storageLen := 33 * len(tuple.StorageKeys)
if storageLen >= 56 {
tupleLen += libcommon.BitLenToByteLen(bits.Len(uint(storageLen))) // BE encoding of the length of the storage keys
}
tupleLen += storageLen
accessListLen++
if tupleLen >= 56 {
accessListLen += libcommon.BitLenToByteLen(bits.Len(uint(tupleLen))) // BE encoding of the length of the storage keys
}
accessListLen += tupleLen
tupleLen += rlp2.ListPrefixLen(storageLen) + storageLen
accessListLen += rlp2.ListPrefixLen(tupleLen) + tupleLen
}
return accessListLen
}
@ -183,13 +155,9 @@ func accessListSize(al types2.AccessList) int {
func encodeAccessList(al types2.AccessList, w io.Writer, b []byte) error {
for _, tuple := range al {
tupleLen := 21
tupleLen++
// Each storage key takes 33 bytes
storageLen := 33 * len(tuple.StorageKeys)
if storageLen >= 56 {
tupleLen += libcommon.BitLenToByteLen(bits.Len(uint(storageLen))) // BE encoding of the length of the storage keys
}
tupleLen += storageLen
tupleLen += rlp2.ListPrefixLen(storageLen) + storageLen
if err := EncodeStructSizePrefix(tupleLen, w, b); err != nil {
return err
}
@ -320,12 +288,8 @@ func (tx AccessListTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceLe
// EncodeRLP implements rlp.Encoder
func (tx AccessListTx) EncodeRLP(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen := tx.payloadSize()
envelopeSize := payloadSize
if payloadSize >= 56 {
envelopeSize += libcommon.BitLenToByteLen(bits.Len(uint(payloadSize)))
}
// size of struct prefix and TxType
envelopeSize += 2
envelopeSize := 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
var b [33]byte
// envelope
if err := rlp.EncodeStringSizePrefix(envelopeSize, w, b[:]); err != nil {

View File

@ -8,6 +8,7 @@ import (
"github.com/holiman/uint256"
libcommon "github.com/ledgerwatch/erigon-lib/common"
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/rlp"
@ -77,8 +78,6 @@ func (a *Account) EncodingLengthForStorage() uint {
}
func (a *Account) EncodingLengthForHashing() uint {
var structLength uint
balanceBytes := 0
if !a.Balance.LtUint64(128) {
balanceBytes = a.Balance.ByteLen()
@ -86,17 +85,11 @@ func (a *Account) EncodingLengthForHashing() uint {
nonceBytes := rlp.IntLenExcludingHead(a.Nonce)
structLength += uint(balanceBytes + nonceBytes + 2)
structLength := balanceBytes + nonceBytes + 2
structLength += 66 // Two 32-byte arrays + 2 prefixes
if structLength < 56 {
return 1 + structLength
}
lengthBytes := libcommon.BitLenToByteLen(bits.Len(structLength))
return uint(1+lengthBytes) + structLength
return uint(rlp2.ListPrefixLen(structLength) + structLength)
}
func (a *Account) EncodeForStorage(buffer []byte) {

View File

@ -4,13 +4,13 @@ import (
"fmt"
"io"
"math/big"
"math/bits"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/fixedgas"
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
types2 "github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/erigon/rlp"
@ -102,12 +102,8 @@ func (stx BlobTx) payloadSize() (payloadSize, nonceLen, gasLen, accessListLen, b
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(stx.MaxFeePerBlobGas)
// size of BlobVersionedHashes
payloadSize++
blobHashesLen = blobVersionedHashesSize(stx.BlobVersionedHashes)
if blobHashesLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(blobHashesLen)))
}
payloadSize += blobHashesLen
payloadSize += rlp2.ListPrefixLen(blobHashesLen) + blobHashesLen
return
}
@ -202,12 +198,8 @@ func (stx BlobTx) encodePayload(w io.Writer, b []byte, payloadSize, nonceLen, ga
func (stx BlobTx) EncodeRLP(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen, blobHashesLen := stx.payloadSize()
envelopeSize := payloadSize
if payloadSize >= 56 {
envelopeSize += libcommon.BitLenToByteLen(bits.Len(uint(payloadSize)))
}
// size of struct prefix and TxType
envelopeSize += 2
envelopeSize := 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
var b [33]byte
// envelope
if err := rlp.EncodeStringSizePrefix(envelopeSize, w, b[:]); err != nil {

View File

@ -24,7 +24,6 @@ import (
"fmt"
"io"
"math/big"
"math/bits"
"reflect"
"sync/atomic"
@ -128,25 +127,11 @@ func (h *Header) EncodingSize() int {
encodingSize++
encodingSize += rlp.IntLenExcludingHead(h.Time)
// size of Extra
encodingSize++
switch len(h.Extra) {
case 0:
case 1:
if h.Extra[0] >= 128 {
encodingSize++
}
default:
if len(h.Extra) >= 56 {
encodingSize += libcommon.BitLenToByteLen(bits.Len(uint(len(h.Extra))))
}
encodingSize += len(h.Extra)
}
encodingSize += rlp2.StringLen(h.Extra)
if len(h.AuRaSeal) != 0 {
encodingSize += 1 + rlp.IntLenExcludingHead(h.AuRaStep) + 1 + len(h.AuRaSeal)
if len(h.AuRaSeal) >= 56 {
encodingSize += libcommon.BitLenToByteLen(bits.Len(uint(len(h.AuRaSeal))))
}
encodingSize += 1 + rlp.IntLenExcludingHead(h.AuRaStep)
encodingSize += rlp2.ListPrefixLen(len(h.AuRaSeal)) + len(h.AuRaSeal)
} else {
encodingSize += 33 /* MixDigest */ + 9 /* BlockNonce */
}
@ -175,26 +160,12 @@ func (h *Header) EncodingSize() int {
if h.Verkle {
// Encoding of Verkle Proof
encodingSize++
switch len(h.VerkleProof) {
case 0:
case 1:
if h.VerkleProof[0] >= 128 {
encodingSize++
}
default:
if len(h.VerkleProof) >= 56 {
encodingSize += libcommon.BitLenToByteLen(bits.Len(uint(len(h.VerkleProof))))
}
encodingSize += len(h.VerkleProof)
}
encodingSize++
encodingSize += rlp2.StringLen(h.VerkleProof)
var tmpBuffer bytes.Buffer
if err := rlp.Encode(&tmpBuffer, h.VerkleKeyVals); err != nil {
panic(err)
}
encodingSize += tmpBuffer.Len()
encodingSize += rlp2.ListPrefixLen(tmpBuffer.Len()) + tmpBuffer.Len()
}
return encodingSize
@ -698,45 +669,25 @@ func (rb RawBody) EncodingSize() int {
func (rb RawBody) payloadSize() (payloadSize, txsLen, unclesLen, withdrawalsLen int) {
// size of Transactions
payloadSize++
for _, tx := range rb.Transactions {
txsLen += len(tx)
}
if txsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(txsLen)))
}
payloadSize += txsLen
payloadSize += rlp2.ListPrefixLen(txsLen) + txsLen
// size of Uncles
payloadSize++
for _, uncle := range rb.Uncles {
unclesLen++
uncleLen := uncle.EncodingSize()
if uncleLen >= 56 {
unclesLen += libcommon.BitLenToByteLen(bits.Len(uint(uncleLen)))
unclesLen += rlp2.ListPrefixLen(uncleLen) + uncleLen
}
unclesLen += uncleLen
}
if unclesLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(unclesLen)))
}
payloadSize += unclesLen
payloadSize += rlp2.ListPrefixLen(unclesLen) + unclesLen
// size of Withdrawals
if rb.Withdrawals != nil {
payloadSize++
for _, withdrawal := range rb.Withdrawals {
withdrawalsLen++
withdrawalLen := withdrawal.EncodingSize()
if withdrawalLen >= 56 {
withdrawalLen += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalLen)))
withdrawalsLen += rlp2.ListPrefixLen(withdrawalLen) + withdrawalLen
}
withdrawalsLen += withdrawalLen
}
if withdrawalsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalsLen)))
}
payloadSize += withdrawalsLen
payloadSize += rlp2.ListPrefixLen(withdrawalsLen) + withdrawalsLen
}
return payloadSize, txsLen, unclesLen, withdrawalsLen
@ -853,9 +804,6 @@ func (rb *RawBody) DecodeRLP(s *rlp.Stream) error {
}
func (bfs BodyForStorage) payloadSize() (payloadSize, unclesLen, withdrawalsLen int) {
payloadSize++
baseTxIdLen := 1 + rlp.IntLenExcludingHead(bfs.BaseTxId)
txAmountLen := 1 + rlp.IntLenExcludingHead(uint64(bfs.TxAmount))
@ -864,33 +812,18 @@ func (bfs BodyForStorage) payloadSize() (payloadSize, unclesLen, withdrawalsLen
// size of Uncles
for _, uncle := range bfs.Uncles {
unclesLen++
uncleLen := uncle.EncodingSize()
if uncleLen >= 56 {
unclesLen += libcommon.BitLenToByteLen(bits.Len(uint(uncleLen)))
unclesLen += rlp2.ListPrefixLen(uncleLen) + uncleLen
}
unclesLen += uncleLen
}
if unclesLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(unclesLen)))
}
payloadSize += unclesLen
payloadSize += rlp2.ListPrefixLen(unclesLen) + unclesLen
// size of Withdrawals
if bfs.Withdrawals != nil {
payloadSize++
for _, withdrawal := range bfs.Withdrawals {
withdrawalsLen++
withdrawalLen := withdrawal.EncodingSize()
if withdrawalLen >= 56 {
withdrawalLen += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalLen)))
withdrawalsLen += rlp2.ListPrefixLen(withdrawalLen) + withdrawalLen
}
withdrawalsLen += withdrawalLen
}
if withdrawalsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalsLen)))
}
payloadSize += withdrawalsLen
payloadSize += rlp2.ListPrefixLen(withdrawalsLen) + withdrawalsLen
}
return payloadSize, unclesLen, withdrawalsLen
@ -1012,50 +945,26 @@ func (bb Body) EncodingSize() int {
func (bb Body) payloadSize() (payloadSize int, txsLen, unclesLen, withdrawalsLen int) {
// size of Transactions
payloadSize++
for _, tx := range bb.Transactions {
txsLen++
txLen := tx.EncodingSize()
if txLen >= 56 {
txsLen += libcommon.BitLenToByteLen(bits.Len(uint(txLen)))
txsLen += rlp2.ListPrefixLen(txLen) + txLen
}
txsLen += txLen
}
if txsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(txsLen)))
}
payloadSize += txsLen
payloadSize += rlp2.ListPrefixLen(txsLen) + txsLen
// size of Uncles
payloadSize++
for _, uncle := range bb.Uncles {
unclesLen++
uncleLen := uncle.EncodingSize()
if uncleLen >= 56 {
unclesLen += libcommon.BitLenToByteLen(bits.Len(uint(uncleLen)))
unclesLen += rlp2.ListPrefixLen(uncleLen) + uncleLen
}
unclesLen += uncleLen
}
if unclesLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(unclesLen)))
}
payloadSize += unclesLen
payloadSize += rlp2.ListPrefixLen(unclesLen) + unclesLen
// size of Withdrawals
if bb.Withdrawals != nil {
payloadSize++
for _, withdrawal := range bb.Withdrawals {
withdrawalsLen++
withdrawalLen := withdrawal.EncodingSize()
if withdrawalLen >= 56 {
withdrawalLen += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalLen)))
withdrawalsLen += rlp2.ListPrefixLen(withdrawalLen) + withdrawalLen
}
withdrawalsLen += withdrawalLen
}
if withdrawalsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalsLen)))
}
payloadSize += withdrawalsLen
payloadSize += rlp2.ListPrefixLen(withdrawalsLen) + withdrawalsLen
}
return payloadSize, txsLen, unclesLen, withdrawalsLen
@ -1359,58 +1268,30 @@ func (bb *Block) DecodeRLP(s *rlp.Stream) error {
func (bb Block) payloadSize() (payloadSize int, txsLen, unclesLen, withdrawalsLen int) {
// size of Header
payloadSize++
headerLen := bb.header.EncodingSize()
if headerLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(headerLen)))
}
payloadSize += headerLen
payloadSize += rlp2.ListPrefixLen(headerLen) + headerLen
// size of Transactions
payloadSize++
for _, tx := range bb.transactions {
txsLen++
txLen := tx.EncodingSize()
if txLen >= 56 {
txsLen += libcommon.BitLenToByteLen(bits.Len(uint(txLen)))
txsLen += rlp2.ListPrefixLen(txLen) + txLen
}
txsLen += txLen
}
if txsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(txsLen)))
}
payloadSize += txsLen
payloadSize += rlp2.ListPrefixLen(txsLen) + txsLen
// size of Uncles
payloadSize++
for _, uncle := range bb.uncles {
unclesLen++
uncleLen := uncle.EncodingSize()
if uncleLen >= 56 {
unclesLen += libcommon.BitLenToByteLen(bits.Len(uint(uncleLen)))
unclesLen += rlp2.ListPrefixLen(uncleLen) + uncleLen
}
unclesLen += uncleLen
}
if unclesLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(unclesLen)))
}
payloadSize += unclesLen
payloadSize += rlp2.ListPrefixLen(unclesLen) + unclesLen
// size of Withdrawals
if bb.withdrawals != nil {
payloadSize++
for _, withdrawal := range bb.withdrawals {
withdrawalsLen++
withdrawalLen := withdrawal.EncodingSize()
if withdrawalLen >= 56 {
withdrawalLen += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalLen)))
withdrawalsLen += rlp2.ListPrefixLen(withdrawalLen) + withdrawalLen
}
withdrawalsLen += withdrawalLen
}
if withdrawalsLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(withdrawalsLen)))
}
payloadSize += withdrawalsLen
payloadSize += rlp2.ListPrefixLen(withdrawalsLen) + withdrawalsLen
}
return payloadSize, txsLen, unclesLen, withdrawalsLen

View File

@ -21,12 +21,12 @@ import (
"fmt"
"io"
"math/big"
"math/bits"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
types2 "github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/erigon/common"
@ -117,13 +117,8 @@ func (tx DynamicFeeTransaction) GetAccessList() types2.AccessList {
func (tx DynamicFeeTransaction) EncodingSize() int {
payloadSize, _, _, _ := tx.payloadSize()
envelopeSize := payloadSize
// Add envelope size and type size
if payloadSize >= 56 {
envelopeSize += libcommon.BitLenToByteLen(bits.Len(uint(payloadSize)))
}
envelopeSize += 2
return envelopeSize
return 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
}
func (tx DynamicFeeTransaction) payloadSize() (payloadSize int, nonceLen, gasLen, accessListLen int) {
@ -153,26 +148,10 @@ func (tx DynamicFeeTransaction) payloadSize() (payloadSize int, nonceLen, gasLen
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(tx.Value)
// size of Data
payloadSize++
switch len(tx.Data) {
case 0:
case 1:
if tx.Data[0] >= 128 {
payloadSize++
}
default:
if len(tx.Data) >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(len(tx.Data))))
}
payloadSize += len(tx.Data)
}
payloadSize += rlp2.StringLen(tx.Data)
// size of AccessList
payloadSize++
accessListLen = accessListSize(tx.AccessList)
if accessListLen >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(accessListLen)))
}
payloadSize += accessListLen
payloadSize += rlp2.ListPrefixLen(accessListLen) + accessListLen
// size of V
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(&tx.V)
@ -296,12 +275,8 @@ func (tx DynamicFeeTransaction) encodePayload(w io.Writer, b []byte, payloadSize
func (tx DynamicFeeTransaction) EncodeRLP(w io.Writer) error {
payloadSize, nonceLen, gasLen, accessListLen := tx.payloadSize()
envelopeSize := payloadSize
if payloadSize >= 56 {
envelopeSize += libcommon.BitLenToByteLen(bits.Len(uint(payloadSize)))
}
// size of struct prefix and TxType
envelopeSize += 2
envelopeSize := 1 + rlp2.ListPrefixLen(payloadSize) + payloadSize
var b [33]byte
// envelope
if err := rlp.EncodeStringSizePrefix(envelopeSize, w, b[:]); err != nil {

View File

@ -21,11 +21,11 @@ import (
"fmt"
"io"
"math/big"
"math/bits"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
types2 "github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/erigon/common"
@ -215,19 +215,7 @@ func (tx LegacyTx) payloadSize() (payloadSize int, nonceLen, gasLen int) {
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(tx.Value)
// size of Data
payloadSize++
switch len(tx.Data) {
case 0:
case 1:
if tx.Data[0] >= 128 {
payloadSize++
}
default:
if len(tx.Data) >= 56 {
payloadSize += libcommon.BitLenToByteLen(bits.Len(uint(len(tx.Data))))
}
payloadSize += len(tx.Data)
}
payloadSize += rlp2.StringLen(tx.Data)
// size of V
payloadSize++
payloadSize += rlp.Uint256LenExcludingHead(&tx.V)

View File

@ -20,11 +20,11 @@ import (
"fmt"
"io"
"math/big"
"math/bits"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/direct"
proto_sentry "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry"
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
"github.com/ledgerwatch/erigon/core/forkid"
"github.com/ledgerwatch/erigon/core/types"
@ -250,12 +250,8 @@ type NewBlockPacket struct {
func (nbp NewBlockPacket) EncodeRLP(w io.Writer) error {
encodingSize := 0
// size of Block
encodingSize++
blockLen := nbp.Block.EncodingSize()
if blockLen >= 56 {
encodingSize += libcommon.BitLenToByteLen(bits.Len(uint(blockLen)))
}
encodingSize += blockLen
encodingSize += rlp2.ListPrefixLen(blockLen) + blockLen
// size of TD
encodingSize++
var tdBitLen, tdLen int