aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp62
1 files changed, 50 insertions, 12 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index da721ea008..450ef4c49c 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1614,14 +1614,15 @@ void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
*/
int64_t CWallet::RescanFromTime(int64_t startTime, bool update)
{
- AssertLockHeld(cs_main);
- AssertLockHeld(cs_wallet);
-
// Find starting block. May be null if nCreateTime is greater than the
// highest blockchain timestamp, in which case there is nothing that needs
// to be scanned.
- CBlockIndex* const startBlock = chainActive.FindEarliestAtLeast(startTime - TIMESTAMP_WINDOW);
- LogPrintf("%s: Rescanning last %i blocks\n", __func__, startBlock ? chainActive.Height() - startBlock->nHeight + 1 : 0);
+ CBlockIndex* startBlock = nullptr;
+ {
+ LOCK(cs_main);
+ startBlock = chainActive.FindEarliestAtLeast(startTime - TIMESTAMP_WINDOW);
+ LogPrintf("%s: Rescanning last %i blocks\n", __func__, startBlock ? chainActive.Height() - startBlock->nHeight + 1 : 0);
+ }
if (startBlock) {
const CBlockIndex* const failedBlock = ScanForWalletTransactions(startBlock, nullptr, update);
@@ -1643,6 +1644,10 @@ int64_t CWallet::RescanFromTime(int64_t startTime, bool update)
*
* If pindexStop is not a nullptr, the scan will stop at the block-index
* defined by pindexStop
+ *
+ * Caller needs to make sure pindexStop (and the optional pindexStart) are on
+ * the main chain after to the addition of any new keys you want to detect
+ * transactions for.
*/
CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlockIndex* pindexStop, bool fUpdate)
{
@@ -1656,24 +1661,49 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
CBlockIndex* pindex = pindexStart;
CBlockIndex* ret = nullptr;
{
- LOCK2(cs_main, cs_wallet);
fAbortRescan = false;
fScanningWallet = true;
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
- double dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
- double dProgressTip = GuessVerificationProgress(chainParams.TxData(), chainActive.Tip());
+ CBlockIndex* tip = nullptr;
+ double dProgressStart;
+ double dProgressTip;
+ {
+ LOCK(cs_main);
+ tip = chainActive.Tip();
+ dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
+ dProgressTip = GuessVerificationProgress(chainParams.TxData(), tip);
+ }
while (pindex && !fAbortRescan)
{
- if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
- ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((GuessVerificationProgress(chainParams.TxData(), pindex) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
+ if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) {
+ double gvp = 0;
+ {
+ LOCK(cs_main);
+ gvp = GuessVerificationProgress(chainParams.TxData(), pindex);
+ }
+ ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((gvp - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
+ }
if (GetTime() >= nNow + 60) {
nNow = GetTime();
+ LOCK(cs_main);
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
}
+ bool readRet = false;
CBlock block;
- if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
+ {
+ LOCK(cs_main);
+ readRet = ReadBlockFromDisk(block, pindex, Params().GetConsensus());
+ }
+ if (readRet) {
+ LOCK2(cs_main, cs_wallet);
+ if (pindex && !chainActive.Contains(pindex)) {
+ // Abort scan if current block is no longer active, to prevent
+ // marking transactions as coming from the wrong block.
+ ret = pindex;
+ break;
+ }
for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
AddToWalletIfInvolvingMe(block.vtx[posInBlock], pindex, posInBlock, fUpdate);
}
@@ -1683,7 +1713,15 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
if (pindex == pindexStop) {
break;
}
- pindex = chainActive.Next(pindex);
+ {
+ LOCK(cs_main);
+ pindex = chainActive.Next(pindex);
+ if (tip != chainActive.Tip()) {
+ tip = chainActive.Tip();
+ // in case the tip has changed, update progress max
+ dProgressTip = GuessVerificationProgress(chainParams.TxData(), tip);
+ }
+ }
}
if (pindex && fAbortRescan) {
LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));