Merge #10114: [tests] sync_with_ping should assert that ping hasn't timed out
[bitcoinplatinum.git] / src / qt / clientmodel.cpp
blobbb10e494220689b30e9583a62fe230ea92c73158
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "clientmodel.h"
7 #include "bantablemodel.h"
8 #include "guiconstants.h"
9 #include "guiutil.h"
10 #include "peertablemodel.h"
12 #include "chainparams.h"
13 #include "checkpoints.h"
14 #include "clientversion.h"
15 #include "validation.h"
16 #include "net.h"
17 #include "txmempool.h"
18 #include "ui_interface.h"
19 #include "util.h"
21 #include <stdint.h>
23 #include <QDebug>
24 #include <QTimer>
26 class CBlockIndex;
28 static const int64_t nClientStartupTime = GetTime();
29 static int64_t nLastHeaderTipUpdateNotification = 0;
30 static int64_t nLastBlockTipUpdateNotification = 0;
32 ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
33 QObject(parent),
34 optionsModel(_optionsModel),
35 peerTableModel(0),
36 banTableModel(0),
37 pollTimer(0)
39 peerTableModel = new PeerTableModel(this);
40 banTableModel = new BanTableModel(this);
41 pollTimer = new QTimer(this);
42 connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
43 pollTimer->start(MODEL_UPDATE_DELAY);
45 subscribeToCoreSignals();
48 ClientModel::~ClientModel()
50 unsubscribeFromCoreSignals();
53 int ClientModel::getNumConnections(unsigned int flags) const
55 CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;
57 if(flags == CONNECTIONS_IN)
58 connections = CConnman::CONNECTIONS_IN;
59 else if (flags == CONNECTIONS_OUT)
60 connections = CConnman::CONNECTIONS_OUT;
61 else if (flags == CONNECTIONS_ALL)
62 connections = CConnman::CONNECTIONS_ALL;
64 if(g_connman)
65 return g_connman->GetNodeCount(connections);
66 return 0;
69 int ClientModel::getNumBlocks() const
71 LOCK(cs_main);
72 return chainActive.Height();
75 int ClientModel::getHeaderTipHeight() const
77 LOCK(cs_main);
78 if (!pindexBestHeader)
79 return 0;
80 return pindexBestHeader->nHeight;
83 int64_t ClientModel::getHeaderTipTime() const
85 LOCK(cs_main);
86 if (!pindexBestHeader)
87 return 0;
88 return pindexBestHeader->GetBlockTime();
91 quint64 ClientModel::getTotalBytesRecv() const
93 if(!g_connman)
94 return 0;
95 return g_connman->GetTotalBytesRecv();
98 quint64 ClientModel::getTotalBytesSent() const
100 if(!g_connman)
101 return 0;
102 return g_connman->GetTotalBytesSent();
105 QDateTime ClientModel::getLastBlockDate() const
107 LOCK(cs_main);
109 if (chainActive.Tip())
110 return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
112 return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
115 long ClientModel::getMempoolSize() const
117 return mempool.size();
120 size_t ClientModel::getMempoolDynamicUsage() const
122 return mempool.DynamicMemoryUsage();
125 double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
127 CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
128 if (!tip)
130 LOCK(cs_main);
131 tip = chainActive.Tip();
133 return GuessVerificationProgress(Params().TxData(), tip);
136 void ClientModel::updateTimer()
138 // no locking required at this point
139 // the following calls will acquire the required lock
140 Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
141 Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
144 void ClientModel::updateNumConnections(int numConnections)
146 Q_EMIT numConnectionsChanged(numConnections);
149 void ClientModel::updateNetworkActive(bool networkActive)
151 Q_EMIT networkActiveChanged(networkActive);
154 void ClientModel::updateAlert()
156 Q_EMIT alertsChanged(getStatusBarWarnings());
159 bool ClientModel::inInitialBlockDownload() const
161 return IsInitialBlockDownload();
164 enum BlockSource ClientModel::getBlockSource() const
166 if (fReindex)
167 return BLOCK_SOURCE_REINDEX;
168 else if (fImporting)
169 return BLOCK_SOURCE_DISK;
170 else if (getNumConnections() > 0)
171 return BLOCK_SOURCE_NETWORK;
173 return BLOCK_SOURCE_NONE;
176 void ClientModel::setNetworkActive(bool active)
178 if (g_connman) {
179 g_connman->SetNetworkActive(active);
183 bool ClientModel::getNetworkActive() const
185 if (g_connman) {
186 return g_connman->GetNetworkActive();
188 return false;
191 QString ClientModel::getStatusBarWarnings() const
193 return QString::fromStdString(GetWarnings("gui"));
196 OptionsModel *ClientModel::getOptionsModel()
198 return optionsModel;
201 PeerTableModel *ClientModel::getPeerTableModel()
203 return peerTableModel;
206 BanTableModel *ClientModel::getBanTableModel()
208 return banTableModel;
211 QString ClientModel::formatFullVersion() const
213 return QString::fromStdString(FormatFullVersion());
216 QString ClientModel::formatSubVersion() const
218 return QString::fromStdString(strSubVersion);
221 bool ClientModel::isReleaseVersion() const
223 return CLIENT_VERSION_IS_RELEASE;
226 QString ClientModel::formatClientStartupTime() const
228 return QDateTime::fromTime_t(nClientStartupTime).toString();
231 QString ClientModel::dataDir() const
233 return GUIUtil::boostPathToQString(GetDataDir());
236 void ClientModel::updateBanlist()
238 banTableModel->refresh();
241 // Handlers for core signals
242 static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
244 // emits signal "showProgress"
245 QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
246 Q_ARG(QString, QString::fromStdString(title)),
247 Q_ARG(int, nProgress));
250 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
252 // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
253 QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
254 Q_ARG(int, newNumConnections));
257 static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
259 QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
260 Q_ARG(bool, networkActive));
263 static void NotifyAlertChanged(ClientModel *clientmodel)
265 qDebug() << "NotifyAlertChanged";
266 QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
269 static void BannedListChanged(ClientModel *clientmodel)
271 qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
272 QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
275 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
277 // lock free async UI updates in case we have a new block tip
278 // during initial sync, only update the UI if the last update
279 // was > 250ms (MODEL_UPDATE_DELAY) ago
280 int64_t now = 0;
281 if (initialSync)
282 now = GetTimeMillis();
284 int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
286 // if we are in-sync, update the UI regardless of last update time
287 if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
288 //pass a async signal to the UI thread
289 QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
290 Q_ARG(int, pIndex->nHeight),
291 Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
292 Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
293 Q_ARG(bool, fHeader));
294 nLastUpdateNotification = now;
298 void ClientModel::subscribeToCoreSignals()
300 // Connect signals to client
301 uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
302 uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
303 uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
304 uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
305 uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
306 uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
307 uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
310 void ClientModel::unsubscribeFromCoreSignals()
312 // Disconnect signals from client
313 uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
314 uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
315 uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
316 uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
317 uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
318 uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
319 uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));