@@ -1814,7 +1814,11 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
1814
1814
uint256 block_hash = start_block;
1815
1815
ScanResult result;
1816
1816
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" );
1818
1822
1819
1823
fAbortRescan = false ;
1820
1824
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
1841
1845
WalletLogPrintf (" Still rescanning. At block %d. Progress=%f\n " , block_height, progress_current);
1842
1846
}
1843
1847
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
+ }
1847
1858
1848
1859
// Find next block separately from reading data above, because reading
1849
1860
// is slow and there might be a reorg while it is read.
@@ -1852,35 +1863,41 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
1852
1863
uint256 next_block_hash;
1853
1864
chain ().findBlock (block_hash, FoundBlock ().inActiveChain (block_still_active).nextBlock (FoundBlock ().inActiveChain (next_block).hash (next_block_hash)));
1854
1865
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;
1870
1886
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);
1873
1889
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
+ }
1878
1895
}
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;
1879
1900
}
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;
1884
1901
}
1885
1902
if (max_height && block_height >= *max_height) {
1886
1903
break ;
0 commit comments