Browse Source

Merge #10660: Allow to cancel the txdb upgrade via splashscreen keypress 'q'

542ce6e Report [CANCELLED] instead of [DONE] when shut down during txdb upgrade (Jonas Schnelli)
83fbea3 Report txdb upgrade not more often then every 10% (Jonas Schnelli)
06c5b6e Show txdb upgrade progress in debug log (Jonas Schnelli)
316fcb5 Allow to cancel the txdb upgrade via splashscreen callback (Jonas Schnelli)
ae09d45 Allow to shut down during txdb upgrade (Jonas Schnelli)
00cb69b [Qt] allow to execute a callback during splashscreen progress (Jonas Schnelli)

Tree-SHA512: 23190f23f441bfd60821e49f8b3698a6bef97eb0e0ee659328e4a7395769ecd1616420eacc38aa1fa0ff62b9de5f13a0098dc798cdec6bff649575cefebc0db2
0.15
Wladimir J. van der Laan 8 years ago
parent
commit
0c3542e5de
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
  1. 5
      src/init.cpp
  2. 1
      src/qt/bitcoin.cpp
  3. 24
      src/qt/splashscreen.cpp
  4. 8
      src/qt/splashscreen.h
  5. 23
      src/txdb.cpp
  6. 3
      src/ui_interface.h

5
src/init.cpp

@ -1358,7 +1358,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) @@ -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) @@ -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) @@ -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(

1
src/qt/bitcoin.cpp

@ -578,6 +578,7 @@ int main(int argc, char *argv[]) @@ -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<void(void)> >("std::function<void(void)>");
/// 3. Application identification
// must be set before OptionsModel is initialized or translations are loaded,

24
src/qt/splashscreen.cpp

@ -131,6 +131,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) @@ -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() @@ -138,6 +139,16 @@ SplashScreen::~SplashScreen()
unsubscribeFromCoreSignals();
}
bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) {
if (ev->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(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 @@ -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<void(void)> &action)
{
breakAction = action;
}
static void SetProgressBreakAction(SplashScreen *splash, const std::function<void(void)> &action)
{
QMetaObject::invokeMethod(splash, "setBreakAction",
Qt::QueuedConnection,
Q_ARG(std::function<void(void)>, action));
}
#ifdef ENABLE_WALLET
void SplashScreen::ConnectWallet(CWallet* wallet)
{
@ -177,6 +200,7 @@ void SplashScreen::subscribeToCoreSignals() @@ -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

8
src/qt/splashscreen.h

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
#ifndef BITCOIN_QT_SPLASHSCREEN_H
#define BITCOIN_QT_SPLASHSCREEN_H
#include <functional>
#include <QSplashScreen>
class CWallet;
@ -35,6 +36,11 @@ public Q_SLOTS: @@ -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<void(void)> &action);
protected:
bool eventFilter(QObject * obj, QEvent * ev);
private:
/** Connect core signals to splash screen */
void subscribeToCoreSignals();
@ -49,6 +55,8 @@ private: @@ -49,6 +55,8 @@ private:
int curAlignment;
QList<CWallet*> connectedWallets;
std::function<void(void)> breakAction;
};
#endif // BITCOIN_QT_SPLASHSCREEN_H

23
src/txdb.cpp

@ -11,6 +11,8 @@ @@ -11,6 +11,8 @@
#include "pow.h"
#include "uint256.h"
#include "util.h"
#include "ui_interface.h"
#include "init.h"
#include <stdint.h>
@ -366,13 +368,30 @@ bool CCoinsViewDB::Upgrade() { @@ -366,13 +368,30 @@ bool CCoinsViewDB::Upgrade() {
return true;
}
LogPrintf("Upgrading database...\n");
int64_t count = 0;
LogPrintf("Upgrading utxo-set database...\n");
LogPrintf("[0%%]...");
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()) {
break;
}
std::pair<unsigned char, uint256> key;
if (pcursor->GetKey(key) && key.first == DB_COINS) {
if (count++ % 256 == 0) {
uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1);
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)) {
return error("%s: cannot parse CCoins record", __func__);
@ -397,5 +416,7 @@ bool CCoinsViewDB::Upgrade() { @@ -397,5 +416,7 @@ bool CCoinsViewDB::Upgrade() {
}
}
db.WriteBatch(batch);
uiInterface.SetProgressBreakAction(std::function<void(void)>());
LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
return true;
}

3
src/ui_interface.h

@ -97,6 +97,9 @@ public: @@ -97,6 +97,9 @@ public:
/** Show progress e.g. for verifychain */
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
/** Set progress break action (possible "cancel button" triggers that action) */
boost::signals2::signal<void (std::function<void(void)> action)> SetProgressBreakAction;
/** New block has been accepted */
boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip;

Loading…
Cancel
Save