[Qt] rescan progress
This commit is contained in:
parent
397521d632
commit
392783697c
10 changed files with 113 additions and 9 deletions
|
@ -21,7 +21,7 @@ namespace Checkpoints
|
|||
// every system. When reindexing from a fast disk with a slow CPU, it
|
||||
// can be up to 20, while when downloading from a slow network with a
|
||||
// fast multicore CPU, it won't be much higher than 1.
|
||||
static const double fSigcheckVerificationFactor = 5.0;
|
||||
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
|
||||
|
||||
struct CCheckpointData {
|
||||
const MapCheckpoints *mapCheckpoints;
|
||||
|
@ -104,12 +104,13 @@ namespace Checkpoints
|
|||
}
|
||||
|
||||
// Guess how far we are in the verification process at the given block index
|
||||
double GuessVerificationProgress(CBlockIndex *pindex) {
|
||||
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) {
|
||||
if (pindex==NULL)
|
||||
return 0.0;
|
||||
|
||||
int64_t nNow = time(NULL);
|
||||
|
||||
double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0;
|
||||
double fWorkBefore = 0.0; // Amount of work done before pindex
|
||||
double fWorkAfter = 0.0; // Amount of work left after pindex (estimated)
|
||||
// Work is defined as: 1.0 per transaction before the last checkpoint, and
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Checkpoints
|
|||
// Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
|
||||
CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
|
||||
|
||||
double GuessVerificationProgress(CBlockIndex *pindex);
|
||||
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks = true);
|
||||
|
||||
extern bool fEnabled;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
#include "splashscreen.h"
|
||||
|
||||
#include "clientversion.h"
|
||||
#include "init.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
|
@ -109,14 +113,33 @@ static void InitMessage(SplashScreen *splash, const std::string &message)
|
|||
Q_ARG(QColor, QColor(55,55,55)));
|
||||
}
|
||||
|
||||
static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress)
|
||||
{
|
||||
InitMessage(splash, title + strprintf("%d", nProgress) + "%");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
static void ConnectWallet(SplashScreen *splash, CWallet* wallet)
|
||||
{
|
||||
wallet->ShowProgress.connect(boost::bind(ShowProgress, splash, _1, _2));
|
||||
}
|
||||
#endif
|
||||
|
||||
void SplashScreen::subscribeToCoreSignals()
|
||||
{
|
||||
// Connect signals to client
|
||||
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
|
||||
#ifdef ENABLE_WALLET
|
||||
uiInterface.LoadWallet.connect(boost::bind(ConnectWallet, this, _1));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SplashScreen::unsubscribeFromCoreSignals()
|
||||
{
|
||||
// Disconnect signals from client
|
||||
uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
|
||||
#ifdef ENABLE_WALLET
|
||||
if(pwalletMain)
|
||||
pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -419,8 +419,17 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
|
|||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
// queue notifications to show a non freezing progress dialog e.g. for rescan
|
||||
static bool fQueueNotifications = false;
|
||||
static std::vector<std::pair<uint256, ChangeType> > vQueueNotifications;
|
||||
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
|
||||
{
|
||||
if (fQueueNotifications)
|
||||
{
|
||||
vQueueNotifications.push_back(make_pair(hash, status));
|
||||
return;
|
||||
}
|
||||
|
||||
QString strHash = QString::fromStdString(hash.GetHex());
|
||||
|
||||
qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
|
||||
|
@ -429,12 +438,32 @@ static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet,
|
|||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
|
||||
{
|
||||
// emits signal "showProgress"
|
||||
QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(title)),
|
||||
Q_ARG(int, nProgress));
|
||||
|
||||
if (nProgress == 0)
|
||||
fQueueNotifications = true;
|
||||
|
||||
if (nProgress == 100)
|
||||
{
|
||||
fQueueNotifications = false;
|
||||
BOOST_FOREACH(const PAIRTYPE(uint256, ChangeType)& notification, vQueueNotifications)
|
||||
NotifyTransactionChanged(walletmodel, NULL, notification.first, notification.second);
|
||||
std::vector<std::pair<uint256, ChangeType> >().swap(vQueueNotifications); // clear
|
||||
}
|
||||
}
|
||||
|
||||
void WalletModel::subscribeToCoreSignals()
|
||||
{
|
||||
// Connect signals to wallet
|
||||
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
|
||||
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
|
||||
}
|
||||
|
||||
void WalletModel::unsubscribeFromCoreSignals()
|
||||
|
@ -443,6 +472,7 @@ void WalletModel::unsubscribeFromCoreSignals()
|
|||
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
|
||||
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
|
||||
}
|
||||
|
||||
// WalletModel::UnlockContext implementation
|
||||
|
|
|
@ -237,6 +237,9 @@ signals:
|
|||
// Coins sent: from wallet, to recipient, in (serialized) transaction:
|
||||
void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
|
||||
|
||||
// Show progress dialog e.g. for rescan
|
||||
void showProgress(const QString &title, int nProgress);
|
||||
|
||||
public slots:
|
||||
/* Wallet status might have changed */
|
||||
void updateStatus();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <QActionGroup>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QProgressDialog>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
@ -127,6 +128,9 @@ void WalletView::setWalletModel(WalletModel *walletModel)
|
|||
|
||||
// Ask for passphrase if needed
|
||||
connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
|
||||
|
||||
// Show progress dialog
|
||||
connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,3 +281,26 @@ void WalletView::usedReceivingAddresses()
|
|||
dlg->setModel(walletModel->getAddressTableModel());
|
||||
dlg->show();
|
||||
}
|
||||
|
||||
void WalletView::showProgress(const QString &title, int nProgress)
|
||||
{
|
||||
if (nProgress == 0)
|
||||
{
|
||||
progressDialog = new QProgressDialog(title, "", 0, 100);
|
||||
progressDialog->setWindowModality(Qt::ApplicationModal);
|
||||
progressDialog->setMinimumDuration(0);
|
||||
progressDialog->setCancelButton(0);
|
||||
progressDialog->setAutoClose(false);
|
||||
progressDialog->setValue(0);
|
||||
}
|
||||
else if (nProgress == 100)
|
||||
{
|
||||
if (progressDialog)
|
||||
{
|
||||
progressDialog->close();
|
||||
progressDialog->deleteLater();
|
||||
}
|
||||
}
|
||||
else if (progressDialog)
|
||||
progressDialog->setValue(nProgress);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ class WalletModel;
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QModelIndex;
|
||||
class QProgressDialog;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/*
|
||||
|
@ -60,6 +61,8 @@ private:
|
|||
|
||||
TransactionView *transactionView;
|
||||
|
||||
QProgressDialog *progressDialog;
|
||||
|
||||
public slots:
|
||||
/** Switch to overview (home) page */
|
||||
void gotoOverviewPage();
|
||||
|
@ -97,6 +100,9 @@ public slots:
|
|||
/** Re-emit encryption status signal */
|
||||
void updateEncryptionStatus();
|
||||
|
||||
/** Show progress dialog e.g. for rescan */
|
||||
void showProgress(const QString &title, int nProgress);
|
||||
|
||||
signals:
|
||||
/** Signal that we want to show the main window */
|
||||
void showNormalIfMinimized();
|
||||
|
|
|
@ -91,6 +91,9 @@ public:
|
|||
* @note called with lock cs_mapAlerts held.
|
||||
*/
|
||||
boost::signals2::signal<void (const uint256 &hash, ChangeType status)> NotifyAlertChanged;
|
||||
|
||||
/** A wallet has been loaded. */
|
||||
boost::signals2::signal<void (CWallet* wallet)> LoadWallet;
|
||||
};
|
||||
|
||||
extern CClientUIInterface uiInterface;
|
||||
|
|
|
@ -835,14 +835,19 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
|||
CBlockIndex* pindex = pindexStart;
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
|
||||
// no need to read and scan block, if block was created before
|
||||
// our wallet birthday (as adjusted for block time variability)
|
||||
while (pindex && nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200)))
|
||||
pindex = chainActive.Next(pindex);
|
||||
|
||||
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
|
||||
double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false);
|
||||
double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false);
|
||||
while (pindex)
|
||||
{
|
||||
// no need to read and scan block, if block was created before
|
||||
// our wallet birthday (as adjusted for block time variability)
|
||||
if (nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200))) {
|
||||
pindex = chainActive.Next(pindex);
|
||||
continue;
|
||||
}
|
||||
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
|
||||
ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
|
||||
|
||||
CBlock block;
|
||||
ReadBlockFromDisk(block, pindex);
|
||||
|
@ -857,6 +862,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
|||
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(pindex));
|
||||
}
|
||||
}
|
||||
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1492,6 +1498,8 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
|||
return nLoadWalletRet;
|
||||
fFirstRunRet = !vchDefaultKey.IsValid();
|
||||
|
||||
uiInterface.LoadWallet(this);
|
||||
|
||||
return DB_LOAD_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -391,6 +391,9 @@ public:
|
|||
*/
|
||||
boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
|
||||
ChangeType status)> NotifyTransactionChanged;
|
||||
|
||||
/** Show progress e.g. for rescan */
|
||||
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
|
||||
};
|
||||
|
||||
/** A key allocated from the key pool. */
|
||||
|
|
Loading…
Reference in a new issue