feat(wallet): optional background auto-consolidation (Settings toggle)

A mining/pool wallet can accumulate tens of thousands of shielded notes, and the
manual "Consolidate" run — capped at 20 batches per address per click — needs
many re-runs to flatten a 10k+ note address. This adds a hands-off alternative:
a Settings toggle ("Auto-consolidate notes", full-node, off by default) that
trickle-merges notes in the background while the wallet is idle, so it sheds
notes over hours/days without the user ever opening the dialog.

Deliberately gentle, per the request: a small batch (15 inputs/tx vs 50 manual)
and only 3 batches per address per cycle, with cycles ~10 min apart — each cycle
is a handful of tiny merges that barely touch the node. It only acts when the
wallet is genuinely idle (walletScanReady: connected, synced, unlocked, node not
busy, not rescanning) and no send / shield / manual run is in progress, and it
goes dormant (re-scanning hourly) once every address is tidy.

Implementation reuses the existing paced services::ConsolidationRun engine in
"keep in each address" mode, so there is NO fund-path change and the run's
pacing / failure breakers / note-locking all apply:
- App::pumpAutoConsolidation (pumped from update() after pumpConsolidation):
  finalizes a finished cycle (schedules the cooldown + dismisses the run so the
  manual dialog never shows a stale auto result), else starts a new cycle when
  idle and the cooldown has elapsed.
- postAutoConsolidationScan: a quiet z_listunspent scan (the dialog's loadScope
  minus the UI state), session-guarded; on result picks candidates and starts.
- startConsolidationQuiet: the same guards as startConsolidation but silent, with
  a gentle RunConfig; finishConsolidation stays silent for auto runs (logs only).
- services::autoConsolidateCandidates (pure, unit-tested): addresses above the
  note floor that are worth merging; plus the gentle kAutoConsolidate* constants.
- The one-time large-wallet nudge is suppressed while auto-consolidation is on.

Settings plumbing (auto_consolidate, default false) + a daemon-gated toggle in
the Wallet tab's options, with a tooltip. Build + tests + hygiene green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 13:18:00 -05:00
co-authored by Claude Opus 4.8
parent 54f8359bd4
commit 64294d1518
10 changed files with 167 additions and 0 deletions
+2
View File
@@ -1592,6 +1592,8 @@ void App::update()
if (send_progress_active_ && !addressScanCanRunNow()) maybeFinishTransactionSendProgress();
// C210: the "Keep in each address" consolidation run, if one is going (paced; one RPC at a time).
pumpConsolidation();
// Background auto-consolidation (settings toggle): gently trickle-merge notes when the wallet is idle.
pumpAutoConsolidation();
// 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.