diff options
| author | langerhans <[email protected]> | 2019-06-09 19:49:48 +0200 |
|---|---|---|
| committer | langerhans <[email protected]> | 2019-06-09 19:51:03 +0200 |
| commit | d278efaccdc45e7155147d2c86a50f193eafdc07 (patch) | |
| tree | 05cf92afa059fafff80e460c1619edd5bec231b3 /src/qt/clientmodel.cpp | |
| parent | Revert "Change fPIE to fPIC (#1420)" (#1447) (diff) | |
| parent | Mark 1.14 ready for release (diff) | |
| download | discoin-d278efaccdc45e7155147d2c86a50f193eafdc07.tar.xz discoin-d278efaccdc45e7155147d2c86a50f193eafdc07.zip | |
Merge branch '1.14-branding'
Diffstat (limited to 'src/qt/clientmodel.cpp')
| -rw-r--r-- | src/qt/clientmodel.cpp | 225 |
1 files changed, 167 insertions, 58 deletions
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 8e29cdeb0..538bd9518 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,18 +1,21 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2016 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 "guiutil.h" #include "peertablemodel.h" #include "alert.h" #include "chainparams.h" #include "checkpoints.h" #include "clientversion.h" -#include "main.h" +#include "validation.h" #include "net.h" +#include "txmempool.h" #include "ui_interface.h" #include "util.h" @@ -21,19 +24,23 @@ #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) : +ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) : QObject(parent), - optionsModel(optionsModel), + optionsModel(_optionsModel), peerTableModel(0), - cachedNumBlocks(0), - cachedBlockDate(QDateTime()), - cachedReindexing(0), - cachedImporting(0), + banTableModel(0), pollTimer(0) { + cachedBestHeaderHeight = -1; + cachedBestHeaderTime = -1; peerTableModel = new PeerTableModel(this); + banTableModel = new BanTableModel(this); pollTimer = new QTimer(this); connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); pollTimer->start(MODEL_UPDATE_DELAY); @@ -48,16 +55,18 @@ ClientModel::~ClientModel() int ClientModel::getNumConnections(unsigned int flags) const { - LOCK(cs_vNodes); - if (flags == CONNECTIONS_ALL) // Shortcut if we want total - return vNodes.size(); - - int nNum = 0; - BOOST_FOREACH(CNode* pnode, vNodes) - if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) - nNum++; - - return nNum; + CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE; + + if(flags == CONNECTIONS_IN) + connections = CConnman::CONNECTIONS_IN; + else if (flags == CONNECTIONS_OUT) + connections = CConnman::CONNECTIONS_OUT; + else if (flags == CONNECTIONS_ALL) + connections = CConnman::CONNECTIONS_ALL; + + if(g_connman) + return g_connman->GetNodeCount(connections); + return 0; } int ClientModel::getNumBlocks() const @@ -66,14 +75,44 @@ int ClientModel::getNumBlocks() const return chainActive.Height(); } +int ClientModel::getHeaderTipHeight() const +{ + if (cachedBestHeaderHeight == -1) { + // make sure we initially populate the cache via a cs_main lock + // otherwise we need to wait for a tip update + LOCK(cs_main); + if (pindexBestHeader) { + cachedBestHeaderHeight = pindexBestHeader->nHeight; + cachedBestHeaderTime = pindexBestHeader->GetBlockTime(); + } + } + return cachedBestHeaderHeight; +} + +int64_t ClientModel::getHeaderTipTime() const +{ + if (cachedBestHeaderTime == -1) { + LOCK(cs_main); + if (pindexBestHeader) { + cachedBestHeaderHeight = pindexBestHeader->nHeight; + cachedBestHeaderTime = pindexBestHeader->GetBlockTime(); + } + } + return cachedBestHeaderTime; +} + quint64 ClientModel::getTotalBytesRecv() const { - return CNode::GetTotalBytesRecv(); + if(!g_connman) + return 0; + return g_connman->GetTotalBytesRecv(); } quint64 ClientModel::getTotalBytesSent() const { - return CNode::GetTotalBytesSent(); + if(!g_connman) + return 0; + return g_connman->GetTotalBytesSent(); } QDateTime ClientModel::getLastBlockDate() const @@ -86,46 +125,43 @@ QDateTime ClientModel::getLastBlockDate() const 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(Params().Checkpoints(), 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(); - 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; + return mempool.DynamicMemoryUsage(); +} - emit numBlocksChanged(newNumBlocks, newBlockDate); +double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const +{ + CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn); + if (!tip) + { + LOCK(cs_main); + tip = chainActive.Tip(); } + return GuessVerificationProgress(Params().TxData(), 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::updateNetworkActive(bool networkActive) +{ + Q_EMIT networkActiveChanged(networkActive); } void ClientModel::updateAlert(const QString &hash, int status) @@ -138,11 +174,11 @@ void ClientModel::updateAlert(const QString &hash, int status) CAlert alert = CAlert::getAlertByHash(hash_256); if(!alert.IsNull()) { - emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); + Q_EMIT message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); } } - emit alertsChanged(getStatusBarWarnings()); + Q_EMIT alertsChanged(getStatusBarWarnings()); } bool ClientModel::inInitialBlockDownload() const @@ -162,9 +198,24 @@ enum BlockSource ClientModel::getBlockSource() const return BLOCK_SOURCE_NONE; } +void ClientModel::setNetworkActive(bool active) +{ + if (g_connman) { + g_connman->SetNetworkActive(active); + } +} + +bool ClientModel::getNetworkActive() const +{ + if (g_connman) { + return g_connman->GetNetworkActive(); + } + return false; +} + QString ClientModel::getStatusBarWarnings() const { - return QString::fromStdString(GetWarnings("statusbar")); + return QString::fromStdString(GetWarnings("gui")); } OptionsModel *ClientModel::getOptionsModel() @@ -177,14 +228,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 @@ -192,14 +248,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 GUIUtil::boostPathToQString(GetDataDir()); +} + +void ClientModel::updateBanlist() +{ + banTableModel->refresh(); } // Handlers for core signals @@ -218,6 +279,12 @@ static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConn Q_ARG(int, newNumConnections)); } +static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive) +{ + QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection, + Q_ARG(bool, networkActive)); +} + static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) { qDebug() << "NotifyAlertChanged: " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status); @@ -226,12 +293,50 @@ static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, Ch Q_ARG(int, status)); } +static void BannedListChanged(ClientModel *clientmodel) +{ + 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 (fHeader) { + // cache best headers time and height to reduce future cs_main locks + clientmodel->cachedBestHeaderHeight = pIndex->nHeight; + clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime(); + } + // 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() { // Connect signals to client uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); + uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, 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, false)); + uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true)); } void ClientModel::unsubscribeFromCoreSignals() @@ -239,5 +344,9 @@ 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.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, 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, false)); + uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true)); } |