Skip to content

Commit 9bd1bdd

Browse files
committed
Merge pull request #3928
3927836 [Qt] rescan progress (Cozz Lovan)
2 parents 8556b02 + 3927836 commit 9bd1bdd

File tree

10 files changed

+113
-9
lines changed

10 files changed

+113
-9
lines changed

src/checkpoints.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace Checkpoints
2121
// every system. When reindexing from a fast disk with a slow CPU, it
2222
// can be up to 20, while when downloading from a slow network with a
2323
// fast multicore CPU, it won't be much higher than 1.
24-
static const double fSigcheckVerificationFactor = 5.0;
24+
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
2525

2626
struct CCheckpointData {
2727
const MapCheckpoints *mapCheckpoints;
@@ -104,12 +104,13 @@ namespace Checkpoints
104104
}
105105

106106
// Guess how far we are in the verification process at the given block index
107-
double GuessVerificationProgress(CBlockIndex *pindex) {
107+
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) {
108108
if (pindex==NULL)
109109
return 0.0;
110110

111111
int64_t nNow = time(NULL);
112112

113+
double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0;
113114
double fWorkBefore = 0.0; // Amount of work done before pindex
114115
double fWorkAfter = 0.0; // Amount of work left after pindex (estimated)
115116
// Work is defined as: 1.0 per transaction before the last checkpoint, and

src/checkpoints.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Checkpoints
2424
// Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
2525
CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
2626

27-
double GuessVerificationProgress(CBlockIndex *pindex);
27+
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks = true);
2828

2929
extern bool fEnabled;
3030
}

src/qt/splashscreen.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
#include "splashscreen.h"
66

77
#include "clientversion.h"
8+
#include "init.h"
89
#include "ui_interface.h"
910
#include "util.h"
11+
#ifdef ENABLE_WALLET
12+
#include "wallet.h"
13+
#endif
1014

1115
#include <QApplication>
1216
#include <QPainter>
@@ -109,14 +113,33 @@ static void InitMessage(SplashScreen *splash, const std::string &message)
109113
Q_ARG(QColor, QColor(55,55,55)));
110114
}
111115

116+
static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress)
117+
{
118+
InitMessage(splash, title + strprintf("%d", nProgress) + "%");
119+
}
120+
121+
#ifdef ENABLE_WALLET
122+
static void ConnectWallet(SplashScreen *splash, CWallet* wallet)
123+
{
124+
wallet->ShowProgress.connect(boost::bind(ShowProgress, splash, _1, _2));
125+
}
126+
#endif
127+
112128
void SplashScreen::subscribeToCoreSignals()
113129
{
114130
// Connect signals to client
115131
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
132+
#ifdef ENABLE_WALLET
133+
uiInterface.LoadWallet.connect(boost::bind(ConnectWallet, this, _1));
134+
#endif
116135
}
117136

118137
void SplashScreen::unsubscribeFromCoreSignals()
119138
{
120139
// Disconnect signals from client
121140
uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
141+
#ifdef ENABLE_WALLET
142+
if(pwalletMain)
143+
pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
144+
#endif
122145
}

src/qt/walletmodel.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,17 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
419419
Q_ARG(int, status));
420420
}
421421

422+
// queue notifications to show a non freezing progress dialog e.g. for rescan
423+
static bool fQueueNotifications = false;
424+
static std::vector<std::pair<uint256, ChangeType> > vQueueNotifications;
422425
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
423426
{
427+
if (fQueueNotifications)
428+
{
429+
vQueueNotifications.push_back(make_pair(hash, status));
430+
return;
431+
}
432+
424433
QString strHash = QString::fromStdString(hash.GetHex());
425434

426435
qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
@@ -429,12 +438,32 @@ static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet,
429438
Q_ARG(int, status));
430439
}
431440

441+
static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
442+
{
443+
// emits signal "showProgress"
444+
QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
445+
Q_ARG(QString, QString::fromStdString(title)),
446+
Q_ARG(int, nProgress));
447+
448+
if (nProgress == 0)
449+
fQueueNotifications = true;
450+
451+
if (nProgress == 100)
452+
{
453+
fQueueNotifications = false;
454+
BOOST_FOREACH(const PAIRTYPE(uint256, ChangeType)& notification, vQueueNotifications)
455+
NotifyTransactionChanged(walletmodel, NULL, notification.first, notification.second);
456+
std::vector<std::pair<uint256, ChangeType> >().swap(vQueueNotifications); // clear
457+
}
458+
}
459+
432460
void WalletModel::subscribeToCoreSignals()
433461
{
434462
// Connect signals to wallet
435463
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
436464
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
437465
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
466+
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
438467
}
439468

440469
void WalletModel::unsubscribeFromCoreSignals()
@@ -443,6 +472,7 @@ void WalletModel::unsubscribeFromCoreSignals()
443472
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
444473
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
445474
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
475+
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
446476
}
447477

448478
// WalletModel::UnlockContext implementation

src/qt/walletmodel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ class WalletModel : public QObject
237237
// Coins sent: from wallet, to recipient, in (serialized) transaction:
238238
void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
239239

240+
// Show progress dialog e.g. for rescan
241+
void showProgress(const QString &title, int nProgress);
242+
240243
public slots:
241244
/* Wallet status might have changed */
242245
void updateStatus();

src/qt/walletview.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <QActionGroup>
2525
#include <QFileDialog>
2626
#include <QHBoxLayout>
27+
#include <QProgressDialog>
2728
#include <QPushButton>
2829
#include <QVBoxLayout>
2930

@@ -127,6 +128,9 @@ void WalletView::setWalletModel(WalletModel *walletModel)
127128

128129
// Ask for passphrase if needed
129130
connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
131+
132+
// Show progress dialog
133+
connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
130134
}
131135
}
132136

@@ -277,3 +281,26 @@ void WalletView::usedReceivingAddresses()
277281
dlg->setModel(walletModel->getAddressTableModel());
278282
dlg->show();
279283
}
284+
285+
void WalletView::showProgress(const QString &title, int nProgress)
286+
{
287+
if (nProgress == 0)
288+
{
289+
progressDialog = new QProgressDialog(title, "", 0, 100);
290+
progressDialog->setWindowModality(Qt::ApplicationModal);
291+
progressDialog->setMinimumDuration(0);
292+
progressDialog->setCancelButton(0);
293+
progressDialog->setAutoClose(false);
294+
progressDialog->setValue(0);
295+
}
296+
else if (nProgress == 100)
297+
{
298+
if (progressDialog)
299+
{
300+
progressDialog->close();
301+
progressDialog->deleteLater();
302+
}
303+
}
304+
else if (progressDialog)
305+
progressDialog->setValue(nProgress);
306+
}

src/qt/walletview.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class WalletModel;
1818

1919
QT_BEGIN_NAMESPACE
2020
class QModelIndex;
21+
class QProgressDialog;
2122
QT_END_NAMESPACE
2223

2324
/*
@@ -60,6 +61,8 @@ class WalletView : public QStackedWidget
6061

6162
TransactionView *transactionView;
6263

64+
QProgressDialog *progressDialog;
65+
6366
public slots:
6467
/** Switch to overview (home) page */
6568
void gotoOverviewPage();
@@ -97,6 +100,9 @@ public slots:
97100
/** Re-emit encryption status signal */
98101
void updateEncryptionStatus();
99102

103+
/** Show progress dialog e.g. for rescan */
104+
void showProgress(const QString &title, int nProgress);
105+
100106
signals:
101107
/** Signal that we want to show the main window */
102108
void showNormalIfMinimized();

src/ui_interface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class CClientUIInterface
9191
* @note called with lock cs_mapAlerts held.
9292
*/
9393
boost::signals2::signal<void (const uint256 &hash, ChangeType status)> NotifyAlertChanged;
94+
95+
/** A wallet has been loaded. */
96+
boost::signals2::signal<void (CWallet* wallet)> LoadWallet;
9497
};
9598

9699
extern CClientUIInterface uiInterface;

src/wallet.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -835,14 +835,19 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
835835
CBlockIndex* pindex = pindexStart;
836836
{
837837
LOCK(cs_wallet);
838+
839+
// no need to read and scan block, if block was created before
840+
// our wallet birthday (as adjusted for block time variability)
841+
while (pindex && nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200)))
842+
pindex = chainActive.Next(pindex);
843+
844+
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
845+
double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false);
846+
double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false);
838847
while (pindex)
839848
{
840-
// no need to read and scan block, if block was created before
841-
// our wallet birthday (as adjusted for block time variability)
842-
if (nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200))) {
843-
pindex = chainActive.Next(pindex);
844-
continue;
845-
}
849+
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
850+
ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
846851

847852
CBlock block;
848853
ReadBlockFromDisk(block, pindex);
@@ -857,6 +862,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
857862
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(pindex));
858863
}
859864
}
865+
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
860866
}
861867
return ret;
862868
}
@@ -1492,6 +1498,8 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
14921498
return nLoadWalletRet;
14931499
fFirstRunRet = !vchDefaultKey.IsValid();
14941500

1501+
uiInterface.LoadWallet(this);
1502+
14951503
return DB_LOAD_OK;
14961504
}
14971505

src/wallet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
391391
*/
392392
boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
393393
ChangeType status)> NotifyTransactionChanged;
394+
395+
/** Show progress e.g. for rescan */
396+
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
394397
};
395398

396399
/** A key allocated from the key pool. */

0 commit comments

Comments
 (0)