* Scan the block chain (starting in pindexStart) for transactions * from or to us. If fUpdate is true, found transactions that already * exist in the wallet will be updated. * * Returns null if scan was successful. Otherwise, if a complete rescan was not * possible (due to pruning or corruption), returns pointer to the most recent * block that could not be scanned. * * If pindexStop is not
| 1714 | * transactions for. |
| 1715 | */ |
| 1716 | CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlockIndex* pindexStop, const WalletRescanReserver &reserver, bool fUpdate) |
| 1717 | { |
| 1718 | int64_t nNow = GetTime(); |
| 1719 | const CChainParams& chainParams = Params(); |
| 1720 | |
| 1721 | assert(reserver.isReserved()); |
| 1722 | if (pindexStop) { |
| 1723 | assert(pindexStop->nHeight >= pindexStart->nHeight); |
| 1724 | } |
| 1725 | |
| 1726 | CBlockIndex* pindex = pindexStart; |
| 1727 | CBlockIndex* ret = nullptr; |
| 1728 | |
| 1729 | if (pindex) WalletLogPrintf("Rescan started from block %d...\n", pindex->nHeight); |
| 1730 | |
| 1731 | { |
| 1732 | fAbortRescan = false; |
| 1733 | ShowProgress(strprintf("%s " + _("Rescanning..."), GetDisplayName()), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup |
| 1734 | CBlockIndex* tip = nullptr; |
| 1735 | double progress_begin; |
| 1736 | double progress_end; |
| 1737 | { |
| 1738 | LOCK(cs_main); |
| 1739 | progress_begin = GuessVerificationProgress(chainParams.TxData(), pindex); |
| 1740 | if (pindexStop == nullptr) { |
| 1741 | tip = chainActive.Tip(); |
| 1742 | progress_end = GuessVerificationProgress(chainParams.TxData(), tip); |
| 1743 | } else { |
| 1744 | progress_end = GuessVerificationProgress(chainParams.TxData(), pindexStop); |
| 1745 | } |
| 1746 | } |
| 1747 | double progress_current = progress_begin; |
| 1748 | while (pindex && !fAbortRescan && !ShutdownRequested()) |
| 1749 | { |
| 1750 | if (pindex->nHeight % 100 == 0 && progress_end - progress_begin > 0.0) { |
| 1751 | ShowProgress(strprintf("%s " + _("Rescanning..."), GetDisplayName()), std::max(1, std::min(99, (int)((progress_current - progress_begin) / (progress_end - progress_begin) * 100)))); |
| 1752 | } |
| 1753 | if (GetTime() >= nNow + 60) { |
| 1754 | nNow = GetTime(); |
| 1755 | WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, progress_current); |
| 1756 | } |
| 1757 | |
| 1758 | CBlock block; |
| 1759 | if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) { |
| 1760 | LOCK2(cs_main, cs_wallet); |
| 1761 | if (pindex && !chainActive.Contains(pindex)) { |
| 1762 | // Abort scan if current block is no longer active, to prevent |
| 1763 | // marking transactions as coming from the wrong block. |
| 1764 | ret = pindex; |
| 1765 | break; |
| 1766 | } |
| 1767 | for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) { |
| 1768 | SyncTransaction(block.vtx[posInBlock], pindex, posInBlock, fUpdate); |
| 1769 | } |
| 1770 | } else { |
| 1771 | ret = pindex; |
| 1772 | } |
| 1773 | if (pindex == pindexStop) { |