eth/protocols/eth: improve server

This commit is contained in:
Felix Lange 2025-04-15 23:12:29 +02:00
parent fa854ca7be
commit f96cfcece0
3 changed files with 62 additions and 12 deletions

View file

@ -319,12 +319,15 @@ func serviceGetReceiptsQuery69(chain *core.BlockChain, query GetReceiptsRequest)
continue continue
} }
} else { } else {
header := chain.GetHeaderByHash(hash) body := chain.GetBodyRLP(hash)
if header.ReceiptHash != types.EmptyReceiptsHash { if body == nil {
body := new(types.Body) continue
if err := rlp.DecodeBytes(chain.GetBodyRLP(hash), &body); err == nil {
results = blockReceiptsToNetwork(results, body.Transactions)
} }
var err error
results, err = blockReceiptsToNetwork(results, body)
if err != nil {
log.Error("Error in block receipts conversion", "hash", hash, "err", err)
continue
} }
} }
receipts = append(receipts, results) receipts = append(receipts, results)
@ -424,7 +427,7 @@ func handleReceipts69(backend Backend, msg Decoder, peer *Peer) error {
for i := range res.List { for i := range res.List {
res.List[i].buf = buffers res.List[i].buf = buffers
} }
metadata := func() interface{} { metadata := func() any {
hasher := trie.NewStackTrie(nil) hasher := trie.NewStackTrie(nil)
hashes := make([]common.Hash, len(res.List)) hashes := make([]common.Hash, len(res.List))
for i := range res.List { for i := range res.List {

View file

@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"iter"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
@ -199,7 +200,14 @@ func (rl *ReceiptList69) toStorageReceiptsRLP() rlp.RawValue {
// blockReceiptsToNetwork takes a slice of rlp-encoded receipts, and transactions, // blockReceiptsToNetwork takes a slice of rlp-encoded receipts, and transactions,
// and applies the type-encoding on the receipts (for non-legacy receipts). // and applies the type-encoding on the receipts (for non-legacy receipts).
// e.g. for non-legacy receipts: receipt-data -> {tx-type || receipt-data} // e.g. for non-legacy receipts: receipt-data -> {tx-type || receipt-data}
func blockReceiptsToNetwork(blockReceipts rlp.RawValue, txs []*types.Transaction) []byte { func blockReceiptsToNetwork(blockReceipts, blockBody rlp.RawValue) ([]byte, error) {
txTypesIter, err := txTypesInBody(blockBody)
if err != nil {
return nil, fmt.Errorf("invalid block body: %v", err)
}
nextTxType, stopTxTypes := iter.Pull(txTypesIter)
defer stopTxTypes()
var ( var (
out bytes.Buffer out bytes.Buffer
enc = rlp.NewEncoderBuffer(&out) enc = rlp.NewEncoderBuffer(&out)
@ -207,13 +215,43 @@ func blockReceiptsToNetwork(blockReceipts rlp.RawValue, txs []*types.Transaction
) )
outer := enc.List() outer := enc.List()
for i := 0; it.Next(); i++ { for i := 0; it.Next(); i++ {
txType, _ := nextTxType()
content, _, _ := rlp.SplitList(it.Value()) content, _, _ := rlp.SplitList(it.Value())
receiptList := enc.List() receiptList := enc.List()
enc.WriteUint64(uint64(txs[i].Type())) enc.WriteUint64(uint64(txType))
enc.Write(content) enc.Write(content)
enc.ListEnd(receiptList) enc.ListEnd(receiptList)
} }
enc.ListEnd(outer) enc.ListEnd(outer)
enc.Flush() enc.Flush()
return out.Bytes() return out.Bytes(), nil
}
// txTypesInBody parses the transactions list of an encoded block body,
// returning just the types.
func txTypesInBody(body rlp.RawValue) (iter.Seq[byte], error) {
bodyFields, _, err := rlp.SplitList(body)
if err != nil {
return nil, err
}
txsIter, err := rlp.NewListIterator(bodyFields)
if err != nil {
return nil, err
}
return func(yield func(byte) bool) {
for txsIter.Next() {
var txType byte
switch k, content, _, _ := rlp.Split(txsIter.Value()); k {
case rlp.List:
txType = 0
case rlp.String:
if len(content) > 0 {
txType = content[0]
}
}
if !yield(txType) {
return
}
}
}, nil
} }

View file

@ -57,11 +57,20 @@ func TestTransformReceipts(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
// encode receipts from types object.
in, _ := rlp.EncodeToBytes(test.input) in, _ := rlp.EncodeToBytes(test.input)
have := blockReceiptsToNetwork(in, test.txs)
// encode block body from types object.
blockBody := types.Body{Transactions: test.txs}
encBlockBody, _ := rlp.EncodeToBytes(blockBody)
have, err := blockReceiptsToNetwork(in, encBlockBody)
if err != nil {
t.Fatalf("test[%d]: blockReceiptsToNetwork error: %v", i, err)
}
out, _ := rlp.EncodeToBytes(test.output) out, _ := rlp.EncodeToBytes(test.output)
if !bytes.Equal(have, out) { if !bytes.Equal(have, out) {
t.Fatalf("test[%d]: blockReceiptToNetwork mismatch\nhave: %x\nwant: %x\n in: %x", i, out, have, in) t.Fatalf("test[%d]: blockReceiptsToNetwork mismatch\nhave: %x\nwant: %x\n in: %x", i, out, have, in)
} }
var rl ReceiptList69 var rl ReceiptList69