Skip to content

Commit 7d2d8b7

Browse files
dzhelezovclaude
andcommitted
fix(how-it-works): traces are client-side filtered to preserve trace_index DFS rank
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4c0e325 commit 7d2d8b7

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

HOW-IT-WORKS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ So more RAM or cores don't buy wall-time here; they're already idle. A counter-i
111111

112112
## Correctness: byte-identical to `eth_getLogs`
113113

114-
None of this is worth anything if the data differs from what an archive node would return. It doesn't. Every row filter is pushed to the Portal's native server-side filters — logs by address and topics, traces by call target / caller / sighash, account transactions by from / to — the field projection requests exactly the columns Ponder's sync store persists, and the Portal's number/quantity encodings are normalized so a stored block, transaction, receipt, or trace is indistinguishable from the RPC path (which always carries `nonce`, `mixHash`, `sha3Uncles`, `totalDifficulty`). The only client-side row filter is the block-interval (offset/modulo) test, which the Portal has no native equivalent for.
114+
None of this is worth anything if the data differs from what an archive node would return. It doesn't. Logs (by address and topics) and account transactions (by from / to) are pushed to the Portal's native server-side filters, the field projection requests exactly the columns Ponder's sync store persists, and the Portal's number/quantity encodings are normalized so a stored block, transaction, receipt, or trace is indistinguishable from the RPC path (which always carries `nonce`, `mixHash`, `sha3Uncles`, `totalDifficulty`). Two row filters are applied client-side, and the first is the sharpest correctness detail in the system. **Traces** are fetched *whole* — the request carries only the parent-transaction relation, no trace filter — and matched after they arrive, because Ponder numbers each trace by its pre-order (depth-first) rank within the transaction's *entire* call tree. A server-side trace filter would return only the matched subset, so that rank would be computed over a partial tree and come out wrong; fetching every trace and filtering after ranking is what keeps `trace_index` byte-identical to the RPC path. The second is the **block-interval** (offset/modulo) test, which the Portal has no native equivalent for.
115115

116116
This is proven, not asserted. The differential harness ([`harness/diff`](harness/diff)) indexes the same bounded range **twice on this fork** — once with `portal:` set (the Portal path) and once without it (the stock RPC path; the only difference is the backfill source) — into two separate `ponder_sync` stores, then diffs every row of `logs`, `transactions`, `transaction_receipts`, and `traces`. Exit `0` means identical. The 15-chain run adds two independent lines of evidence: **60 of 60** sampled windows matched the Portal ground truth exactly, and two runs with *different* chunking, heap, and Postgres configs produced the **identical** 28,405,932-event total — a data-loss bug would diverge, and it doesn't.
117117

0 commit comments

Comments
 (0)