Skip to content

Commit

Permalink
Report reindexing progress in GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa committed May 16, 2016
1 parent d3d7547 commit b4d24e1
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 19 deletions.
3 changes: 3 additions & 0 deletions qa/rpc-tests/reindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import time

class ReindexTest(BitcoinTestFramework):

Expand All @@ -26,6 +27,8 @@ def reindex(self, justchainstate=False):
stop_node(self.nodes[0], 0)
wait_bitcoinds()
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"])
while self.nodes[0].getblockcount() < blockcount:
time.sleep(0.1)
assert_equal(self.nodes[0].getblockcount(), blockcount)
print("Success")

Expand Down
39 changes: 39 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2883,6 +2883,28 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
return true;
}

static void NotifyHeaderTip() {
bool fNotify = false;
bool fInitialBlockDownload = false;
static CBlockIndex* pindexHeaderOld = NULL;
CBlockIndex* pindexHeader = NULL;
{
LOCK(cs_main);
if (!setBlockIndexCandidates.empty()) {
pindexHeader = *setBlockIndexCandidates.rbegin();
}
if (pindexHeader != pindexHeaderOld) {
fNotify = true;
fInitialBlockDownload = IsInitialBlockDownload();
pindexHeaderOld = pindexHeader;
}
}
// Send block tip changed notifications without cs_main
if (fNotify) {
uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader);
}
}

/**
* Make the best chain active, in multiple steps. The result is either failure
* or an activated best chain. pblock is either NULL or a pointer to a block
Expand Down Expand Up @@ -3499,6 +3521,8 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
return error("%s: AcceptBlock FAILED", __func__);
}

NotifyHeaderTip();

if (!ActivateBestChain(state, chainparams, pblock))
return error("%s: ActivateBestChain failed", __func__);

Expand Down Expand Up @@ -4054,6 +4078,16 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
LogPrint("reindex", "Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
}

// Activate the genesis block so normal node progress can continue
if (hash == chainparams.GetConsensus().hashGenesisBlock) {
CValidationState state;
if (!ActivateBestChain(state, chainparams)) {
break;
}
}

NotifyHeaderTip();

// Recursively process earlier encountered successors of this block
deque<uint256> queue;
queue.push_back(hash);
Expand All @@ -4077,6 +4111,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
}
range.first++;
mapBlocksUnknownParent.erase(it);
NotifyHeaderTip();
}
}
} catch (const std::exception& e) {
Expand Down Expand Up @@ -5088,6 +5123,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
}

{
LOCK(cs_main);

if (nCount == 0) {
Expand Down Expand Up @@ -5171,6 +5207,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}

CheckBlockIndex(chainparams.GetConsensus());
}

NotifyHeaderTip();
}

else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
Expand Down
18 changes: 14 additions & 4 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
setNumConnections(clientModel->getNumConnections());
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));

setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL));
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double)));
setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL), false);
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));

// Receive and report messages from client model
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
Expand Down Expand Up @@ -696,7 +696,7 @@ void BitcoinGUI::setNumConnections(int count)
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}

void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress)
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header)
{
if(!clientModel)
return;
Expand All @@ -708,15 +708,25 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
enum BlockSource blockSource = clientModel->getBlockSource();
switch (blockSource) {
case BLOCK_SOURCE_NETWORK:
if (header) {
return;
}
progressBarLabel->setText(tr("Synchronizing with network..."));
break;
case BLOCK_SOURCE_DISK:
progressBarLabel->setText(tr("Importing blocks from disk..."));
if (header) {
progressBarLabel->setText(tr("Indexing blocks on disk..."));
} else {
progressBarLabel->setText(tr("Processing blocks on disk..."));
}
break;
case BLOCK_SOURCE_REINDEX:
progressBarLabel->setText(tr("Reindexing blocks on disk..."));
break;
case BLOCK_SOURCE_NONE:
if (header) {
return;
}
// Case: not Importing, not Reindexing and no network connection
progressBarLabel->setText(tr("No block source available..."));
break;
Expand Down
2 changes: 1 addition & 1 deletion src/qt/bitcoingui.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public Q_SLOTS:
/** Set number of connections shown in the UI */
void setNumConnections(int count);
/** Set number of blocks and last block date shown in the UI */
void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress);
void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers);

/** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title
Expand Down
18 changes: 12 additions & 6 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
class CBlockIndex;

static const int64_t nClientStartupTime = GetTime();
static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
Expand Down Expand Up @@ -226,7 +227,7 @@ static void BannedListChanged(ClientModel *clientmodel)
QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
{
// lock free async UI updates in case we have a new block tip
// during initial sync, only update the UI if the last update
Expand All @@ -235,14 +236,17 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
if (initialSync)
now = GetTimeMillis();

int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;

// if we are in-sync, update the UI regardless of last update time
if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) {
if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
//pass a async signal to the UI thread
QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
Q_ARG(int, pIndex->nHeight),
Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
Q_ARG(double, clientmodel->getVerificationProgress(pIndex)));
nLastBlockTipUpdateNotification = now;
Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
Q_ARG(bool, fHeader));
nLastUpdateNotification = now;
}
}

Expand All @@ -253,7 +257,8 @@ void ClientModel::subscribeToCoreSignals()
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2));
uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
}

void ClientModel::unsubscribeFromCoreSignals()
Expand All @@ -263,5 +268,6 @@ void ClientModel::unsubscribeFromCoreSignals()
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2));
uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
}
2 changes: 1 addition & 1 deletion src/qt/clientmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class ClientModel : public QObject

Q_SIGNALS:
void numConnectionsChanged(int count);
void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress);
void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress, bool header);
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes);
void alertsChanged(const QString &warnings);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
Expand Down
12 changes: 7 additions & 5 deletions src/qt/rpcconsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,8 @@ void RPCConsole::setClientModel(ClientModel *model)
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));

setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL));
connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double)));
setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL), false);
connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));

updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
Expand Down Expand Up @@ -585,10 +585,12 @@ void RPCConsole::setNumConnections(int count)
ui->numberOfConnections->setText(connections);
}

void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress)
void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers)
{
ui->numberOfBlocks->setText(QString::number(count));
ui->lastBlockTime->setText(blockDate.toString());
if (!headers) {
ui->numberOfBlocks->setText(QString::number(count));
ui->lastBlockTime->setText(blockDate.toString());
}
}

void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage)
Expand Down
2 changes: 1 addition & 1 deletion src/qt/rpcconsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public Q_SLOTS:
/** Set number of connections shown in the UI */
void setNumConnections(int count);
/** Set number of blocks and last block date shown in the UI */
void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress);
void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers);
/** Set size (number of transactions and memory usage) of the mempool in the UI */
void setMempoolSize(long numberOfTxs, size_t dynUsage);
/** Go forward or back in history */
Expand Down
2 changes: 1 addition & 1 deletion src/qt/sendcoinsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel)
this->clientModel = clientModel;

if (clientModel) {
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(updateSmartFeeLabel()));
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel()));
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/ui_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ class CClientUIInterface
/** New block has been accepted */
boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip;

/** Best header has changed */
boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyHeaderTip;

/** Banlist did change. */
boost::signals2::signal<void (void)> BannedListChanged;
};
Expand Down

0 comments on commit b4d24e1

Please sign in to comment.