Skip to content

feat: reconcile indexed chain state#93

Open
barry01-hash wants to merge 1 commit into
StepFi-app:mainfrom
barry01-hash:feat/state-reconciliation
Open

feat: reconcile indexed chain state#93
barry01-hash wants to merge 1 commit into
StepFi-app:mainfrom
barry01-hash:feat/state-reconciliation

Conversation

@barry01-hash

@barry01-hash barry01-hash commented Jul 18, 2026

Copy link
Copy Markdown

Closes #80

What changed

  • adds a guarded 15-minute state reconciliation job using indexed chain events as authority
  • reconciles provisional loan IDs, stale loan status, liquidity positions, and reputation projections
  • backfills missed transaction records and resolves orphaned pending transactions
  • exports drift gauges by mismatch type and logs structured drift reports
  • stores loan event transaction hashes and ledger sequences through a new migration
  • makes the existing health unit test deterministic to remove its live-Horizon CI timeout

Architecture note

The issue requested BullMQ, but this repository's required architecture explicitly prohibits reintroducing BullMQ after its Redis polling exhausted the Upstash quota. This implementation uses NestJS @Cron with an overlap guard and caught errors, matching the current background-job standard.

The reconciliation path performs no on-chain writes.

Validation

  • npm run build
  • npm test -- --runInBand (25 suites, 292 tests)
  • ESLint on all touched TypeScript files
  • no new explicit any types
  • migration included

Closes #80

@barry01-hash
barry01-hash marked this pull request as ready for review July 18, 2026 11:23
@barry01-hash
barry01-hash requested a review from EmeditWeb as a code owner July 18, 2026 11:23
@barry01-hash

Copy link
Copy Markdown
Author

Please merge

@EmeditWeb EmeditWeb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review verdict: ✅ APPROVE with notes

Solid reconciliation job. @Cron('0 */15 * * * *') (not BullMQ), overlap guard, no any, tests included (+132). Verified the write paths: reconciliation is chain → DB only and iterates over the authoritative on-chain set, so a failed/empty read is a no-op loop — it never zeroes or corrupts existing rows (safe failure direction). Errors throw rather than silently continue. Transaction status resolution (missing/orphaned/pending) and liquidity/reputation correction all look reasonable.

Notes before merge:

  1. The financial DB writes (liquidity_positions.deposited_amount, reputation_cache.score) are only as correct as src/indexer/authoritative-state.reader.ts. That 114-line reader now drives money/credit-state writes — please give it a focused review (it's the single point of truth for these overwrites).
  2. Reconciliation only writes rows present on-chain; DB rows with no on-chain counterpart are left as-is (conservative — fine, just note it).
  3. The 30-minute cutoff that marks a pending transaction orphaned/failed — confirm a slow-but-valid submission can't be prematurely orphaned under network latency.

No blockers; approve once the reader has had a look.

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.

core: implement on-chain to database state reconciliation job

2 participants