feat(wallet): pause routine wallet scans during a user-run consolidation

A manual consolidation's merges compete with the GUI's routine wallet scans for
the daemon's cs_main: the run won't fire the next merge while any scan is in
flight, and because each merge mutates the wallet it re-triggers the balance /
history scans, which then delay the following merge. The WalletScanGovernor
already serializes all of these one-at-a-time under a cs_main budget, so the fix
is to pause the heavy routine streams — not every RPC — while a user run owns the
budget.

WalletScanGovernor gains per-stream routine suppression (tryAdmit returns empty
for a paused stream, which keeps waiting and resumes the instant it is unpaused;
explicit needs via beginExplicit are never paused), plus a convenience that
pauses the balance / addresses / history / recent-tx group together. App::update
pauses that group while consolidation_.active() AND the run is user-started —
an auto (background) run is left gentle and untouched, and the cheap sync / peer
/ mempool / operation-status polls keep running so sync and disconnects stay
visible. The end-of-run forced balance refresh repaints once the run finishes.

Note: a manual run is bounded (≤ maxBatches per click, ~minutes), so the balance
and recent-tx views are only briefly stale — an incoming payment shows once the
run finishes or is stopped. Unit-tested (testWalletScanGovernor): a paused stream
is not admitted but keeps waiting, explicit bypasses it, unpausing re-admits, and
chat/Adhoc are never in the paused group.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 14:22:53 -05:00
co-authored by Claude Opus 4.8
parent 9335e2bffb
commit d83169c963
4 changed files with 41 additions and 0 deletions
+5
View File
@@ -1594,6 +1594,11 @@ void App::update()
pumpConsolidation();
// Background auto-consolidation (settings toggle): gently trickle-merge notes when the wallet is idle.
pumpAutoConsolidation();
// While a USER-started consolidation is running, pause the heavy routine wallet scans (balance /
// addresses / history / recent-tx) so its merges get more of the node's cs_main budget and finish
// sooner — the end-of-run refresh repaints. An auto (background) run stays gentle and is left alone, and
// explicit needs (the user's own send, a never-loaded list) still go through. Idempotent per frame.
scan_governor_.suppressRoutineWalletScans(consolidation_.active() && !auto_consolidate_run_);
// A Settings bootstrap that finished while its dialog wasn't drawn (clicked away, minimized): process it
// here so the connect and reconcile gates release and the post-bootstrap rescan is armed.