1 Commits

Author SHA1 Message Date
501a9e6ad4 fix(data): re-read event history under the current keep policy
All checks were successful
deploy / build (push) Successful in 8m35s
deploy / deploy-web (push) Successful in 7s
deploy / deploy-api (push) Successful in 16s
Until 1e8869e the backfill kept only MiningRewards::* and Balances::Transfer.
The skip-list that replaced that allowlist only applied to blocks read after
the deploy, and event_scan never revisits a range it has claimed. So on
mainnet every block below 18510 has no Wormhole::* (or any other newly kept
kind) while indexed_from says 1. Planck and Heisenberg have the same hole over
whatever they had read by then.

This was found checking #22's endpoint against a mining address whose
deposits began at transfer_count 17,142. A mainnet node decodes
Wormhole::NativeTransferred in blocks 18400 and 18509, under the same spec 152
as the indexed blocks.

Migration 0008 collapses each chain's cursor to its top (low = high), so the
backfill walks back to genesis again. record_events and record_extrinsics
upsert on their primary keys, so re-reading is safe. Until the walk finishes,
indexed_from reports the real, shrinking gap. CLAUDE.md now says that keeping
more events needs a migration like this one.

Closes #23

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
2026-09-16 17:23:34 +03:00
2 changed files with 23 additions and 0 deletions

View File

@@ -51,6 +51,15 @@ orders of magnitude that still renders as a number. `RollingWindow::push` takes
an explicit `at_tip` flag and backfilled blocks contribute no timing sample. The
`Interval` enum exists so a caller cannot forget to say which kind it has.
**Changing what events are kept does nothing to history already read.**
`event_scan` records *where* the backfill has been, not *under which policy*, and
never revisits a range it has claimed. When the allowlist became a skip-list,
every block read before that deploy stayed without `Wormhole::*` (mainnet below
18510) while `indexed_from` said 1 — found only because a wallet's deposits
started at transfer 17,142. Any change to `SKIPPED_EVENTS` that keeps *more*
needs a migration that collapses the cursor (`0008_rescan_events.sql`), so the
backfill reads history again. Inserts upsert, so a re-read is safe.
**A head that closes a gap is not a tip observation.** `measured_interval`
divides elapsed time by height difference, which is the chain's rate only if
every height between two samples was *watched arriving*. A gap fill is proof

View File

@@ -0,0 +1,14 @@
-- Re-read every block's events under the current keep policy.
--
-- Until 1e8869e (2026-09-10) the backfill kept only `MiningRewards::*` and
-- `Balances::Transfer`. It claimed each block it read in `event_scan`, and the
-- skip-list that replaced the allowlist only ever applied to blocks read after
-- it, so every block read before that deploy is missing `Wormhole::*` and every
-- other kind while the cursor says it is done. On mainnet that is everything
-- below block 18510; blackbeard/observer#23.
--
-- Collapsing each range to its top makes the backfill walk down to genesis
-- again. Re-reading is safe: `record_events` and `record_extrinsics` upsert on
-- their primary keys. While it runs, `indexed_from` reports the real, shrinking
-- gap, which is the honest answer to "how far back can this be trusted".
update event_scan set low = high, updated_at = now();