fix(fullnode): reliable rescan completion + self-explaining shielded send errors
Two related fixes for the post-bootstrap "send fails / rescan stuck at 99%" trap: 1) Rescan completion now keys off warmup-end. A -rescan runs entirely inside daemon warmup (every RPC returns -28 until it finishes), so warmup completing IS the rescan completing. The old detectors relied on getrescaninfo (which some daemons answer with "Method not found") or a "Done rescanning"/bench log line the daemon may never print, leaving the status bar stuck at 99% — so users killed the rescan before it finished. When warmup ends and a rescan was confirmed active, clear the rescan state, flip to 100%, refresh history/balance, and toast completion. 2) z_sendmany failures that mean stale shielded note data (shielded-requirements-not-met, missing sapling anchor, invalid sapling spend proof, bad-txns-sapling-*) now append a plain-language hint telling the user to run a full rescan, instead of surfacing only the raw daemon string. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1144,6 +1144,26 @@ void App::refreshCoreData()
|
||||
state_.warmup_description.clear();
|
||||
connection_status_ = TR("connected");
|
||||
VERBOSE_LOGF("[warmup] Daemon ready, warmup complete\n");
|
||||
|
||||
// A -rescan runs entirely INSIDE daemon warmup (every RPC returns -28 until the
|
||||
// scan finishes), so warmup completing IS the rescan completing. This is the
|
||||
// reliable completion signal: some daemons lack getrescaninfo (it returns
|
||||
// "Method not found") or never print a "Done rescanning"/bench line, which left
|
||||
// the older detectors stuck at 99% — the user would then kill it prematurely.
|
||||
// rescan_confirmed_active_ ensures we actually observed this rescan running (set
|
||||
// by the getrescaninfo / daemon-log pollers) before declaring it done.
|
||||
if (state_.sync.rescanning && rescan_confirmed_active_) {
|
||||
state_.sync.rescanning = false;
|
||||
rescan_confirmed_active_ = false;
|
||||
state_.sync.rescan_progress = 1.0f;
|
||||
state_.sync.rescan_status.clear();
|
||||
// Notes/witnesses were rebuilt — force a fresh history + balance pull.
|
||||
transactions_dirty_ = true;
|
||||
last_tx_block_height_ = -1;
|
||||
invalidateShieldedHistoryScanProgress(true);
|
||||
ui::Notifications::instance().success("Blockchain rescan complete");
|
||||
}
|
||||
|
||||
NetworkRefreshService::applyConnectionInfoResult(state_, result.info);
|
||||
// Trigger full data refresh now that daemon is ready
|
||||
refreshData();
|
||||
|
||||
Reference in New Issue
Block a user