wallet: take use of FastWalletRescanFilter

Can be reviewed with `--ignore-all-space`.
This commit is contained in:
Sebastian Falbesoner 2022-08-26 02:57:41 +02:00
parent 70b3513904
commit 935c6c4b23

View file

@ -1814,7 +1814,11 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
uint256 block_hash = start_block; uint256 block_hash = start_block;
ScanResult result; ScanResult result;
WalletLogPrintf("Rescan started from block %s...\n", start_block.ToString()); std::unique_ptr<FastWalletRescanFilter> fast_rescan_filter;
if (!IsLegacy() && chain().hasBlockFilterIndex(BlockFilterType::BASIC)) fast_rescan_filter = std::make_unique<FastWalletRescanFilter>(*this);
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; fAbortRescan = false;
ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), 0); // show rescan progress in GUI as dialog or on splashscreen, if rescan required on startup (e.g. due to corruption) ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), 0); // show rescan progress in GUI as dialog or on splashscreen, if rescan required on startup (e.g. due to corruption)
@ -1841,9 +1845,16 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", block_height, progress_current); WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", block_height, progress_current);
} }
// Read block data bool fetch_block{true};
CBlock block; if (fast_rescan_filter) {
chain().findBlock(block_hash, FoundBlock().data(block)); fast_rescan_filter->UpdateIfNeeded();
auto matches_block{fast_rescan_filter->MatchesBlock(block_hash)};
if (matches_block.has_value() && !*matches_block) {
result.last_scanned_block = block_hash;
result.last_scanned_height = block_height;
fetch_block = false;
}
}
// Find next block separately from reading data above, because reading // Find next block separately from reading data above, because reading
// is slow and there might be a reorg while it is read. // is slow and there might be a reorg while it is read.
@ -1852,35 +1863,41 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
uint256 next_block_hash; uint256 next_block_hash;
chain().findBlock(block_hash, FoundBlock().inActiveChain(block_still_active).nextBlock(FoundBlock().inActiveChain(next_block).hash(next_block_hash))); chain().findBlock(block_hash, FoundBlock().inActiveChain(block_still_active).nextBlock(FoundBlock().inActiveChain(next_block).hash(next_block_hash)));
if (!block.IsNull()) { if (fetch_block) {
LOCK(cs_wallet); // Read block data
if (!block_still_active) { CBlock block;
// Abort scan if current block is no longer active, to prevent chain().findBlock(block_hash, FoundBlock().data(block));
// marking transactions as coming from the wrong block.
if (!block.IsNull()) {
LOCK(cs_wallet);
if (!block_still_active) {
// Abort scan if current block is no longer active, to prevent
// marking transactions as coming from the wrong block.
result.last_failed_block = block_hash;
result.status = ScanResult::FAILURE;
break;
}
for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
SyncTransaction(block.vtx[posInBlock], TxStateConfirmed{block_hash, block_height, static_cast<int>(posInBlock)}, fUpdate, /*rescanning_old_block=*/true);
}
// scan succeeded, record block as most recent successfully scanned
result.last_scanned_block = block_hash;
result.last_scanned_height = block_height;
if (save_progress && next_interval) {
CBlockLocator loc = m_chain->getActiveChainLocator(block_hash);
if (!loc.IsNull()) {
WalletLogPrintf("Saving scan progress %d.\n", block_height);
WalletBatch batch(GetDatabase());
batch.WriteBestBlock(loc);
}
}
} else {
// could not scan block, keep scanning but record this block as the most recent failure
result.last_failed_block = block_hash; result.last_failed_block = block_hash;
result.status = ScanResult::FAILURE; result.status = ScanResult::FAILURE;
break;
} }
for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
SyncTransaction(block.vtx[posInBlock], TxStateConfirmed{block_hash, block_height, static_cast<int>(posInBlock)}, fUpdate, /*rescanning_old_block=*/true);
}
// scan succeeded, record block as most recent successfully scanned
result.last_scanned_block = block_hash;
result.last_scanned_height = block_height;
if (save_progress && next_interval) {
CBlockLocator loc = m_chain->getActiveChainLocator(block_hash);
if (!loc.IsNull()) {
WalletLogPrintf("Saving scan progress %d.\n", block_height);
WalletBatch batch(GetDatabase());
batch.WriteBestBlock(loc);
}
}
} else {
// could not scan block, keep scanning but record this block as the most recent failure
result.last_failed_block = block_hash;
result.status = ScanResult::FAILURE;
} }
if (max_height && block_height >= *max_height) { if (max_height && block_height >= *max_height) {
break; break;