diff options
author | Luke Dashjr <luke-jr+git@utopios.org> | 2016-08-09 05:45:50 +0000 |
---|---|---|
committer | Luke Dashjr <luke-jr+git@utopios.org> | 2016-08-09 05:45:50 +0000 |
commit | df634908ba758232413c50e8f1f7a80d546d777b (patch) | |
tree | 92cccae378b192f5f70986d2167209cbfd24ae08 /src/qt/clientmodel.cpp | |
parent | e98e3dde6a976a2c8f266ee963d6931fd4b37262 (diff) | |
parent | e4382fbef56a0e04b0ed834e8b3a3a16f81db149 (diff) | |
download | bitcoin-df634908ba758232413c50e8f1f7a80d546d777b.tar.xz |
Merge tag 'branch-0.13' into bugfix_gitdir
Diffstat (limited to 'src/qt/clientmodel.cpp')
-rw-r--r-- | src/qt/clientmodel.cpp | 170 |
1 files changed, 98 insertions, 72 deletions
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index aedda49071..14661b857a 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,38 +1,41 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2011-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "clientmodel.h" +#include "bantablemodel.h" #include "guiconstants.h" #include "peertablemodel.h" -#include "alert.h" #include "chainparams.h" #include "checkpoints.h" #include "clientversion.h" -#include "main.h" #include "net.h" +#include "txmempool.h" #include "ui_interface.h" #include "util.h" #include <stdint.h> -#include <QDateTime> #include <QDebug> #include <QTimer> +class CBlockIndex; + static const int64_t nClientStartupTime = GetTime(); +static int64_t nLastHeaderTipUpdateNotification = 0; +static int64_t nLastBlockTipUpdateNotification = 0; ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), peerTableModel(0), - cachedNumBlocks(0), - cachedReindexing(0), cachedImporting(0), - numBlocksAtStartup(-1), pollTimer(0) + banTableModel(0), + pollTimer(0) { peerTableModel = new PeerTableModel(this); + banTableModel = new BanTableModel(this); pollTimer = new QTimer(this); connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); pollTimer->start(MODEL_UPDATE_DELAY); @@ -52,9 +55,9 @@ int ClientModel::getNumConnections(unsigned int flags) const return vNodes.size(); int nNum = 0; - BOOST_FOREACH(CNode* pnode, vNodes) - if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) - nNum++; + BOOST_FOREACH(const CNode* pnode, vNodes) + if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) + nNum++; return nNum; } @@ -65,12 +68,6 @@ int ClientModel::getNumBlocks() const return chainActive.Height(); } -int ClientModel::getNumBlocksAtStartup() -{ - if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks(); - return numBlocksAtStartup; -} - quint64 ClientModel::getTotalBytesRecv() const { return CNode::GetTotalBytesRecv(); @@ -84,64 +81,50 @@ quint64 ClientModel::getTotalBytesSent() const QDateTime ClientModel::getLastBlockDate() const { LOCK(cs_main); + if (chainActive.Tip()) return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime()); - else - return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network + + return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network } -double ClientModel::getVerificationProgress() const +long ClientModel::getMempoolSize() const { - LOCK(cs_main); - return Checkpoints::GuessVerificationProgress(chainActive.Tip()); + return mempool.size(); } -void ClientModel::updateTimer() +size_t ClientModel::getMempoolDynamicUsage() const { - // 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(); - - // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state - if (cachedNumBlocks != newNumBlocks || - cachedReindexing != fReindex || cachedImporting != fImporting) - { - cachedNumBlocks = newNumBlocks; - cachedReindexing = fReindex; - cachedImporting = fImporting; + return mempool.DynamicMemoryUsage(); +} - emit numBlocksChanged(newNumBlocks); +double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const +{ + CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn); + if (!tip) + { + LOCK(cs_main); + tip = chainActive.Tip(); } + return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), tip); +} - emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); +void ClientModel::updateTimer() +{ + // no locking required at this point + // the following calls will acquire the required lock + Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage()); + Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } void ClientModel::updateNumConnections(int numConnections) { - emit numConnectionsChanged(numConnections); + Q_EMIT numConnectionsChanged(numConnections); } -void ClientModel::updateAlert(const QString &hash, int status) +void ClientModel::updateAlert() { - // Show error message notification for new alert - if(status == CT_NEW) - { - uint256 hash_256; - hash_256.SetHex(hash.toStdString()); - CAlert alert = CAlert::getAlertByHash(hash_256); - if(!alert.IsNull()) - { - emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); - } - } - - emit alertsChanged(getStatusBarWarnings()); + Q_EMIT alertsChanged(getStatusBarWarnings()); } bool ClientModel::inInitialBlockDownload() const @@ -163,7 +146,7 @@ enum BlockSource ClientModel::getBlockSource() const QString ClientModel::getStatusBarWarnings() const { - return QString::fromStdString(GetWarnings("statusbar")); + return QString::fromStdString(GetWarnings("gui")); } OptionsModel *ClientModel::getOptionsModel() @@ -176,14 +159,19 @@ PeerTableModel *ClientModel::getPeerTableModel() return peerTableModel; } +BanTableModel *ClientModel::getBanTableModel() +{ + return banTableModel; +} + QString ClientModel::formatFullVersion() const { return QString::fromStdString(FormatFullVersion()); } -QString ClientModel::formatBuildDate() const +QString ClientModel::formatSubVersion() const { - return QString::fromStdString(CLIENT_DATE); + return QString::fromStdString(strSubVersion); } bool ClientModel::isReleaseVersion() const @@ -191,14 +179,19 @@ bool ClientModel::isReleaseVersion() const return CLIENT_VERSION_IS_RELEASE; } -QString ClientModel::clientName() const +QString ClientModel::formatClientStartupTime() const { - return QString::fromStdString(CLIENT_NAME); + return QDateTime::fromTime_t(nClientStartupTime).toString(); } -QString ClientModel::formatClientStartupTime() const +QString ClientModel::dataDir() const { - return QDateTime::fromTime_t(nClientStartupTime).toString(); + return QString::fromStdString(GetDataDir().string()); +} + +void ClientModel::updateBanlist() +{ + banTableModel->refresh(); } // Handlers for core signals @@ -212,17 +205,44 @@ static void ShowProgress(ClientModel *clientmodel, const std::string &title, int static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections) { - // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections); + // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections); QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, Q_ARG(int, newNumConnections)); } -static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) +static void NotifyAlertChanged(ClientModel *clientmodel) +{ + qDebug() << "NotifyAlertChanged"; + QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection); +} + +static void BannedListChanged(ClientModel *clientmodel) { - qDebug() << "NotifyAlertChanged : " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status); - QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection, - Q_ARG(QString, QString::fromStdString(hash.GetHex())), - Q_ARG(int, status)); + qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__); + QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection); +} + +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 + // was > 250ms (MODEL_UPDATE_DELAY) ago + int64_t now = 0; + 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 - 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)), + Q_ARG(bool, fHeader)); + nLastUpdateNotification = now; + } } void ClientModel::subscribeToCoreSignals() @@ -230,7 +250,10 @@ void ClientModel::subscribeToCoreSignals() // Connect signals to client uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); - uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this)); + uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); + uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false)); + uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true)); } void ClientModel::unsubscribeFromCoreSignals() @@ -238,5 +261,8 @@ void ClientModel::unsubscribeFromCoreSignals() // Disconnect signals from client uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); - uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this)); + uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); + uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false)); + uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true)); } |