mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/types: reduce allocation when decoding typed transactions and receipts
This commit is contained in:
parent
e4a28340c4
commit
353c1d3ee0
3 changed files with 34 additions and 4 deletions
|
|
@ -18,6 +18,8 @@ package types
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -36,6 +38,21 @@ var encodeBufferPool = sync.Pool{
|
|||
New: func() interface{} { return new(bytes.Buffer) },
|
||||
}
|
||||
|
||||
// getPooledBuffer retrieves a buffer from the pool and creates a byte slice
|
||||
// of the requested size from it.
|
||||
//
|
||||
// The caller should return the Buffer object back into encodeBufferPool after use!
|
||||
func getPooledBuffer(size uint64) ([]byte, *bytes.Buffer, error) {
|
||||
if size > math.MaxInt {
|
||||
return nil, nil, fmt.Errorf("can't get buffer of size %d", size)
|
||||
}
|
||||
buf := encodeBufferPool.Get().(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
buf.Grow(int(size))
|
||||
b := buf.Bytes()[:int(size)]
|
||||
return b, buf, nil
|
||||
}
|
||||
|
||||
// rlpHash encodes x and hashes the encoded bytes.
|
||||
func rlpHash(x interface{}) (h common.Hash) {
|
||||
sha := hasherPool.Get().(crypto.KeccakState)
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func (r *Receipt) MarshalBinary() ([]byte, error) {
|
|||
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
|
||||
// from an RLP stream.
|
||||
func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
||||
kind, _, err := s.Kind()
|
||||
kind, size, err := s.Kind()
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
|
|
@ -167,7 +167,14 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
|||
return r.setFromRLP(dec)
|
||||
default:
|
||||
// It's an EIP-2718 typed tx receipt.
|
||||
b, err := s.Bytes()
|
||||
b, buf, err := getPooledBuffer(size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer encodeBufferPool.Put(buf)
|
||||
if err := s.ReadBytes(b); err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,10 +147,16 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
|
|||
return err
|
||||
default:
|
||||
// It's an EIP-2718 typed TX envelope.
|
||||
var b []byte
|
||||
if b, err = s.Bytes(); err != nil {
|
||||
// First read the tx payload bytes into a temporary buffer.
|
||||
b, buf, err := getPooledBuffer(size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer encodeBufferPool.Put(buf)
|
||||
if err := s.ReadBytes(b); err != nil {
|
||||
return err
|
||||
}
|
||||
// Now decode the inner transaction.
|
||||
inner, err := tx.decodeTyped(b)
|
||||
if err == nil {
|
||||
tx.setDecoded(inner, uint64(len(b)))
|
||||
|
|
|
|||
Loading…
Reference in a new issue