Skip to content

Commit 0c3542e

Browse files
committed
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
2 parents 65cc7aa + 542ce6e commit 0c3542e

File tree

6 files changed

+61
-3
lines changed

6 files changed

+61
-3
lines changed

src/init.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
13581358
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));
13591359

13601360
bool fLoaded = false;
1361-
while (!fLoaded) {
1361+
while (!fLoaded && !fRequestShutdown) {
13621362
bool fReset = fReindex;
13631363
std::string strLoadError;
13641364

@@ -1389,6 +1389,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
13891389
break;
13901390
}
13911391
}
1392+
if (fRequestShutdown) break;
13921393

13931394
if (!LoadBlockIndex(chainparams)) {
13941395
strLoadError = _("Error loading block database");
@@ -1466,7 +1467,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
14661467
fLoaded = true;
14671468
} while(false);
14681469

1469-
if (!fLoaded) {
1470+
if (!fLoaded && !fRequestShutdown) {
14701471
// first suggest a reindex
14711472
if (!fReset) {
14721473
bool fRet = uiInterface.ThreadSafeQuestion(

src/qt/bitcoin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ int main(int argc, char *argv[])
578578
// Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
579579
// IMPORTANT if it is no longer a typedef use the normal variant above
580580
qRegisterMetaType< CAmount >("CAmount");
581+
qRegisterMetaType< std::function<void(void)> >("std::function<void(void)>");
581582

582583
/// 3. Application identification
583584
// must be set before OptionsModel is initialized or translations are loaded,

src/qt/splashscreen.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,24 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
131131
move(QApplication::desktop()->screenGeometry().center() - r.center());
132132

133133
subscribeToCoreSignals();
134+
installEventFilter(this);
134135
}
135136

136137
SplashScreen::~SplashScreen()
137138
{
138139
unsubscribeFromCoreSignals();
139140
}
140141

142+
bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) {
143+
if (ev->type() == QEvent::KeyPress) {
144+
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
145+
if(keyEvent->text()[0] == 'q' && breakAction != nullptr) {
146+
breakAction();
147+
}
148+
}
149+
return QObject::eventFilter(obj, ev);
150+
}
151+
141152
void SplashScreen::slotFinish(QWidget *mainWin)
142153
{
143154
Q_UNUSED(mainWin);
@@ -164,6 +175,18 @@ static void ShowProgress(SplashScreen *splash, const std::string &title, int nPr
164175
InitMessage(splash, title + strprintf("%d", nProgress) + "%");
165176
}
166177

178+
void SplashScreen::setBreakAction(const std::function<void(void)> &action)
179+
{
180+
breakAction = action;
181+
}
182+
183+
static void SetProgressBreakAction(SplashScreen *splash, const std::function<void(void)> &action)
184+
{
185+
QMetaObject::invokeMethod(splash, "setBreakAction",
186+
Qt::QueuedConnection,
187+
Q_ARG(std::function<void(void)>, action));
188+
}
189+
167190
#ifdef ENABLE_WALLET
168191
void SplashScreen::ConnectWallet(CWallet* wallet)
169192
{
@@ -177,6 +200,7 @@ void SplashScreen::subscribeToCoreSignals()
177200
// Connect signals to client
178201
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
179202
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
203+
uiInterface.SetProgressBreakAction.connect(boost::bind(SetProgressBreakAction, this, _1));
180204
#ifdef ENABLE_WALLET
181205
uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1));
182206
#endif

src/qt/splashscreen.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef BITCOIN_QT_SPLASHSCREEN_H
66
#define BITCOIN_QT_SPLASHSCREEN_H
77

8+
#include <functional>
89
#include <QSplashScreen>
910

1011
class CWallet;
@@ -35,6 +36,11 @@ public Q_SLOTS:
3536
/** Show message and progress */
3637
void showMessage(const QString &message, int alignment, const QColor &color);
3738

39+
/** Sets the break action */
40+
void setBreakAction(const std::function<void(void)> &action);
41+
protected:
42+
bool eventFilter(QObject * obj, QEvent * ev);
43+
3844
private:
3945
/** Connect core signals to splash screen */
4046
void subscribeToCoreSignals();
@@ -49,6 +55,8 @@ public Q_SLOTS:
4955
int curAlignment;
5056

5157
QList<CWallet*> connectedWallets;
58+
59+
std::function<void(void)> breakAction;
5260
};
5361

5462
#endif // BITCOIN_QT_SPLASHSCREEN_H

src/txdb.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "pow.h"
1212
#include "uint256.h"
1313
#include "util.h"
14+
#include "ui_interface.h"
15+
#include "init.h"
1416

1517
#include <stdint.h>
1618

@@ -366,13 +368,30 @@ bool CCoinsViewDB::Upgrade() {
366368
return true;
367369
}
368370

369-
LogPrintf("Upgrading database...\n");
371+
int64_t count = 0;
372+
LogPrintf("Upgrading utxo-set database...\n");
373+
LogPrintf("[0%%]...");
370374
size_t batch_size = 1 << 24;
371375
CDBBatch batch(db);
376+
uiInterface.SetProgressBreakAction(StartShutdown);
377+
int reportDone = 0;
372378
while (pcursor->Valid()) {
373379
boost::this_thread::interruption_point();
380+
if (ShutdownRequested()) {
381+
break;
382+
}
374383
std::pair<unsigned char, uint256> key;
375384
if (pcursor->GetKey(key) && key.first == DB_COINS) {
385+
if (count++ % 256 == 0) {
386+
uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1);
387+
int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
388+
uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", percentageDone);
389+
if (reportDone < percentageDone/10) {
390+
// report max. every 10% step
391+
LogPrintf("[%d%%]...", percentageDone);
392+
reportDone = percentageDone/10;
393+
}
394+
}
376395
CCoins old_coins;
377396
if (!pcursor->GetValue(old_coins)) {
378397
return error("%s: cannot parse CCoins record", __func__);
@@ -397,5 +416,7 @@ bool CCoinsViewDB::Upgrade() {
397416
}
398417
}
399418
db.WriteBatch(batch);
419+
uiInterface.SetProgressBreakAction(std::function<void(void)>());
420+
LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
400421
return true;
401422
}

src/ui_interface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class CClientUIInterface
9797
/** Show progress e.g. for verifychain */
9898
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
9999

100+
/** Set progress break action (possible "cancel button" triggers that action) */
101+
boost::signals2::signal<void (std::function<void(void)> action)> SetProgressBreakAction;
102+
100103
/** New block has been accepted */
101104
boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip;
102105

0 commit comments

Comments
 (0)