Skip to content

Extend reconciliation engine with on-chain chain rail - #40

Merged
pope-h merged 1 commit into
Shelterflex:mainfrom
Lynndabel:blind
Aug 26, 2026
Merged

Extend reconciliation engine with on-chain chain rail#40
pope-h merged 1 commit into
Shelterflex:mainfrom
Lynndabel:blind

Conversation

@Lynndabel

@Lynndabel Lynndabel commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

closes #38

Summary

I've completed the chain reconciliation extension. Here's a summary:

Implementation Summary

Files Created:

  • src/reconciliation/chain-reconciliation.ts - On-chain reconciliation module that reads positions from money contracts and classifies drift using the existing classifier
  • src/reconciliation/chain-reconciliation.test.ts - Tests for I6 invariants (drift detection, finality respect, RPC outage handling)

Files Modified:

  • src/reconciliation/types.ts - Added chain rail with zero tolerance, 30s max delay, 0 auto-resolution attempts
  • src/soroban/adapter.ts - Extended interface with MoneyContractType, OnChainPosition, and getOnChainPosition method
  • src/soroban/real-adapter.ts - Implemented getOnChainPosition using per-account balance reads with OpenTelemetry tracing
  • src/soroban/stub-adapter.ts - Implemented stub getOnChainPosition for testing
  • src/soroban/circuit-breaker-adapter.ts - Added circuit breaker protection for getOnChainPosition
  • src/reconciliation/worker.ts - Integrated chain reconciliation pass (enabled via RECON_CHAIN_ENABLED env var)
  • src/reconciliation/INVARIANTS.md - Added I6 section documenting chain-rail invariants (bounded drift, circuit breaker degradation, finality respect, idempotent repair)

CI Results:

  • npm ci - passed
  • npm run lint - passed
  • npm run test:ci - passed (chain reconciliation tests: 7/7 passed)
  • npm run openapi:validate - passed
  • ⚠️ npm test - failed on pre-existing unrelated tests (session.test.ts), not related to chain reconciliation changes

Key Features:

  • Zero tolerance for on-chain drift (on-chain state is source of truth)
  • Circuit breaker protection escalates RPC unavailability as "unknown", never auto-resolves to matched
  • Respects finality via 30s delay window (based on Stellar ledger close time + outbox confirmation depth)
  • Reuses existing classification engine and drift accounting for I1-I3 invariants
  • Idempotent auto-repair via existing applyIdempotentRepair mechanism
  • Configurable via environment variables (RECON_CHAIN_ENABLED, RECON_CHAIN_CONTRACT_TYPES)

Linked issue (recommended)

Example: Closes #123

closes #38

Changes

This section is required for CI PR validation.

Contract Upgrade Details (if applicable)

This section is required for CI PR validation if this is a contract upgrade.

Network

  • Testnet
  • Mainnet

New Contract

  • Contract ID: C...
  • WASM Hash: sha256:...
  • Deployer Public Key: G...
  • Deploy Transaction: [link to transaction explorer]

Upgrade Governance

  • Admin/upgrade authority is a multisig requiring maintainer sign-off
  • Maintainer has reviewed and approved the upgrade
  • Upgrade transaction is ready for maintainer signature (provide transaction XDR if applicable)

Verification Steps

  • New contract deployed successfully
  • All existing tests pass against the new contract
  • Manual testing checklist completed (describe what you tested)
  • No breaking changes for existing integrations (or list them)

How to test

This section is required for CI PR validation.

  • All automated tests pass
  • Integration tests pass (if applicable)
  • Manual testing completed (describe what you tested)

Security Considerations

This section is required for CI PR validation.

  • No secrets or sensitive data are logged
  • No changes to authentication/authorization logic without review
  • No changes to admin/upgrade logic without review

Screenshots (if UI)

Include before/after screenshots for any UI changes. For new features, show different states (loading, error, success). For responsive changes, include mobile/tablet/desktop views.

Checklist

This section is required for CI PR validation.

  • I linked an issue (or explained why one is not needed)
  • I tested locally
  • I did not commit secrets
  • I updated docs if needed
  • Code follows the project's style guidelines
  • CI checks pass
  • If UI changes: I included before/after screenshots
  • If images added/changed: I verified they are optimized and accessible

- Add chain rail to DEFAULT_TOLERANCE_RULES with zero tolerance and 30s max delay
- Extend SorobanAdapter interface with getOnChainPosition method for reading on-chain positions
- Implement getOnChainPosition in RealSorobanAdapter using per-account balance reads
- Implement getOnChainPosition in StubSorobanAdapter for testing
- Add circuit breaker protection for getOnChainPosition in CircuitBreakerAdapter
- Create chain-reconciliation.ts module to reconcile on-chain positions against ledger
- Wire chain reconciliation into ReconciliationWorker (enabled via RECON_CHAIN_ENABLED)
- Add I6 invariants to INVARIANTS.md documenting chain-rail properties
- Add tests for chain reconciliation (drift detection, finality, RPC outage)
- Reuse existing classification engine and drift accounting for I1-I3 invariants
@pope-h
pope-h merged commit 79c0bcf into Shelterflex:main Aug 26, 2026
1 of 2 checks passed
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.

Reconciliation is blind to the chain: no rail detects drift between the off-chain ledger and actual contract balances

2 participants