mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
rlp, eth: batch-allocate headers and reuse stream in decode path
This commit is contained in:
parent
fc19b63105
commit
17ecac6a16
2 changed files with 28 additions and 3 deletions
|
|
@ -21,6 +21,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
|
|
@ -374,15 +375,31 @@ func handleBlockHeaders(backend Backend, msg Decoder, peer *Peer) error {
|
|||
}, metadata)
|
||||
}
|
||||
|
||||
type headerAlloc struct {
|
||||
header types.Header
|
||||
difficulty big.Int
|
||||
number big.Int
|
||||
}
|
||||
|
||||
func decodeBlockHeaders(list *rlp.RawList[*types.Header]) ([]*types.Header, error) {
|
||||
headers := make([]*types.Header, 0, list.Len())
|
||||
stream := rlp.NewBytesStream(nil)
|
||||
defer rlp.PutStream(stream)
|
||||
|
||||
it := list.ContentIterator()
|
||||
for it.Next() {
|
||||
header := new(types.Header)
|
||||
if err := types.DecodeHeader(it.Value(), header); err != nil {
|
||||
a := new(headerAlloc)
|
||||
a.header.Difficulty = &a.difficulty
|
||||
a.header.Number = &a.number
|
||||
|
||||
stream.ResetBytes(it.Value())
|
||||
if err := a.header.DecodeRLP(stream); err != nil {
|
||||
return headers, err
|
||||
}
|
||||
headers = append(headers, header)
|
||||
if stream.Remaining() != 0 {
|
||||
return headers, rlp.ErrMoreThanOneValue
|
||||
}
|
||||
headers = append(headers, &a.header)
|
||||
}
|
||||
return headers, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -642,6 +642,14 @@ func PutStream(stream *Stream) {
|
|||
streamPool.Put(stream)
|
||||
}
|
||||
|
||||
// ResetBytes resets the stream to decode from b, reusing the inline slice
|
||||
// reader. This allows decoding a batch of values with one pooled stream
|
||||
// instead of doing a pool round-trip per value.
|
||||
func (s *Stream) ResetBytes(b []byte) {
|
||||
s.sliceRdr = b
|
||||
s.Reset(&s.sliceRdr, uint64(len(b)))
|
||||
}
|
||||
|
||||
// NewListStream creates a new stream that pretends to be positioned
|
||||
// at an encoded list of the given length.
|
||||
func NewListStream(r io.Reader, len uint64) *Stream {
|
||||
|
|
|
|||
Loading…
Reference in a new issue