@@ -1611,8 +1611,9 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r
1611
1611
}
1612
1612
1613
1613
if (startBlock) {
1614
- const CBlockIndex* const failedBlock = ScanForWalletTransactions (startBlock, nullptr , reserver, update);
1615
- if (failedBlock) {
1614
+ const CBlockIndex *failedBlock, *stop_block;
1615
+ // TODO: this should take into account failure by ScanResult::USER_ABORT
1616
+ if (ScanResult::FAILURE == ScanForWalletTransactions (startBlock, nullptr , reserver, failedBlock, stop_block, update)) {
1616
1617
return failedBlock->GetBlockTimeMax () + TIMESTAMP_WINDOW + 1 ;
1617
1618
}
1618
1619
}
@@ -1624,18 +1625,22 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r
1624
1625
* from or to us. If fUpdate is true, found transactions that already
1625
1626
* exist in the wallet will be updated.
1626
1627
*
1627
- * Returns null if scan was successful. Otherwise, if a complete rescan was not
1628
- * possible (due to pruning or corruption), returns pointer to the most recent
1629
- * block that could not be scanned.
1628
+ * @param[in] pindexStop if not a nullptr, the scan will stop at this block-index
1629
+ * @param[out] failed_block if FAILURE is returned, the most recent block
1630
+ * that could not be scanned, otherwise nullptr
1631
+ * @param[out] stop_block the most recent block that could be scanned,
1632
+ * otherwise nullptr if no block could be scanned
1630
1633
*
1631
- * If pindexStop is not a nullptr, the scan will stop at the block-index
1632
- * defined by pindexStop
1634
+ * @return ScanResult indicating success or failure of the scan. SUCCESS if
1635
+ * scan was successful. FAILURE if a complete rescan was not possible (due to
1636
+ * pruning or corruption). USER_ABORT if the rescan was aborted before it
1637
+ * could complete.
1633
1638
*
1634
- * Caller needs to make sure pindexStop (and the optional pindexStart) are on
1639
+ * @pre Caller needs to make sure pindexStop (and the optional pindexStart) are on
1635
1640
* the main chain after to the addition of any new keys you want to detect
1636
1641
* transactions for.
1637
1642
*/
1638
- CBlockIndex* CWallet::ScanForWalletTransactions (CBlockIndex* pindexStart, CBlockIndex* pindexStop, const WalletRescanReserver & reserver, bool fUpdate )
1643
+ CWallet::ScanResult CWallet::ScanForWalletTransactions (const CBlockIndex* const pindexStart, const CBlockIndex* const pindexStop, const WalletRescanReserver& reserver, const CBlockIndex*& failed_block, const CBlockIndex*& stop_block , bool fUpdate )
1639
1644
{
1640
1645
int64_t nNow = GetTime ();
1641
1646
const CChainParams& chainParams = Params ();
@@ -1645,8 +1650,8 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
1645
1650
assert (pindexStop->nHeight >= pindexStart->nHeight );
1646
1651
}
1647
1652
1648
- CBlockIndex* pindex = pindexStart;
1649
- CBlockIndex* ret = nullptr ;
1653
+ const CBlockIndex* pindex = pindexStart;
1654
+ failed_block = nullptr ;
1650
1655
1651
1656
if (pindex) WalletLogPrintf (" Rescan started from block %d...\n " , pindex->nHeight );
1652
1657
@@ -1667,8 +1672,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
1667
1672
}
1668
1673
}
1669
1674
double progress_current = progress_begin;
1670
- while (pindex && !fAbortRescan && !ShutdownRequested ())
1671
- {
1675
+ while (pindex && !fAbortRescan && !ShutdownRequested ()) {
1672
1676
if (pindex->nHeight % 100 == 0 && progress_end - progress_begin > 0.0 ) {
1673
1677
ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), std::max (1 , std::min (99 , (int )((progress_current - progress_begin) / (progress_end - progress_begin) * 100 ))));
1674
1678
}
@@ -1684,14 +1688,17 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
1684
1688
if (pindex && !chainActive.Contains (pindex)) {
1685
1689
// Abort scan if current block is no longer active, to prevent
1686
1690
// marking transactions as coming from the wrong block.
1687
- ret = pindex;
1691
+ failed_block = pindex;
1688
1692
break ;
1689
1693
}
1690
1694
for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
1691
1695
SyncTransaction (block.vtx [posInBlock], pindex, posInBlock, fUpdate );
1692
1696
}
1697
+ // scan succeeded, record block as most recent successfully scanned
1698
+ stop_block = pindex;
1693
1699
} else {
1694
- ret = pindex;
1700
+ // could not scan block, keep scanning but record this block as the most recent failure
1701
+ failed_block = pindex;
1695
1702
}
1696
1703
if (pindex == pindexStop) {
1697
1704
break ;
@@ -1707,14 +1714,20 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
1707
1714
}
1708
1715
}
1709
1716
}
1717
+ ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), 100 ); // hide progress dialog in GUI
1710
1718
if (pindex && fAbortRescan ) {
1711
1719
WalletLogPrintf (" Rescan aborted at block %d. Progress=%f\n " , pindex->nHeight , progress_current);
1720
+ return ScanResult::USER_ABORT;
1712
1721
} else if (pindex && ShutdownRequested ()) {
1713
1722
WalletLogPrintf (" Rescan interrupted by shutdown request at block %d. Progress=%f\n " , pindex->nHeight , progress_current);
1723
+ return ScanResult::USER_ABORT;
1714
1724
}
1715
- ShowProgress (strprintf (" %s " + _ (" Rescanning..." ), GetDisplayName ()), 100 ); // hide progress dialog in GUI
1716
1725
}
1717
- return ret;
1726
+ if (failed_block) {
1727
+ return ScanResult::FAILURE;
1728
+ } else {
1729
+ return ScanResult::SUCCESS;
1730
+ }
1718
1731
}
1719
1732
1720
1733
void CWallet::ReacceptWalletTransactions ()
@@ -4169,11 +4182,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
4169
4182
nStart = GetTimeMillis ();
4170
4183
{
4171
4184
WalletRescanReserver reserver (walletInstance.get ());
4172
- if (!reserver.reserve ()) {
4185
+ const CBlockIndex *stop_block, *failed_block;
4186
+ if (!reserver.reserve () || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions (pindexRescan, nullptr , reserver, failed_block, stop_block, true ))) {
4173
4187
InitError (_ (" Failed to rescan the wallet during initialization" ));
4174
4188
return nullptr ;
4175
4189
}
4176
- walletInstance->ScanForWalletTransactions (pindexRescan, nullptr , reserver, true );
4177
4190
}
4178
4191
walletInstance->WalletLogPrintf (" Rescan completed in %15dms\n " , GetTimeMillis () - nStart);
4179
4192
walletInstance->ChainStateFlushed (chainActive.GetLocator ());
0 commit comments