Skip to content

Commit 4818da8

Browse files
mzumsandepsgreco
andcommitted
wallet: fix rescanning inconsistency
If the chain advances during a rescan, ScanForWalletTransactions would previously process the new blocks without adjusting m_last_processed_block, which would leave the wallet in an inconsistent state temporarily, and could lead to crashes in the GUI. Fix this by not rescanning blocks beyond the last_processed_block - for all blocks beyond that height, there will be pending BlockConnected notifications that will process them after the rescan is finished. Co-authored-by: Pablo Greco <[email protected]>
1 parent 41a2ce9 commit 4818da8

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/wallet/wallet.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,14 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
19841984
if (max_height && block_height >= *max_height) {
19851985
break;
19861986
}
1987+
// If rescanning was triggered with cs_wallet permanently locked (AttachChain), additional blocks that were connected during the rescan
1988+
// aren't processed here but will be processed with the pending blockConnected notifications after the lock is released.
1989+
// If rescanning without a permanent cs_wallet lock, additional blocks that were added during the rescan will be re-processed if
1990+
// the notification was processed and the last block height was updated.
1991+
if (block_height >= WITH_LOCK(cs_wallet, return GetLastBlockHeight())) {
1992+
break;
1993+
}
1994+
19871995
{
19881996
if (!next_block) {
19891997
// break successfully when rescan has reached the tip, or
@@ -3266,12 +3274,12 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
32663274
}
32673275

32683276
// Register wallet with validationinterface. It's done before rescan to avoid
3269-
// missing block connections between end of rescan and validation subscribing.
3270-
// Because of wallet lock being hold, block connection notifications are going to
3271-
// be pending on the validation-side until lock release. It's likely to have
3272-
// block processing duplicata (if rescan block range overlaps with notification one)
3273-
// but we guarantee at least than wallet state is correct after notifications delivery.
3274-
// However, chainStateFlushed notifications are ignored until the rescan is finished
3277+
// missing block connections during the rescan.
3278+
// Because of the wallet lock being held, block connection notifications are going to
3279+
// be pending on the validation-side until lock release. Blocks that are connected while the
3280+
// rescan is ongoing will not be processed in the rescan but with the block connected notifications,
3281+
// so the wallet will only be completeley synced after the notifications delivery.
3282+
// chainStateFlushed notifications are ignored until the rescan is finished
32753283
// so that in case of a shutdown event, the rescan will be repeated at the next start.
32763284
// This is temporary until rescan and notifications delivery are unified under same
32773285
// interface.

0 commit comments

Comments
 (0)