Skip to content

feat(sqlite_schema_manager): dynamic historical sync ranges for custom event imports - #370

Merged
2 commits merged into
Goldii-locks:mainfrom
solaawojobi00-bit:fix/issue-263-sqlite-schema-manager-historical-ranges
Aug 30, 2026
Merged

feat(sqlite_schema_manager): dynamic historical sync ranges for custom event imports#370
2 commits merged into
Goldii-locks:mainfrom
solaawojobi00-bit:fix/issue-263-sqlite-schema-manager-historical-ranges

Conversation

@solaawojobi00-bit

Copy link
Copy Markdown
Contributor

Configure dynamic historical sync ranges in sqlite_schema_manager

Problem

sqlite_schema_manager (src/indexer/db.ts) had no way to accept an arbitrary, caller-supplied start/end ledger range for a one-off historical event import. Any bulk/backfill import had to go through the live insert path (insertEventBatch), which unconditionally advances indexer_state.last_ledger_sequence — so there was no safe way to import a custom historical window without risking corruption of the live indexer pointer, and no built-in way to verify the imported event counts for that window.

Scenario Before After
Import a custom historical ledger window Not supported; only the live insert path existed, which always advances the ledger pointer insertHistoricalEventBatch() accepts an explicit { startLedger, endLedger } range
Range validation None at the schema-manager layer validateHistoricalRange() rejects non-integers, values < 1, and start > end
Live pointer safety during import N/A Pointer is left untouched unless advanceLivePointer: true is passed, and never moves backwards
Verifying imported event counts No dedicated helper getHistoricalEventCounts() returns total + per-type counts for a range
Mistyped/incorrect range Silently accepted Any event whose ledger_sequence falls outside the declared range throws before any row is written

Solution

Added a small, self-contained "dynamic historical sync ranges" section to sqlite_schema_manager (src/indexer/db.ts) mirroring the range-validation semantics already used elsewhere in the indexer (inclusive [startLedger, endLedger], reject on start > end), but scoped to custom event imports rather than live RPC polling.

Changes

src/indexer/db.ts

  • HistoricalRangeError — dedicated error type for invalid historical ranges.
  • validateHistoricalRange(startLedger, endLedger) — validates an inclusive ledger range (positive integers, start <= end).
  • insertHistoricalEventBatch(events, range, options?) — atomically inserts a batch of events for a custom historical range. Rejects the whole batch up front if any event's ledger_sequence is outside the declared range. Only advances last_ledger_sequence when options.advanceLivePointer is true, and never moves it backwards.
  • getHistoricalEventCounts(startLedger, endLedger) — returns { totalEvents, eventsByType } for a range, so a custom import can be asserted against expected block event counts.

__tests__/sqlite-schema-manager.test.ts

Regression Tests

Acceptance criteria Test
Accepts dynamic start/end ledger values for custom imports insertHistoricalEventBatch tests: "imports events within the declared range without advancing the live pointer"
Validates the supplied range validateHistoricalRange describe block (valid range, single-ledger range, non-integer/negative start, non-numeric end, start > end)
Live pointer is never disturbed unless requested "advances the live pointer only when advanceLivePointer is requested", "does not move the live pointer backwards when advanceLivePointer is set"
Import is idempotent "ignores duplicate events on repeated import (idempotent)"
Rejects malformed input before writing "rejects an event whose ledger_sequence falls outside the declared range", "rejects an invalid range before touching the database"
Asserts correct block event counts are indexed getHistoricalEventCounts describe block: "asserts correct block event counts are indexed for a custom range", "throws for an invalid range"

Testing

$ npm test -- __tests__/sqlite-schema-manager.test.ts -t "263"

Test Suites: 1 passed, 1 total
Tests:       31 skipped, 14 passed, 45 total

Full suite (npm test) also run for regression:

Test Suites: 3 failed, 55 passed, 58 total
Tests:       5 failed, 960 passed, 965 total

The 5 pre-existing failures are unrelated to this change and reproduce identically on main before this branch's commit:

  • __tests__/failover-recovery-backoff-retry.test.ts and __tests__/failover-recovery-poll-diagnostics.test.ts — missing jest import (ReferenceError: jest is not defined).
  • __tests__/sqlite-schema-manager.test.ts — a pre-existing creates all schema-manager lookup indexes (#259) test references an undefined SCHEMA_MANAGER_INDEXES, and a pre-existing #186 rollback test asserts a stale migration-version list ([1,2,3]) that predates migrations 4 and 5.

None of these are touched by this PR's diff and are out of scope for #263.

Notes for Reviewers

  • Kept this additive and self-contained: no existing exports (insertEventBatch, getLastIndexedLedger, etc.) were modified, so the live poll path is unaffected.
  • Deliberately did not reuse ledger-range-tracker.ts's validateLedgerRange/resolveHistoricalLedgerRangeledger-range-tracker.ts imports from db.ts, so importing back would create a circular dependency. The validation logic here is intentionally small and scoped to this module.
  • The pre-existing test failures listed above are flagged for visibility but left untouched per issue scope.

Closes #263

@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@solaawojobi00-bit Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…m event imports

Add validated start/end ledger range support to the schema manager so
operators can import a custom historical window of events without
disturbing the live indexer pointer, plus a helper to assert indexed
event counts for that range.
Rebasing onto upstream/main pulled in migrations 4-6, exposing two
pre-existing bugs in this branch's copy of sqlite-schema-manager.test.ts
that predate this PR: an undefined SCHEMA_MANAGER_INDEXES reference (now
exported from db.ts) and a stale hardcoded migration-version assertion
(now derived from getShippedMigrationVersions()).
@solaawojobi00-bit
solaawojobi00-bit force-pushed the fix/issue-263-sqlite-schema-manager-historical-ranges branch from fb5f3c8 to 7d85833 Compare August 30, 2026 03:09
@godamongstmen897 godamongstmen897 closed this pull request by merging all changes into Goldii-locks:main in 9e42e6f Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configure dynamic historical sync ranges in sqlite_schema_manager

2 participants