sync: clamp suggested scan ranges to the current chain tip in initialize#640
Open
pacu wants to merge 1 commit into
Open
sync: clamp suggested scan ranges to the current chain tip in initialize#640pacu wants to merge 1 commit into
pacu wants to merge 1 commit into
Conversation
The wallet database can record a higher chain tip than the current chain view serves (e.g. Zebra's read-only secondary exposing finalized state that lags what the wallet observed before a restart). In that state suggest_scan_ranges returns ranges starting above the tip; steps::scan_blocks has nothing to scan for them and returns Ok without progress, so the initialize catch-up loop re-ran instantly with no state change - pinning a core and logging tens of lines per second until the chain view happened to advance past the range. Clamp every suggested range to the current tip when selecting the next range to scan: a partially-available range scans its available prefix (real progress), and a range entirely above the tip is dropped so the existing no-range arm exits initialize to steady_state, which waits for chain tip changes properly. Selection logic is extracted into select_initial_scan_range and unit-tested, including the reported repro (range 3413618..3414133 against tip 3413617). Fixes #636. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017WB1TU6tyLmMa1n4SQ9XgK
pacu
marked this pull request as ready for review
July 17, 2026 12:54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #636.
Summary
initialize's catch-up loop busy-looped at full speed — pinning a core and writing ~40 log lines/second indefinitely — wheneversuggest_scan_rangesreturned a range starting above the current chain view's tip.scan_blockshas nothing to scan for such a range and returnsOkwithout breaking, and theOk(_)arm re-ran the loop instantly with no state change, so nothing inside the loop could ever resolve the condition (as reported:Scanning blocks Historic(3413618..3414133)againstLatest block height is 3413617, repeating indefinitely).The wallet database can legitimately be ahead of the chain view: it records the highest tip it has ever observed, while Zebra's read-only secondary serves finalized on-disk state that can lag (or effectively regress across a restart).
Fix
Clamp every suggested range to the current tip when selecting the next range to scan (
select_initial_scan_range, extracted for testability):initializetosteady_state, which waits for chain-tip changes properly instead of polling.This also covers the silent variant of the same spin where
tree_state_as_of(start - 1)returnsNone(range starting more than one block above the tip), which previously re-looped without even logging.Verification
select_initial_scan_range, including the reported repro (range3413618..3414133against tip3413617→ dropped), straddle clamping, Verify-vs-Historic boundary handling, and above-tip ranges not masking later scannable candidates.cargo test -p zallet-core: 201 passed.wallet_z_shieldcoinbase.py(fresh-walletinitialize+ 100-block catch-up scan) passes against a release build of this branch on the zebrad+zainod regtest stack.🤖 Generated with Claude Code
https://claude.ai/code/session_017WB1TU6tyLmMa1n4SQ9XgK