Skip to content

Scan full history on initial API restore - #710

Merged
abdrasulov merged 1 commit into
masterfrom
fix/api-restore-stop-height
Aug 10, 2026
Merged

abdrasulov merged 1 commit into
masterfrom
fix/api-restore-stop-height

Conversation

@abdrasulov

@abdrasulov abdrasulov commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

A failed first restore attempt (e.g. rate-limited under parallel multi-coin restore) leaves block hashes in storage; the retry then used their height as the stop-height cutoff and skipped all older history for keys discovered via gap expansion, permanently losing their transactions — observed as missing sends and an inflated balance. Apply the cutoff only to incremental re-scans of an already-restored wallet, and fail the sync instead of silently dropping transactions whose block hash cannot be resolved.

Part of horizontalsystems/unstoppable-wallet-android#9440.

A failed first restore attempt leaves block hashes in storage; using
their height as the stop-height cutoff on retry skipped all older
history for keys discovered via gap expansion, permanently losing
their transactions. Apply the cutoff only to incremental re-scans of
a restored wallet, and fail the sync instead of silently dropping
transactions whose block hash cannot be resolved.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an API-restore edge case where a failed initial restore could leave partial block-hash state in storage; a retry would then incorrectly apply a height cutoff and skip older history for later-discovered keys (via gap expansion), causing permanently missing transactions and incorrect balances.

Changes:

  • Apply the stop-height cutoff only after the wallet has been successfully restored (ApiSyncStateManager.restored), so initial restores always scan full history.
  • Fail the sync when confirmed transaction heights cannot be resolved to block hashes, instead of silently dropping those transactions.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/apisync/blockchair/BlockchairTransactionProvider.kt Enforces “all confirmed heights must resolve” by throwing on missing block hashes rather than filtering out transactions.
bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/apisync/blockchair/BlockchairApiSyncer.kt Makes stopHeight nullable and only sets it for incremental re-scans after a successful initial restore.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@abdrasulov
abdrasulov merged commit 2cb6e40 into master Aug 10, 2026
2 checks passed
@abdrasulov
abdrasulov deleted the fix/api-restore-stop-height branch August 10, 2026 11:51
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.

3 participants