Skip to content

cross-validation: RPC-realtime store missing on-chain logs of long-established addresses at scattered recent blocks — (block,address)-scoped, third-party confirmed; Portal store complete #36

Description

@dzhelezov

Found by the hourly A/B differ (the strict onlyB class added in #13): on chain 1, 89 log rows + 18 block rows are present in the Portal-leg store but absent from the RPC-realtime-leg store, inside the finalized overlap. Per-block sampling over [25455000, 25456100] shows 10 affected heights with clusters of 3–6 logs each.

Decisive third-party-confirmed sample (publicnode eth_getTransactionReceipt):

  • tx 0xea181850e9fcd5c0ad7ae89ca92c10472ffd2d58918342f003183f9f7dc009fe, block 25455946
  • the on-chain receipt carries logs at indices 989/990/992 from 0x61129032f2309d0bb73e00cc3ae411e4cbd9d95f (topic0s match the Portal-leg rows byte-for-byte)
  • the RPC-realtime store has the SAME transaction's logs at indices 997–1006 (other addresses) but not 989/990/992 — the loss is (block, address)-scoped and cuts through the middle of a single receipt.

This is not new-child discovery lag. Every affected address is long-established in BOTH stores — e.g. 0x611290… first seen at block 24,986,184 with 745 logs stored (739 in the lossy leg); two others first seen at 22,681,265 with ~6.2–6.4k logs each. At another affected height (25455045) the RPC-realtime leg has ZERO rows while the chain carries 6 relevant logs from two of these established addresses.

Mechanism open, two candidates:

  1. Provider-served incomplete realtime responses — the same leg's provider previously produced realtime (RPC mode): deterministic crash when a block's full-block eth_getLogs response exceeds viem's 10MiB body cap #23 (>10MiB full-block eth_getLogs bodies) and realtime (RPC mode): access_list stored as NULL for realtime-ingested txs — including txs with real access lists; Portal /stream preserves them #27 (accessList stripped from full-tx blocks, provider-confirmed), so response-integrity issues on this path have precedent.
  2. A client-side realtime handling defect (refetch/reorg path dropping part of a block's logs).

The Portal leg is chain-true at every sampled point (its rows match the on-chain receipt exactly). Notably, the same-block-child log-loss class that #26 just fixed in the fork's stream path shows that per-address realtime log loss is an easy defect class to have; whatever the mechanism here, the RPC-realtime path has no integrity check that would catch it — it trusts the provider's response completeness. Cross-validation is currently the only detector.

Repro (against two independently-synced stores):

-- per-block log-count diff over a recent window, chain 1
select block_number, count(*) from ponder_sync.logs
where chain_id=1 and block_number between 25455000 and 25456100 group by 1;
-- run on both stores and diff; then eth_getTransactionReceipt any missing row's tx hash

Follow-ups:

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseverity:criticalSilent data corruption/loss on the portal path — top priority

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions