Skip to content

ServiceGetReceiptsQuery68

Source (upstream pre-purge) Current
File eth/protocols/eth/handlers.go handlers_pow.go
Symbol ServiceGetReceiptsQuery68 ServiceGetReceiptsQuery68
Ref 723aae2b4~1 etc/v1.17.4-full-node

Byte-for-byte revival. Serves from chain.GetReceiptsRLP + blockReceiptsToNetwork68, i.e. storage-RLP transformed to the wire form with the bloom recomputed from the raw log bytes — no receipt is ever decoded into a types.Receipt. Supersedes the earlier purge1 revival, which called rlp.EncodeToBytes(chain.GetReceiptsByHash(hash)) and therefore decoded and re-encoded every receipt. Output verified byte-identical between the two by TestMessages68, which encodes both forms against the same upstream golden vector. ONE LINE deviates from every source — results = rlp.EmptyList in the branch where the receipts are absent but the header carries an empty ReceiptHash. It matches neither the purge_eth68 original nor purge1 nor core-geth, and the reason is a latent bug in the original that only this lineage exposes. Pre-drop appended the nil rlp.RawValue returned by GetReceiptsRLP; rlp's writeRawValue emits the bytes verbatim, so nil contributes zero bytes and the entry silently vanishes from the response list instead of being sent as an empty list. The requester matches receipt lists to headers positionally (queue.DeliverReceipts compares receiptListHashes[index] against header.ReceiptHash), so a vanished entry shifts every later one and the whole response is rejected. purge1 and core-geth never hit this because they build the reply with rlp.EncodeToBytes(types.Receipts(nil)), which yields 0xC0 — an empty list, the correct answer for a block whose receipt root is empty. Upstream's own eth/69 successor rewrote the branch to break instead. rlp.EmptyList (0xC0) restores exactly the purge1 / core-geth behaviour this fork shipped before, inside the newer raw serving path.

3-way merge — purge → getc ← upstream

pre-purgefork-only
// ServiceGetReceiptsQuery68 assembles the response to a receipt query. It is
// exposed to allow external packages to test protocol behavior.
func ServiceGetReceiptsQuery68(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
// Gather state data until the fetch or network limits is reached
var (
bytes int
receipts []rlp.RawValue
)
for lookups, hash := range query {
if bytes >= softResponseLimit || len(receipts) >= maxReceiptsServe ||
lookups >= 2*maxReceiptsServe {
break
}
// Retrieve the requested block's receipts
results := chain.GetReceiptsRLP(hash)
if results == nil {
if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
continue
}
results = rlp.EmptyList
} else {
body := chain.GetBodyRLP(hash)
if body == nil {
continue
}
var err error
results, err = blockReceiptsToNetwork68(results, body)
if err != nil {
log.Error("Error in block receipts conversion", "hash", hash, "err", err)
continue
}
}
receipts = append(receipts, results)
bytes += len(results)
}
return receipts
}
core-geth validation — +16 -9 | | | |---|---| | File | [`handlers.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/eth/protocols/eth/handlers.go) | | Symbol | `ServiceGetReceiptsQuery` | | Ref | `v1.12.20` |
--- a/core-geth/eth/protocols/eth/handlers.go
+++ b/etc/eth/protocols/eth/handlers_pow.go
@@ -1,6 +1,6 @@
-// ServiceGetReceiptsQuery assembles the response to a receipt query. It is
+// ServiceGetReceiptsQuery68 assembles the response to a receipt query. It is
 // exposed to allow external packages to test protocol behavior.
-func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
+func ServiceGetReceiptsQuery68(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
    // Gather state data until the fetch or network limits is reached
    var (
        bytes    int
@@ -12,19 +12,26 @@
            break
        }
        // Retrieve the requested block's receipts
-       results := chain.GetReceiptsByHash(hash)
+       results := chain.GetReceiptsRLP(hash)
        if results == nil {
            if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
                continue
            }
-       }
-       // If known, encode and queue for response packet
-       if encoded, err := rlp.EncodeToBytes(results); err != nil {
-           log.Error("Failed to encode receipt", "err", err)
+           results = rlp.EmptyList
        } else {
-           receipts = append(receipts, encoded)
-           bytes += len(encoded)
+           body := chain.GetBodyRLP(hash)
+           if body == nil {
+               continue
+           }
+           var err error
+           results, err = blockReceiptsToNetwork68(results, body)
+           if err != nil {
+               log.Error("Error in block receipts conversion", "hash", hash, "err", err)
+               continue
+           }
        }
+       receipts = append(receipts, results)
+       bytes += len(results)
    }
    return receipts
 }

← eth Protocol