@@ -1771,6 +1771,7 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r
1771
1771
CWallet::ScanResult CWallet::ScanForWalletTransactions (const uint256& start_block, const uint256& stop_block, const WalletRescanReserver& reserver, bool fUpdate )
1772
1772
{
1773
1773
int64_t nNow = GetTime ();
1774
+ int64_t start_time = GetTimeMillis ();
1774
1775
1775
1776
assert (reserver.isReserved ());
1776
1777
@@ -1779,90 +1780,90 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
1779
1780
1780
1781
WalletLogPrintf (" Rescan started from block %s...\n " , start_block.ToString ());
1781
1782
1783
+ fAbortRescan = false ;
1784
+ ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), 0 ); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
1785
+ uint256 tip_hash;
1786
+ // The way the 'block_height' is initialized is just a workaround for the gcc bug #47679 since version 4.6.0.
1787
+ Optional<int > block_height = MakeOptional (false , int ());
1788
+ double progress_begin;
1789
+ double progress_end;
1782
1790
{
1783
- fAbortRescan = false ;
1784
- ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), 0 ); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
1785
- uint256 tip_hash;
1786
- // The way the 'block_height' is initialized is just a workaround for the gcc bug #47679 since version 4.6.0.
1787
- Optional<int > block_height = MakeOptional (false , int ());
1788
- double progress_begin;
1789
- double progress_end;
1790
- {
1791
- auto locked_chain = chain ().lock ();
1792
- if (Optional<int > tip_height = locked_chain->getHeight ()) {
1793
- tip_hash = locked_chain->getBlockHash (*tip_height);
1794
- }
1795
- block_height = locked_chain->getBlockHeight (block_hash);
1796
- progress_begin = chain ().guessVerificationProgress (block_hash);
1797
- progress_end = chain ().guessVerificationProgress (stop_block.IsNull () ? tip_hash : stop_block);
1798
- }
1799
- double progress_current = progress_begin;
1800
- while (block_height && !fAbortRescan && !chain ().shutdownRequested ()) {
1801
- if (*block_height % 100 == 0 && progress_end - progress_begin > 0.0 ) {
1802
- ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), std::max (1 , std::min (99 , (int )((progress_current - progress_begin) / (progress_end - progress_begin) * 100 ))));
1803
- }
1804
- if (GetTime () >= nNow + 60 ) {
1805
- nNow = GetTime ();
1806
- WalletLogPrintf (" Still rescanning. At block %d. Progress=%f\n " , *block_height, progress_current);
1807
- }
1791
+ auto locked_chain = chain ().lock ();
1792
+ if (Optional<int > tip_height = locked_chain->getHeight ()) {
1793
+ tip_hash = locked_chain->getBlockHash (*tip_height);
1794
+ }
1795
+ block_height = locked_chain->getBlockHeight (block_hash);
1796
+ progress_begin = chain ().guessVerificationProgress (block_hash);
1797
+ progress_end = chain ().guessVerificationProgress (stop_block.IsNull () ? tip_hash : stop_block);
1798
+ }
1799
+ double progress_current = progress_begin;
1800
+ while (block_height && !fAbortRescan && !chain ().shutdownRequested ()) {
1801
+ if (*block_height % 100 == 0 && progress_end - progress_begin > 0.0 ) {
1802
+ ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), std::max (1 , std::min (99 , (int )((progress_current - progress_begin) / (progress_end - progress_begin) * 100 ))));
1803
+ }
1804
+ if (GetTime () >= nNow + 60 ) {
1805
+ nNow = GetTime ();
1806
+ WalletLogPrintf (" Still rescanning. At block %d. Progress=%f\n " , *block_height, progress_current);
1807
+ }
1808
1808
1809
- CBlock block;
1810
- if (chain ().findBlock (block_hash, &block) && !block.IsNull ()) {
1811
- auto locked_chain = chain ().lock ();
1812
- LOCK (cs_wallet);
1813
- if (!locked_chain->getBlockHeight (block_hash)) {
1814
- // Abort scan if current block is no longer active, to prevent
1815
- // marking transactions as coming from the wrong block.
1816
- // TODO: This should return success instead of failure, see
1817
- // https://github.com/bitcoin/bitcoin/pull/14711#issuecomment-458342518
1818
- result.last_failed_block = block_hash;
1819
- result.status = ScanResult::FAILURE;
1820
- break ;
1821
- }
1822
- for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
1823
- SyncTransaction (block.vtx [posInBlock], block_hash, posInBlock, fUpdate );
1824
- }
1825
- // scan succeeded, record block as most recent successfully scanned
1826
- result.last_scanned_block = block_hash;
1827
- result.last_scanned_height = *block_height;
1828
- } else {
1829
- // could not scan block, keep scanning but record this block as the most recent failure
1809
+ CBlock block;
1810
+ if (chain ().findBlock (block_hash, &block) && !block.IsNull ()) {
1811
+ auto locked_chain = chain ().lock ();
1812
+ LOCK (cs_wallet);
1813
+ if (!locked_chain->getBlockHeight (block_hash)) {
1814
+ // Abort scan if current block is no longer active, to prevent
1815
+ // marking transactions as coming from the wrong block.
1816
+ // TODO: This should return success instead of failure, see
1817
+ // https://github.com/bitcoin/bitcoin/pull/14711#issuecomment-458342518
1830
1818
result.last_failed_block = block_hash;
1831
1819
result.status = ScanResult::FAILURE;
1820
+ break ;
1821
+ }
1822
+ for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
1823
+ SyncTransaction (block.vtx [posInBlock], block_hash, posInBlock, fUpdate );
1832
1824
}
1833
- if (block_hash == stop_block) {
1825
+ // scan succeeded, record block as most recent successfully scanned
1826
+ result.last_scanned_block = block_hash;
1827
+ result.last_scanned_height = *block_height;
1828
+ } else {
1829
+ // could not scan block, keep scanning but record this block as the most recent failure
1830
+ result.last_failed_block = block_hash;
1831
+ result.status = ScanResult::FAILURE;
1832
+ }
1833
+ if (block_hash == stop_block) {
1834
+ break ;
1835
+ }
1836
+ {
1837
+ auto locked_chain = chain ().lock ();
1838
+ Optional<int > tip_height = locked_chain->getHeight ();
1839
+ if (!tip_height || *tip_height <= block_height || !locked_chain->getBlockHeight (block_hash)) {
1840
+ // break successfully when rescan has reached the tip, or
1841
+ // previous block is no longer on the chain due to a reorg
1834
1842
break ;
1835
1843
}
1836
- {
1837
- auto locked_chain = chain ().lock ();
1838
- Optional<int > tip_height = locked_chain->getHeight ();
1839
- if (!tip_height || *tip_height <= block_height || !locked_chain->getBlockHeight (block_hash)) {
1840
- // break successfully when rescan has reached the tip, or
1841
- // previous block is no longer on the chain due to a reorg
1842
- break ;
1843
- }
1844
1844
1845
- // increment block and verification progress
1846
- block_hash = locked_chain->getBlockHash (++*block_height);
1847
- progress_current = chain ().guessVerificationProgress (block_hash);
1845
+ // increment block and verification progress
1846
+ block_hash = locked_chain->getBlockHash (++*block_height);
1847
+ progress_current = chain ().guessVerificationProgress (block_hash);
1848
1848
1849
- // handle updated tip hash
1850
- const uint256 prev_tip_hash = tip_hash;
1851
- tip_hash = locked_chain->getBlockHash (*tip_height);
1852
- if (stop_block.IsNull () && prev_tip_hash != tip_hash) {
1853
- // in case the tip has changed, update progress max
1854
- progress_end = chain ().guessVerificationProgress (tip_hash);
1855
- }
1849
+ // handle updated tip hash
1850
+ const uint256 prev_tip_hash = tip_hash;
1851
+ tip_hash = locked_chain->getBlockHash (*tip_height);
1852
+ if (stop_block.IsNull () && prev_tip_hash != tip_hash) {
1853
+ // in case the tip has changed, update progress max
1854
+ progress_end = chain ().guessVerificationProgress (tip_hash);
1856
1855
}
1857
1856
}
1858
- ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), 100 ); // hide progress dialog in GUI
1859
- if (block_height && fAbortRescan ) {
1860
- WalletLogPrintf (" Rescan aborted at block %d. Progress=%f\n " , *block_height, progress_current);
1861
- result.status = ScanResult::USER_ABORT;
1862
- } else if (block_height && chain ().shutdownRequested ()) {
1863
- WalletLogPrintf (" Rescan interrupted by shutdown request at block %d. Progress=%f\n " , *block_height, progress_current);
1864
- result.status = ScanResult::USER_ABORT;
1865
- }
1857
+ }
1858
+ ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), 100 ); // hide progress dialog in GUI
1859
+ if (block_height && fAbortRescan ) {
1860
+ WalletLogPrintf (" Rescan aborted at block %d. Progress=%f\n " , *block_height, progress_current);
1861
+ result.status = ScanResult::USER_ABORT;
1862
+ } else if (block_height && chain ().shutdownRequested ()) {
1863
+ WalletLogPrintf (" Rescan interrupted by shutdown request at block %d. Progress=%f\n " , *block_height, progress_current);
1864
+ result.status = ScanResult::USER_ABORT;
1865
+ } else {
1866
+ WalletLogPrintf (" Rescan completed in %15dms\n " , GetTimeMillis () - start_time);
1866
1867
}
1867
1868
return result;
1868
1869
}
@@ -4245,15 +4246,13 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
4245
4246
}
4246
4247
}
4247
4248
4248
- nStart = GetTimeMillis ();
4249
4249
{
4250
4250
WalletRescanReserver reserver (walletInstance.get ());
4251
4251
if (!reserver.reserve () || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions (locked_chain->getBlockHash (rescan_height), {} /* stop block */ , reserver, true /* update */ ).status )) {
4252
4252
chain.initError (_ (" Failed to rescan the wallet during initialization" ));
4253
4253
return nullptr ;
4254
4254
}
4255
4255
}
4256
- walletInstance->WalletLogPrintf (" Rescan completed in %15dms\n " , GetTimeMillis () - nStart);
4257
4256
walletInstance->ChainStateFlushed (locked_chain->getTipLocator ());
4258
4257
walletInstance->database ->IncrementUpdateCounter ();
4259
4258
0 commit comments