Conversation
A quit issued while a sync was in flight waited behind the scan: the save loop observes its shutdown flag only after it wins the wallet write lock and completes a full save, and nothing told the sync task to stop. On a fresh wallet's initial sync the session spun on "quit: working" until it was killed. This serves ZIN-70. quit now stops the sync task first and awaits the engine's answer, and only then drains the save task, whose next cycle wins the lock promptly. A network-bound acceptance test, ignored by default, drives a real session against a mainnet indexer, issues quit mid-sync, and asserts the process exits within a bounded time and leaves a wallet file a fresh session loads. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The review of the quit-interrupts-sync fix (PR #2746, ZIN-70) confirmed six findings, and this change resolves all of them, with each behavioral fix proven by a test that failed before it. zingolib gains LightClient::shutdown_sync, a bounded graceful stop that reads the task through poll_sync and aborts the engine when it outlives the bound, reporting the outcome as the new SyncShutdown enum. Unlike await_sync, the interrupted path never captures part witnesses over half-synced state, and the typed outcome ends the mislabeled "sync stop failed" report. A falsifier with a fabricated wedged sync task pins the bound. quit now drives shutdown_sync, and the interactive session's Ctrl-C, Ctrl-D, and terminal-error arms dispatch the same quit teardown before breaking, so no exit path abandons the sync task or skips the save drain. A new offline acceptance test ends a session by closing stdin and asserts the teardown's trailer. The mid-sync acceptance test now holds quit until pepper-sync reports a scanned batch processed, so it cannot pass by quitting during pre-scan initialization; its session inherits stdout and stderr so failures carry the session's own words; and the constants and proxy resolution it shared verbatim with sync_bench_cli.rs now live once in a shared support module. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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 ZIN-70: https://linear.app/zingo-mobile/issue/ZIN-70/quit-hangs-during-sync-the-save-task-shutdown-waits-behind-the-scan
Problem
quitdrained only the save task. The save loop observes its shutdown flag only after it wins the wallet write lock and completes a full save. During a sync the scan holds that lock for long stretches. Nothing told the sync task to stop. On a fresh wallet's initial sync the session spun onquit: workinguntil the user killed it.Fix
quitnow stops the sync task first and awaits the engine's answer. Only then does it drain the save task. The save loop's next cycle wins the lock promptly and the shutdown completes.Verification
cargo check,clippy, andfmtare clean. A new acceptance test,zingo-cli/tests/quit_mid_sync.rs, drives a real session against a mainnet indexer. It issuesquitafter the sync span opens. It asserts the process exits within a bounded time and leaves a wallet file a fresh session loads. The test is network-bound and ignored by default.🤖 Generated with Claude Code