aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2015-11-30 12:58:01 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2015-11-30 13:04:29 +0100
commit96b802510da0750aabc4f3ba6750cb5ce76f2b8c (patch)
tree3374e1ba583bf511745c2cd4c02ff6ecb6d3cc8b
parenta7751824ce8a7e1cc5511794516fe674bc3eaa3c (diff)
parent9af5f9cb8773da2904aa3819234aaebd2efb5d15 (diff)
Merge pull request #7112
9af5f9c Move uiInterface.NotifyBlockTip signal above the core/wallet signal - This will keep getbestblockhash more in sync with blocknotify callbacks (Jonas Schnelli) 4082e46 [Qt] call GuessVerificationProgress synchronous during core signal, pass double over UI signal (Jonas Schnelli) 947d20b [Qt] reduce cs_main in getVerificationProgress() (Jonas Schnelli) e6d50fc [Qt] update block tip (height and date) without locking cs_main, update always (each block) (Jonas Schnelli) 012fc91 NotifyBlockTip signal: switch from hash (uint256) to CBlockIndex* - also adds a boolean for indication if the tip update was happening during initial sync - emit notification also during initial sync (Jonas Schnelli)
-rw-r--r--src/init.cpp7
-rw-r--r--src/main.cpp58
-rw-r--r--src/qt/bitcoingui.cpp8
-rw-r--r--src/qt/bitcoingui.h2
-rw-r--r--src/qt/clientmodel.cpp65
-rw-r--r--src/qt/clientmodel.h10
-rw-r--r--src/qt/rpcconsole.cpp6
-rw-r--r--src/qt/rpcconsole.h2
-rw-r--r--src/qt/sendcoinsdialog.cpp2
-rw-r--r--src/ui_interface.h3
10 files changed, 83 insertions, 80 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 191c2ed8ae..e6ce3d7b59 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -515,11 +515,14 @@ std::string LicenseInfo()
"\n";
}
-static void BlockNotifyCallback(const uint256& hashNewTip)
+static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex)
{
+ if (initialSync || !pBlockIndex)
+ return;
+
std::string strCmd = GetArg("-blocknotify", "");
- boost::replace_all(strCmd, "%s", hashNewTip.GetHex());
+ boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex());
boost::thread t(runCommand, strCmd); // thread runs free
}
diff --git a/src/main.cpp b/src/main.cpp
index 901a34bdec..33bd2e0ce1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2606,37 +2606,41 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
// Notifications/callbacks that can run without cs_main
- if (!fInitialDownload) {
- // Find the hashes of all blocks that weren't previously in the best chain.
- std::vector<uint256> vHashes;
- CBlockIndex *pindexToAnnounce = pindexNewTip;
- while (pindexToAnnounce != pindexFork) {
- vHashes.push_back(pindexToAnnounce->GetBlockHash());
- pindexToAnnounce = pindexToAnnounce->pprev;
- if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
- // Limit announcements in case of a huge reorganization.
- // Rely on the peer's synchronization mechanism in that case.
- break;
+ // Always notify the UI if a new block tip was connected
+ if (pindexFork != pindexNewTip) {
+ uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
+
+ if (!fInitialDownload) {
+ // Find the hashes of all blocks that weren't previously in the best chain.
+ std::vector<uint256> vHashes;
+ CBlockIndex *pindexToAnnounce = pindexNewTip;
+ while (pindexToAnnounce != pindexFork) {
+ vHashes.push_back(pindexToAnnounce->GetBlockHash());
+ pindexToAnnounce = pindexToAnnounce->pprev;
+ if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
+ // Limit announcements in case of a huge reorganization.
+ // Rely on the peer's synchronization mechanism in that case.
+ break;
+ }
}
- }
- // Relay inventory, but don't relay old inventory during initial block download.
- int nBlockEstimate = 0;
- if (fCheckpointsEnabled)
- nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints());
- {
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes) {
- if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
- BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
- pnode->PushBlockHash(hash);
+ // Relay inventory, but don't relay old inventory during initial block download.
+ int nBlockEstimate = 0;
+ if (fCheckpointsEnabled)
+ nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints());
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes) {
+ if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
+ BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
+ pnode->PushBlockHash(hash);
+ }
}
}
}
- }
- // Notify external listeners about the new tip.
- if (!vHashes.empty()) {
- GetMainSignals().UpdatedBlockTip(pindexNewTip);
- uiInterface.NotifyBlockTip(vHashes.front());
+ // Notify external listeners about the new tip.
+ if (!vHashes.empty()) {
+ GetMainSignals().UpdatedBlockTip(pindexNewTip);
+ }
}
}
} while(pindexMostWork != chainActive.Tip());
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 853a29e661..b2bd167aea 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -453,8 +453,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
setNumConnections(clientModel->getNumConnections());
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
- connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
+ setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL));
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double)));
// Receive and report messages from client model
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
@@ -682,7 +682,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)
+void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress)
{
if(!clientModel)
return;
@@ -759,7 +759,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
progressBarLabel->setVisible(true);
progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
progressBar->setMaximum(1000000000);
- progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5);
+ progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
progressBar->setVisible(true);
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 945adcd459..b121a443e7 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -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);
+ void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress);
/** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 566e8fa62d..d36d129c1a 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -22,17 +22,16 @@
#include <QDebug>
#include <QTimer>
+class CBlockIndex;
+
static const int64_t nClientStartupTime = GetTime();
+static int64_t nLastBlockTipUpdateNotification = 0;
ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
QObject(parent),
optionsModel(optionsModel),
peerTableModel(0),
banTableModel(0),
- cachedNumBlocks(0),
- cachedBlockDate(QDateTime()),
- cachedReindexing(0),
- cachedImporting(0),
pollTimer(0)
{
peerTableModel = new PeerTableModel(this);
@@ -99,40 +98,21 @@ size_t ClientModel::getMempoolDynamicUsage() const
return mempool.DynamicMemoryUsage();
}
-double ClientModel::getVerificationProgress() const
+double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
- LOCK(cs_main);
- return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip());
+ CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
+ if (!tip)
+ {
+ LOCK(cs_main);
+ tip = chainActive.Tip();
+ }
+ return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), tip);
}
void ClientModel::updateTimer()
{
- // Get required lock upfront. This avoids the GUI from getting stuck on
- // periodical polls if the core is holding the locks for a longer time -
- // for example, during a wallet rescan.
- TRY_LOCK(cs_main, lockMain);
- if (!lockMain)
- return;
-
- // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
- // Periodically check and update with a timer.
- int newNumBlocks = getNumBlocks();
- QDateTime newBlockDate = getLastBlockDate();
-
- // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
- if (cachedNumBlocks != newNumBlocks ||
- cachedBlockDate != newBlockDate ||
- cachedReindexing != fReindex ||
- cachedImporting != fImporting)
- {
- cachedNumBlocks = newNumBlocks;
- cachedBlockDate = newBlockDate;
- cachedReindexing = fReindex;
- cachedImporting = fImporting;
-
- Q_EMIT numBlocksChanged(newNumBlocks, newBlockDate);
- }
-
+ // no locking required at this point
+ // the following calls will aquire the required lock
Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
}
@@ -261,6 +241,23 @@ static void BannedListChanged(ClientModel *clientmodel)
QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}
+static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
+{
+ // lock free async UI updates in case we have a new block tip
+ // during initial sync, only update the UI if the last update
+ // was > 250ms (MODEL_UPDATE_DELAY) ago
+ int64_t now = 0;
+ if (initialSync)
+ now = GetTimeMillis();
+
+ // if we are in-sync, update the UI regardless of last update time
+ if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) {
+ //pass a async signal to the UI thread
+ Q_EMIT clientmodel->numBlocksChanged(pIndex->nHeight, QDateTime::fromTime_t(pIndex->GetBlockTime()), clientmodel->getVerificationProgress(pIndex));
+ nLastBlockTipUpdateNotification = now;
+ }
+}
+
void ClientModel::subscribeToCoreSignals()
{
// Connect signals to client
@@ -268,6 +265,7 @@ void ClientModel::subscribeToCoreSignals()
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
+ uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2));
}
void ClientModel::unsubscribeFromCoreSignals()
@@ -277,4 +275,5 @@ void ClientModel::unsubscribeFromCoreSignals()
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
+ uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2));
}
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 493a759331..2d204fdb67 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -15,6 +15,7 @@ class PeerTableModel;
class TransactionTableModel;
class CWallet;
+class CBlockIndex;
QT_BEGIN_NAMESPACE
class QTimer;
@@ -59,7 +60,7 @@ public:
quint64 getTotalBytesRecv() const;
quint64 getTotalBytesSent() const;
- double getVerificationProgress() const;
+ double getVerificationProgress(const CBlockIndex *tip) const;
QDateTime getLastBlockDate() const;
//! Return true if core is doing initial block download
@@ -81,11 +82,6 @@ private:
PeerTableModel *peerTableModel;
BanTableModel *banTableModel;
- int cachedNumBlocks;
- QDateTime cachedBlockDate;
- bool cachedReindexing;
- bool cachedImporting;
-
QTimer *pollTimer;
void subscribeToCoreSignals();
@@ -93,7 +89,7 @@ private:
Q_SIGNALS:
void numConnectionsChanged(int count);
- void numBlocksChanged(int count, const QDateTime& blockDate);
+ void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress);
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes);
void alertsChanged(const QString &warnings);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index b2b4fd0fab..30e551de19 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -343,8 +343,8 @@ void RPCConsole::setClientModel(ClientModel *model)
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
- connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
+ setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL));
+ connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double)));
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
@@ -525,7 +525,7 @@ void RPCConsole::setNumConnections(int count)
ui->numberOfConnections->setText(connections);
}
-void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
+void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress)
{
ui->numberOfBlocks->setText(QString::number(count));
ui->lastBlockTime->setText(blockDate.toString());
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 4b242affcd..4aebad480c 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -83,7 +83,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);
+ void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress);
/** 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 */
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 7b714be5b1..0fd86da034 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -124,7 +124,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel)
this->clientModel = clientModel;
if (clientModel) {
- connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel()));
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(updateSmartFeeLabel()));
}
}
diff --git a/src/ui_interface.h b/src/ui_interface.h
index e402479933..00d9303124 100644
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -15,6 +15,7 @@
class CBasicKeyStore;
class CWallet;
class uint256;
+class CBlockIndex;
/** General change type (added, updated, removed). */
enum ChangeType
@@ -94,7 +95,7 @@ public:
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
/** New block has been accepted */
- boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip;
+ boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip;
/** Banlist did change. */
boost::signals2::signal<void (void)> BannedListChanged;