Background
SorobanListener (src/soroban/soroban.listener.ts) streams contract events
and the indexer module persists them. If the process is down, the RPC drops a
connection, or an event is missed, the DB silently diverges from chain state and
nothing detects or repairs it.
Goal
Add a durable per-contract sync checkpoint plus a periodic reconciliation job
that detects gaps between the last indexed ledger and chain head and backfills
missing events, making indexing self-healing.
Tasks
- Entity
src/indexer/entities/chain-sync-checkpoint.entity.ts:
- Update the listener/indexer ingest path to advance the checkpoint
ReconciliationService with a @Cron job (interval from
- Health surface: extend the existing indexer health controller
- Env
RECONCILE_INTERVAL_MS, RECONCILE_WINDOW, RECONCILE_ENABLED in
Acceptance Criteria
- Killing the indexer, advancing the chain, and restarting results in the gap
- Re-running reconciliation over already-indexed ledgers inserts zero
- Checkpoint never advances past events that failed to persist.
- Health endpoint reports a non-negative
lag.
Files
src/indexer/entities/chain-sync-checkpoint.entity.ts,
src/indexer/reconciliation.service.ts (new),
src/indexer/indexer.service.ts, src/soroban/soroban.listener.ts,
src/indexer/indexer-health.controller.ts,
Background
SorobanListener(src/soroban/soroban.listener.ts) streams contract eventsand the
indexermodule persists them. If the process is down, the RPC drops aconnection, or an event is missed, the DB silently diverges from chain state and
nothing detects or repairs it.
Goal
Add a durable per-contract sync checkpoint plus a periodic reconciliation job
that detects gaps between the last indexed ledger and chain head and backfills
missing events, making indexing self-healing.
Tasks
src/indexer/entities/chain-sync-checkpoint.entity.ts:ReconciliationServicewith a@Cronjob (interval fromRECONCILE_INTERVAL_MS,RECONCILE_WINDOW,RECONCILE_ENABLEDinAcceptance Criteria
lag.Files
src/indexer/entities/chain-sync-checkpoint.entity.ts,src/indexer/reconciliation.service.ts(new),src/indexer/indexer.service.ts,src/soroban/soroban.listener.ts,src/indexer/indexer-health.controller.ts,