wallet: move fAbortRescan reset into WalletRescanReserver reserve()

Reserving the wallet rescan is the first thing done when starting a rescan.
As part of the reservation, clear any leftover state from previous
rescans (reset fAbortRescan). This prevents a race condition
where an abort request arrives before the rescan loop starts; without
this reset, the abort could be ignored and the rescan would proceed.

Co-authored-by: w0xlt <woltx@protonmail.com>
This commit is contained in:
Pol Espinasa
2026-06-11 09:59:45 +02:00
parent 5f33da9aa3
commit bc30e95163
2 changed files with 6 additions and 3 deletions

View File

@@ -1884,7 +1884,6 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
WalletLogPrintf("Rescan started from block %s... (%s)\n", start_block.ToString(),
fast_rescan_filter ? "fast variant using block filters" : "slow variant inspecting all blocks");
fAbortRescan = false;
ShowProgress(strprintf("[%s] %s", DisplayName(), _("Rescanning…")), 0); // show rescan progress in GUI as dialog or on splashscreen, if rescan required on startup (e.g. due to corruption)
uint256 tip_hash = WITH_LOCK(cs_wallet, return GetLastBlockHash());
uint256 end_hash = tip_hash;
@@ -2006,10 +2005,10 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
WITH_LOCK(cs_wallet, chain().requestMempoolTransactions(*this));
}
ShowProgress(strprintf("[%s] %s", DisplayName(), _("Rescanning…")), 100); // hide progress dialog in GUI
if (block_height && fAbortRescan) {
if (fAbortRescan) {
WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", block_height, progress_current);
result.status = ScanResult::USER_ABORT;
} else if (block_height && chain().shutdownRequested()) {
} else if (chain().shutdownRequested()) {
WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current);
result.status = ScanResult::USER_ABORT;
} else {

View File

@@ -1103,6 +1103,10 @@ public:
if (m_wallet.fScanningWallet.exchange(true)) {
return false;
}
// Discard any abort request left over from previous reservation, so
// that an abort requested while the reservation is held always applies
// to abort this rescan, even if it arrives before the scan loop starts.
m_wallet.fAbortRescan = false;
m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
m_wallet.m_scanning_start = SteadyClock::now();
m_wallet.m_scanning_progress = 0;