@@ -1814,7 +1814,11 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
18141814 uint256 block_hash = start_block;
18151815 ScanResult result;
18161816
1817- WalletLogPrintf (" Rescan started from block %s...\n " , start_block.ToString ());
1817+ std::unique_ptr<FastWalletRescanFilter> fast_rescan_filter;
1818+ if (!IsLegacy () && chain ().hasBlockFilterIndex (BlockFilterType::BASIC)) fast_rescan_filter = std::make_unique<FastWalletRescanFilter>(*this );
1819+
1820+ WalletLogPrintf (" Rescan started from block %s... (%s)\n " , start_block.ToString (),
1821+ fast_rescan_filter ? " fast variant using block filters" : " slow variant inspecting all blocks" );
18181822
18191823 fAbortRescan = false ;
18201824 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
18411845 WalletLogPrintf (" Still rescanning. At block %d. Progress=%f\n " , block_height, progress_current);
18421846 }
18431847
1844- // Read block data
1845- CBlock block;
1846- chain ().findBlock (block_hash, FoundBlock ().data (block));
1848+ bool fetch_block{true };
1849+ if (fast_rescan_filter) {
1850+ fast_rescan_filter->UpdateIfNeeded ();
1851+ auto matches_block{fast_rescan_filter->MatchesBlock (block_hash)};
1852+ if (matches_block.has_value () && !*matches_block) {
1853+ result.last_scanned_block = block_hash;
1854+ result.last_scanned_height = block_height;
1855+ fetch_block = false ;
1856+ }
1857+ }
18471858
18481859 // Find next block separately from reading data above, because reading
18491860 // is slow and there might be a reorg while it is read.
@@ -1852,35 +1863,41 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
18521863 uint256 next_block_hash;
18531864 chain ().findBlock (block_hash, FoundBlock ().inActiveChain (block_still_active).nextBlock (FoundBlock ().inActiveChain (next_block).hash (next_block_hash)));
18541865
1855- if (!block.IsNull ()) {
1856- LOCK (cs_wallet);
1857- if (!block_still_active) {
1858- // Abort scan if current block is no longer active, to prevent
1859- // marking transactions as coming from the wrong block.
1860- result.last_failed_block = block_hash;
1861- result.status = ScanResult::FAILURE;
1862- break ;
1863- }
1864- for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
1865- SyncTransaction (block.vtx [posInBlock], TxStateConfirmed{block_hash, block_height, static_cast <int >(posInBlock)}, fUpdate , /* rescanning_old_block=*/ true );
1866- }
1867- // scan succeeded, record block as most recent successfully scanned
1868- result.last_scanned_block = block_hash;
1869- result.last_scanned_height = block_height;
1866+ if (fetch_block) {
1867+ // Read block data
1868+ CBlock block;
1869+ chain ().findBlock (block_hash, FoundBlock ().data (block));
1870+
1871+ if (!block.IsNull ()) {
1872+ LOCK (cs_wallet);
1873+ if (!block_still_active) {
1874+ // Abort scan if current block is no longer active, to prevent
1875+ // marking transactions as coming from the wrong block.
1876+ result.last_failed_block = block_hash;
1877+ result.status = ScanResult::FAILURE;
1878+ break ;
1879+ }
1880+ for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
1881+ SyncTransaction (block.vtx [posInBlock], TxStateConfirmed{block_hash, block_height, static_cast <int >(posInBlock)}, fUpdate , /* rescanning_old_block=*/ true );
1882+ }
1883+ // scan succeeded, record block as most recent successfully scanned
1884+ result.last_scanned_block = block_hash;
1885+ result.last_scanned_height = block_height;
18701886
1871- if (save_progress && next_interval) {
1872- CBlockLocator loc = m_chain->getActiveChainLocator (block_hash);
1887+ if (save_progress && next_interval) {
1888+ CBlockLocator loc = m_chain->getActiveChainLocator (block_hash);
18731889
1874- if (!loc.IsNull ()) {
1875- WalletLogPrintf (" Saving scan progress %d.\n " , block_height);
1876- WalletBatch batch (GetDatabase ());
1877- batch.WriteBestBlock (loc);
1890+ if (!loc.IsNull ()) {
1891+ WalletLogPrintf (" Saving scan progress %d.\n " , block_height);
1892+ WalletBatch batch (GetDatabase ());
1893+ batch.WriteBestBlock (loc);
1894+ }
18781895 }
1896+ } else {
1897+ // could not scan block, keep scanning but record this block as the most recent failure
1898+ result.last_failed_block = block_hash;
1899+ result.status = ScanResult::FAILURE;
18791900 }
1880- } else {
1881- // could not scan block, keep scanning but record this block as the most recent failure
1882- result.last_failed_block = block_hash;
1883- result.status = ScanResult::FAILURE;
18841901 }
18851902 if (max_height && block_height >= *max_height) {
18861903 break ;
0 commit comments