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:
@@ -18030,6 +18030,23 @@ void testWalletScanGovernor()
|
||||
EXPECT_TRUE(static_cast<bool>(gov.tryAdmit(ScanStream::Balance, true, sig, 372.0)));
|
||||
EXPECT_FALSE(gov.waiting(ScanStream::Balance, 373.0)); // admitted: no longer waiting
|
||||
}
|
||||
{ // Suppression: a paused routine stream is never admitted (but keeps waiting); explicit needs bypass
|
||||
// it; unpausing admits it again. Used to give a user consolidation the cs_main budget.
|
||||
G gov;
|
||||
gov.suppressRoutineWalletScans(true);
|
||||
EXPECT_TRUE(gov.streamSuppressed(ScanStream::Balance));
|
||||
EXPECT_FALSE(static_cast<bool>(gov.tryAdmit(ScanStream::Balance, true, sig, 0.0))); // paused: not admitted
|
||||
EXPECT_TRUE(gov.waiting(ScanStream::Balance, 0.1)); // ...but still waiting
|
||||
auto ex = gov.beginExplicit(ScanStream::Balance, sig, 0.2); // explicit bypasses it
|
||||
EXPECT_TRUE(static_cast<bool>(ex));
|
||||
gov.complete(ex, 0.0, ScanOutcome::Skipped, 0.3);
|
||||
gov.suppressRoutineWalletScans(false);
|
||||
EXPECT_FALSE(gov.streamSuppressed(ScanStream::Balance));
|
||||
EXPECT_TRUE(static_cast<bool>(gov.tryAdmit(ScanStream::Balance, true, sig, 0.4))); // resumes once unpaused
|
||||
// Chat scans and Adhoc (the merges themselves) are never in the suppressed group.
|
||||
EXPECT_FALSE(gov.streamSuppressed(ScanStream::ChatNotes));
|
||||
EXPECT_FALSE(gov.streamSuppressed(ScanStream::Adhoc));
|
||||
}
|
||||
}
|
||||
|
||||
// The between-blocks probe's rotation: every z-address once (oldest-scanned first) before it is done.
|
||||
|
||||
Reference in New Issue
Block a user