From 00cb69bc8655b1c17064a7e42453fd049e555076 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 23 Jun 2017 09:32:38 +0200 Subject: [PATCH 1/6] [Qt] allow to execute a callback during splashscreen progress --- src/qt/bitcoin.cpp | 1 + src/qt/splashscreen.cpp | 24 ++++++++++++++++++++++++ src/qt/splashscreen.h | 8 ++++++++ src/ui_interface.h | 3 +++ 4 files changed, 36 insertions(+) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6d8760c07..8a745cadc 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -578,6 +578,7 @@ int main(int argc, char *argv[]) // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) // IMPORTANT if it is no longer a typedef use the normal variant above qRegisterMetaType< CAmount >("CAmount"); + qRegisterMetaType< std::function >("std::function"); /// 3. Application identification // must be set before OptionsModel is initialized or translations are loaded, diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 10966e42e..1b7cc6923 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -131,6 +131,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) move(QApplication::desktop()->screenGeometry().center() - r.center()); subscribeToCoreSignals(); + installEventFilter(this); } SplashScreen::~SplashScreen() @@ -138,6 +139,16 @@ SplashScreen::~SplashScreen() unsubscribeFromCoreSignals(); } +bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) { + if (ev->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(ev); + if(keyEvent->text()[0] == 'q' && breakAction != nullptr) { + breakAction(); + } + } + return QObject::eventFilter(obj, ev); +} + void SplashScreen::slotFinish(QWidget *mainWin) { Q_UNUSED(mainWin); @@ -164,6 +175,18 @@ static void ShowProgress(SplashScreen *splash, const std::string &title, int nPr InitMessage(splash, title + strprintf("%d", nProgress) + "%"); } +void SplashScreen::setBreakAction(const std::function &action) +{ + breakAction = action; +} + +static void SetProgressBreakAction(SplashScreen *splash, const std::function &action) +{ + QMetaObject::invokeMethod(splash, "setBreakAction", + Qt::QueuedConnection, + Q_ARG(std::function, action)); +} + #ifdef ENABLE_WALLET void SplashScreen::ConnectWallet(CWallet* wallet) { @@ -177,6 +200,7 @@ void SplashScreen::subscribeToCoreSignals() // Connect signals to client uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1)); uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); + uiInterface.SetProgressBreakAction.connect(boost::bind(SetProgressBreakAction, this, _1)); #ifdef ENABLE_WALLET uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1)); #endif diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 95a65cc53..a88ebb98a 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_QT_SPLASHSCREEN_H #define BITCOIN_QT_SPLASHSCREEN_H +#include #include class CWallet; @@ -35,6 +36,11 @@ public Q_SLOTS: /** Show message and progress */ void showMessage(const QString &message, int alignment, const QColor &color); + /** Sets the break action */ + void setBreakAction(const std::function &action); +protected: + bool eventFilter(QObject * obj, QEvent * ev); + private: /** Connect core signals to splash screen */ void subscribeToCoreSignals(); @@ -49,6 +55,8 @@ private: int curAlignment; QList connectedWallets; + + std::function breakAction; }; #endif // BITCOIN_QT_SPLASHSCREEN_H diff --git a/src/ui_interface.h b/src/ui_interface.h index 090402aee..762dd19b1 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -97,6 +97,9 @@ public: /** Show progress e.g. for verifychain */ boost::signals2::signal ShowProgress; + /** Set progress break action (possible "cancel button" triggers that action) */ + boost::signals2::signal action)> SetProgressBreakAction; + /** New block has been accepted */ boost::signals2::signal NotifyBlockTip; From ae09d4583b26251e67fa48216ebafb6bcdf2472b Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 23 Jun 2017 09:33:31 +0200 Subject: [PATCH 2/6] Allow to shut down during txdb upgrade --- src/init.cpp | 5 +++-- src/txdb.cpp | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index d59713258..ec1f18fae 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1358,7 +1358,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("* Using %.1fMiB for in-memory UTXO set (plus up to %.1fMiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024)); bool fLoaded = false; - while (!fLoaded) { + while (!fLoaded && !fRequestShutdown) { bool fReset = fReindex; std::string strLoadError; @@ -1389,6 +1389,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) break; } } + if (fRequestShutdown) break; if (!LoadBlockIndex(chainparams)) { strLoadError = _("Error loading block database"); @@ -1466,7 +1467,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fLoaded = true; } while(false); - if (!fLoaded) { + if (!fLoaded && !fRequestShutdown) { // first suggest a reindex if (!fReset) { bool fRet = uiInterface.ThreadSafeQuestion( diff --git a/src/txdb.cpp b/src/txdb.cpp index d24162ba2..3e05683d1 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -371,6 +371,9 @@ bool CCoinsViewDB::Upgrade() { CDBBatch batch(db); while (pcursor->Valid()) { boost::this_thread::interruption_point(); + if (ShutdownRequested()) { + break; + } std::pair key; if (pcursor->GetKey(key) && key.first == DB_COINS) { CCoins old_coins; From 316fcb5106b90f3dd7a2dced2063e237539e75b4 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 23 Jun 2017 09:35:24 +0200 Subject: [PATCH 3/6] Allow to cancel the txdb upgrade via splashscreen callback --- src/txdb.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/txdb.cpp b/src/txdb.cpp index 3e05683d1..6f1d48247 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -11,6 +11,8 @@ #include "pow.h" #include "uint256.h" #include "util.h" +#include "ui_interface.h" +#include "init.h" #include @@ -366,9 +368,11 @@ bool CCoinsViewDB::Upgrade() { return true; } + int64_t count = 0; LogPrintf("Upgrading database...\n"); size_t batch_size = 1 << 24; CDBBatch batch(db); + uiInterface.SetProgressBreakAction(StartShutdown); while (pcursor->Valid()) { boost::this_thread::interruption_point(); if (ShutdownRequested()) { @@ -376,6 +380,10 @@ bool CCoinsViewDB::Upgrade() { } std::pair key; if (pcursor->GetKey(key) && key.first == DB_COINS) { + if (count++ % 256 == 0) { + uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1); + uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", (int)(high * 100.0 / 65536.0 + 0.5)); + } CCoins old_coins; if (!pcursor->GetValue(old_coins)) { return error("%s: cannot parse CCoins record", __func__); @@ -400,5 +408,6 @@ bool CCoinsViewDB::Upgrade() { } } db.WriteBatch(batch); + uiInterface.SetProgressBreakAction(std::function()); return true; } From 06c5b6edd33213a410d9f128524e74ba076f7ba0 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 23 Jun 2017 09:51:59 +0200 Subject: [PATCH 4/6] Show txdb upgrade progress in debug log --- src/txdb.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 6f1d48247..6eff52f05 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -369,7 +369,8 @@ bool CCoinsViewDB::Upgrade() { } int64_t count = 0; - LogPrintf("Upgrading database...\n"); + LogPrintf("Upgrading utxo-set database...\n"); + LogPrintf("[0%%]..."); size_t batch_size = 1 << 24; CDBBatch batch(db); uiInterface.SetProgressBreakAction(StartShutdown); @@ -383,6 +384,7 @@ bool CCoinsViewDB::Upgrade() { if (count++ % 256 == 0) { uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1); uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", (int)(high * 100.0 / 65536.0 + 0.5)); + LogPrintf("[%d%%]...", (int)(high * 100.0 / 65536.0 + 0.5)); } CCoins old_coins; if (!pcursor->GetValue(old_coins)) { @@ -409,5 +411,6 @@ bool CCoinsViewDB::Upgrade() { } db.WriteBatch(batch); uiInterface.SetProgressBreakAction(std::function()); + LogPrintf("[DONE].\n"); return true; } From 83fbea3f25558fa6c72f2100d203b95b4030573e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 28 Jun 2017 21:05:39 +0200 Subject: [PATCH 5/6] Report txdb upgrade not more often then every 10% --- src/txdb.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 6eff52f05..c62f51cfc 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -374,6 +374,7 @@ bool CCoinsViewDB::Upgrade() { size_t batch_size = 1 << 24; CDBBatch batch(db); uiInterface.SetProgressBreakAction(StartShutdown); + int reportDone = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); if (ShutdownRequested()) { @@ -383,8 +384,13 @@ bool CCoinsViewDB::Upgrade() { if (pcursor->GetKey(key) && key.first == DB_COINS) { if (count++ % 256 == 0) { uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1); - uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", (int)(high * 100.0 / 65536.0 + 0.5)); - LogPrintf("[%d%%]...", (int)(high * 100.0 / 65536.0 + 0.5)); + int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5); + uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", percentageDone); + if (reportDone < percentageDone/10) { + // report max. every 10% step + LogPrintf("[%d%%]...", percentageDone); + reportDone = percentageDone/10; + } } CCoins old_coins; if (!pcursor->GetValue(old_coins)) { From 542ce6e24631a22451fabdb85d545add4024f553 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 28 Jun 2017 21:28:11 +0200 Subject: [PATCH 6/6] Report [CANCELLED] instead of [DONE] when shut down during txdb upgrade --- src/txdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index c62f51cfc..002f6550b 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -417,6 +417,6 @@ bool CCoinsViewDB::Upgrade() { } db.WriteBatch(batch); uiInterface.SetProgressBreakAction(std::function()); - LogPrintf("[DONE].\n"); + LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE"); return true; }