Merge #10660: Allow to cancel the txdb upgrade via splashscreen keypress 'q'
542ce6eReport [CANCELLED] instead of [DONE] when shut down during txdb upgrade (Jonas Schnelli)83fbea3Report txdb upgrade not more often then every 10% (Jonas Schnelli)06c5b6eShow txdb upgrade progress in debug log (Jonas Schnelli)316fcb5Allow to cancel the txdb upgrade via splashscreen callback (Jonas Schnelli)ae09d45Allow to shut down during txdb upgrade (Jonas Schnelli)00cb69b[Qt] allow to execute a callback during splashscreen progress (Jonas Schnelli) Tree-SHA512: 23190f23f441bfd60821e49f8b3698a6bef97eb0e0ee659328e4a7395769ecd1616420eacc38aa1fa0ff62b9de5f13a0098dc798cdec6bff649575cefebc0db2
This commit is contained in:
commit
0c3542e5de
@ -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));
|
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;
|
bool fLoaded = false;
|
||||||
while (!fLoaded) {
|
while (!fLoaded && !fRequestShutdown) {
|
||||||
bool fReset = fReindex;
|
bool fReset = fReindex;
|
||||||
std::string strLoadError;
|
std::string strLoadError;
|
||||||
|
|
||||||
@ -1389,6 +1389,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fRequestShutdown) break;
|
||||||
|
|
||||||
if (!LoadBlockIndex(chainparams)) {
|
if (!LoadBlockIndex(chainparams)) {
|
||||||
strLoadError = _("Error loading block database");
|
strLoadError = _("Error loading block database");
|
||||||
@ -1466,7 +1467,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
fLoaded = true;
|
fLoaded = true;
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
if (!fLoaded) {
|
if (!fLoaded && !fRequestShutdown) {
|
||||||
// first suggest a reindex
|
// first suggest a reindex
|
||||||
if (!fReset) {
|
if (!fReset) {
|
||||||
bool fRet = uiInterface.ThreadSafeQuestion(
|
bool fRet = uiInterface.ThreadSafeQuestion(
|
||||||
|
|||||||
@ -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)
|
// 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
|
// IMPORTANT if it is no longer a typedef use the normal variant above
|
||||||
qRegisterMetaType< CAmount >("CAmount");
|
qRegisterMetaType< CAmount >("CAmount");
|
||||||
|
qRegisterMetaType< std::function<void(void)> >("std::function<void(void)>");
|
||||||
|
|
||||||
/// 3. Application identification
|
/// 3. Application identification
|
||||||
// must be set before OptionsModel is initialized or translations are loaded,
|
// must be set before OptionsModel is initialized or translations are loaded,
|
||||||
|
|||||||
@ -131,6 +131,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||||||
move(QApplication::desktop()->screenGeometry().center() - r.center());
|
move(QApplication::desktop()->screenGeometry().center() - r.center());
|
||||||
|
|
||||||
subscribeToCoreSignals();
|
subscribeToCoreSignals();
|
||||||
|
installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
SplashScreen::~SplashScreen()
|
SplashScreen::~SplashScreen()
|
||||||
@ -138,6 +139,16 @@ SplashScreen::~SplashScreen()
|
|||||||
unsubscribeFromCoreSignals();
|
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)
|
void SplashScreen::slotFinish(QWidget *mainWin)
|
||||||
{
|
{
|
||||||
Q_UNUSED(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) + "%");
|
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
|
#ifdef ENABLE_WALLET
|
||||||
void SplashScreen::ConnectWallet(CWallet* wallet)
|
void SplashScreen::ConnectWallet(CWallet* wallet)
|
||||||
{
|
{
|
||||||
@ -177,6 +200,7 @@ void SplashScreen::subscribeToCoreSignals()
|
|||||||
// Connect signals to client
|
// Connect signals to client
|
||||||
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
|
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
|
||||||
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
|
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
|
||||||
|
uiInterface.SetProgressBreakAction.connect(boost::bind(SetProgressBreakAction, this, _1));
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1));
|
uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#ifndef BITCOIN_QT_SPLASHSCREEN_H
|
#ifndef BITCOIN_QT_SPLASHSCREEN_H
|
||||||
#define BITCOIN_QT_SPLASHSCREEN_H
|
#define BITCOIN_QT_SPLASHSCREEN_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <QSplashScreen>
|
#include <QSplashScreen>
|
||||||
|
|
||||||
class CWallet;
|
class CWallet;
|
||||||
@ -35,6 +36,11 @@ public Q_SLOTS:
|
|||||||
/** Show message and progress */
|
/** Show message and progress */
|
||||||
void showMessage(const QString &message, int alignment, const QColor &color);
|
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:
|
private:
|
||||||
/** Connect core signals to splash screen */
|
/** Connect core signals to splash screen */
|
||||||
void subscribeToCoreSignals();
|
void subscribeToCoreSignals();
|
||||||
@ -49,6 +55,8 @@ private:
|
|||||||
int curAlignment;
|
int curAlignment;
|
||||||
|
|
||||||
QList<CWallet*> connectedWallets;
|
QList<CWallet*> connectedWallets;
|
||||||
|
|
||||||
|
std::function<void(void)> breakAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_QT_SPLASHSCREEN_H
|
#endif // BITCOIN_QT_SPLASHSCREEN_H
|
||||||
|
|||||||
23
src/txdb.cpp
23
src/txdb.cpp
@ -11,6 +11,8 @@
|
|||||||
#include "pow.h"
|
#include "pow.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@ -366,13 +368,30 @@ bool CCoinsViewDB::Upgrade() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("Upgrading database...\n");
|
int64_t count = 0;
|
||||||
|
LogPrintf("Upgrading utxo-set database...\n");
|
||||||
|
LogPrintf("[0%%]...");
|
||||||
size_t batch_size = 1 << 24;
|
size_t batch_size = 1 << 24;
|
||||||
CDBBatch batch(db);
|
CDBBatch batch(db);
|
||||||
|
uiInterface.SetProgressBreakAction(StartShutdown);
|
||||||
|
int reportDone = 0;
|
||||||
while (pcursor->Valid()) {
|
while (pcursor->Valid()) {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
if (ShutdownRequested()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
std::pair<unsigned char, uint256> key;
|
std::pair<unsigned char, uint256> key;
|
||||||
if (pcursor->GetKey(key) && key.first == DB_COINS) {
|
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;
|
CCoins old_coins;
|
||||||
if (!pcursor->GetValue(old_coins)) {
|
if (!pcursor->GetValue(old_coins)) {
|
||||||
return error("%s: cannot parse CCoins record", __func__);
|
return error("%s: cannot parse CCoins record", __func__);
|
||||||
@ -397,5 +416,7 @@ bool CCoinsViewDB::Upgrade() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.WriteBatch(batch);
|
db.WriteBatch(batch);
|
||||||
|
uiInterface.SetProgressBreakAction(std::function<void(void)>());
|
||||||
|
LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,6 +97,9 @@ public:
|
|||||||
/** Show progress e.g. for verifychain */
|
/** Show progress e.g. for verifychain */
|
||||||
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
|
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 */
|
/** New block has been accepted */
|
||||||
boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip;
|
boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user