From 3773cad14d769e7179d285c6e9f440d54a855595 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 25 Feb 2018 09:05:34 +0800 Subject: [PATCH] Merge #12287: Optimise lock behaviour for GuessVerificationProgress() 90ba2df11 Fix missing cs_main lock for GuessVerificationProgress() (Jonas Schnelli) Pull request description: `GuessVerificationProgress()` needs `cs_main` due to accessing the `pindex->nChainTx`. This adds a `AssertLockHeld` in `GuessVerificationProgress()` and adds the missing locks in... * `LoadChainTip()` * `ScanForWalletTransactions()` (got missed in #11281) * GUI, `ClientModel::getVerificationProgress()` <--- **this may have GUI performance impacts**, but could be relaxed later with a cache or something more efficient. Tree-SHA512: 13302946571422375f32af8e396b9d2c1180f2693ea363aeba9e98c8266ddec64fe7862bfdcbb5a93a4b12165a61eec1e51e4e7d7a8515fa50879095dc163412 --- src/qt/clientmodel.cpp | 2 +- src/validation.cpp | 1 + src/wallet/wallet.cpp | 12 ++++-------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 8063a6d6a26983..b454dcf88bb8b4 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -174,9 +174,9 @@ size_t ClientModel::getInstantSentLockCount() const double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const { CBlockIndex *tip = const_cast(tipIn); + LOCK(cs_main); if (!tip) { - LOCK(cs_main); tip = chainActive.Tip(); } return GuessVerificationProgress(Params().TxData(), tip); diff --git a/src/validation.cpp b/src/validation.cpp index f7fd33582187b7..4fb90c6256edb7 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4989,6 +4989,7 @@ bool DumpMempool(void) } //! Guess how far we are in the verification process at the given block index +//! require cs_main if pindex has not been validated yet (because nChainTx might be unset) double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) { if (pindex == nullptr) return 0.0; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1cebe35ffbf172..ba73bdf38732e3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2065,20 +2065,15 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex); dProgressTip = GuessVerificationProgress(chainParams.TxData(), tip); } + double gvp = dProgressStart; while (pindex && !fAbortRescan) { 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)); + LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, gvp); } CBlock block; @@ -2102,6 +2097,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock { LOCK(cs_main); pindex = chainActive.Next(pindex); + gvp = GuessVerificationProgress(chainParams.TxData(), pindex); if (tip != chainActive.Tip()) { tip = chainActive.Tip(); // in case the tip has changed, update progress max @@ -2110,7 +2106,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock } } if (pindex && fAbortRescan) { - LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex)); + LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, gvp); } ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI }