Files
observer/.sqlx
grenadeandClaude Opus 5.5 739a2f5345
ci / gate (push) Successful in 5m41s
deploy / validate (push) Skipped
deploy / build (push) Successful in 10m12s
deploy / deploy-web (push) Successful in 5s
deploy / deploy-api (push) Successful in 22s
fix: a reorged height takes the winner's block and events, not the loser's
`chain_subscribeNewHeads` reports the best head, so a fork that wins at h
arrives as its h+1 and the replacement at h is never delivered. Ingest
checked heights for gaps but never parents for continuity, so h kept the
losing block's row, and `chain_event`, upserted by index, kept its
reward. Mainnet 61041 credited baba-gorchitsa 0.31 QTC the chain paid
QUANPOOL: its "mined" read 14.97 against a balance of 14.68 that can
only ever rise.

- `record` reads the header at the hash it resolved, then compares its
  parent with the row beneath it and walks a fork back (`repair_fork`),
  re-recording each replaced block and re-reading its events.
- Event and extrinsic rows carry `block_hash` (0024); a height is cleared
  of rows from any other block before it is written.
- The backfill stays `SETTLE_DEPTH` behind the tip and re-records any
  block row that is not canonical. 0024 collapses its cursor so all
  history is re-checked.
- `RollingWindow::push` replaces a block at a height it already holds
  instead of counting both forks.

Closes #52

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKabPYLTYP2G5s7ph7oCpo
2026-10-14 08:29:07 +03:00
..