Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

clientmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2019 The Dash Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <qt/clientmodel.h>
7 
8 #include <qt/bantablemodel.h>
9 #include <qt/guiconstants.h>
10 #include <qt/guiutil.h>
11 #include <qt/peertablemodel.h>
12 
13 #include <chain.h>
14 #include <chainparams.h>
15 #include <checkpoints.h>
16 #include <clientversion.h>
17 #include <validation.h>
18 #include <net.h>
19 #include <txmempool.h>
20 #include <ui_interface.h>
21 #include <util.h>
22 #include <warnings.h>
23 
26 
28 
29 #include <stdint.h>
30 
31 #include <QDebug>
32 #include <QTimer>
33 
34 class CBlockIndex;
35 
38 
39 ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
40  QObject(parent),
41  optionsModel(_optionsModel),
42  peerTableModel(0),
43  banTableModel(0),
44  pollTimer(0)
45 {
48  peerTableModel = new PeerTableModel(this);
49  banTableModel = new BanTableModel(this);
50  pollTimer = new QTimer(this);
51  connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
53 
55 }
56 
58 {
60 }
61 
62 int ClientModel::getNumConnections(unsigned int flags) const
63 {
65 
66  if(flags == CONNECTIONS_IN)
67  connections = CConnman::CONNECTIONS_IN;
68  else if (flags == CONNECTIONS_OUT)
69  connections = CConnman::CONNECTIONS_OUT;
70  else if (flags == CONNECTIONS_ALL)
71  connections = CConnman::CONNECTIONS_ALL;
72 
73  if(g_connman)
74  return g_connman->GetNodeCount(connections);
75  return 0;
76 }
77 
79 {
81  if (mnListCached.GetBlockHash() == mnList.GetBlockHash()) {
82  return;
83  }
84  mnListCached = mnList;
85  Q_EMIT masternodeListChanged();
86 }
87 
89 {
91  return mnListCached;
92 }
93 
95 {
97  setMasternodeList(deterministicMNManager->GetListAtChainTip());
98 }
99 
101 {
102  LOCK(cs_main);
103  return chainActive.Height();
104 }
105 
107 {
108  if (cachedBestHeaderHeight == -1) {
109  // make sure we initially populate the cache via a cs_main lock
110  // otherwise we need to wait for a tip update
111  LOCK(cs_main);
112  if (pindexBestHeader) {
115  }
116  }
117  return cachedBestHeaderHeight;
118 }
119 
121 {
122  if (cachedBestHeaderTime == -1) {
123  LOCK(cs_main);
124  if (pindexBestHeader) {
127  }
128  }
129  return cachedBestHeaderTime;
130 }
131 
133 {
134  if(!g_connman)
135  return 0;
136  return g_connman->GetTotalBytesRecv();
137 }
138 
140 {
141  if(!g_connman)
142  return 0;
143  return g_connman->GetTotalBytesSent();
144 }
145 
147 {
148  LOCK(cs_main);
149 
150  if (chainActive.Tip())
151  return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
152 
153  return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
154 }
155 
157 {
158  LOCK(cs_main);
159 
160  if (chainActive.Tip())
161  return QString::fromStdString(chainActive.Tip()->GetBlockHash().ToString());
162 
163  return QString::fromStdString(Params().GenesisBlock().GetHash().ToString()); // Genesis block's hash of current network
164 }
165 
167 {
168  return mempool.size();
169 }
170 
172 {
173  return mempool.DynamicMemoryUsage();
174 }
175 
177 {
179  return 0;
180  }
182 }
183 
185 {
186  CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
187  if (!tip)
188  {
189  LOCK(cs_main);
190  tip = chainActive.Tip();
191  }
192  return GuessVerificationProgress(Params().TxData(), tip);
193 }
194 
196 {
197  // no locking required at this point
198  // the following calls will acquire the required lock
201 }
202 
203 void ClientModel::updateNumConnections(int numConnections)
204 {
205  Q_EMIT numConnectionsChanged(numConnections);
206 }
207 
208 void ClientModel::updateNetworkActive(bool networkActive)
209 {
210  Q_EMIT networkActiveChanged(networkActive);
211 }
212 
214 {
216 }
217 
219 {
220  return IsInitialBlockDownload();
221 }
222 
224 {
225  if (fReindex)
226  return BLOCK_SOURCE_REINDEX;
227  else if (fImporting)
228  return BLOCK_SOURCE_DISK;
229  else if (getNumConnections() > 0)
230  return BLOCK_SOURCE_NETWORK;
231 
232  return BLOCK_SOURCE_NONE;
233 }
234 
236 {
237  if (g_connman) {
238  g_connman->SetNetworkActive(active);
239  }
240 }
241 
243 {
244  if (g_connman) {
245  return g_connman->GetNetworkActive();
246  }
247  return false;
248 }
249 
251 {
252  return QString::fromStdString(GetWarnings("gui"));
253 }
254 
256 {
257  return optionsModel;
258 }
259 
261 {
262  return peerTableModel;
263 }
264 
266 {
267  return banTableModel;
268 }
269 
271 {
272  return QString::fromStdString(FormatFullVersion());
273 }
274 
276 {
277  return QString::fromStdString(strSubVersion);
278 }
279 
281 {
282  return CLIENT_VERSION_IS_RELEASE;
283 }
284 
286 {
287  return QDateTime::fromTime_t(GetStartupTime()).toString();
288 }
289 
290 QString ClientModel::dataDir() const
291 {
293 }
294 
296 {
298 }
299 
300 // Handlers for core signals
301 static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
302 {
303  // emits signal "showProgress"
304  QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
305  Q_ARG(QString, QString::fromStdString(title)),
306  Q_ARG(int, nProgress));
307 }
308 
309 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
310 {
311  // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
312  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
313  Q_ARG(int, newNumConnections));
314 }
315 
316 static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
317 {
318  QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
319  Q_ARG(bool, networkActive));
320 }
321 
322 static void NotifyAlertChanged(ClientModel *clientmodel)
323 {
324  qDebug() << "NotifyAlertChanged";
325  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
326 }
327 
328 static void BannedListChanged(ClientModel *clientmodel)
329 {
330  qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
331  QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
332 }
333 
334 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
335 {
336  // lock free async UI updates in case we have a new block tip
337  // during initial sync, only update the UI if the last update
338  // was > 250ms (MODEL_UPDATE_DELAY) ago
339  int64_t now = 0;
340  if (initialSync)
341  now = GetTimeMillis();
342 
343  int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
344 
345  if (fHeader) {
346  // cache best headers time and height to reduce future cs_main locks
347  clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
348  clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
349  }
350  // if we are in-sync, update the UI regardless of last update time
351  if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
352  //pass an async signal to the UI thread
353  QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
354  Q_ARG(int, pIndex->nHeight),
355  Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
356  Q_ARG(QString, QString::fromStdString(pIndex->GetBlockHash().ToString())),
357  Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
358  Q_ARG(bool, fHeader));
359  nLastUpdateNotification = now;
360  }
361 }
362 
363 static void NotifyMasternodeListChanged(ClientModel *clientmodel, const CDeterministicMNList& newList)
364 {
365  clientmodel->setMasternodeList(newList);
366 }
367 
368 static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress)
369 {
370  QMetaObject::invokeMethod(clientmodel, "additionalDataSyncProgressChanged", Qt::QueuedConnection,
371  Q_ARG(double, nSyncProgress));
372 }
373 
375 {
376  // Connect signals to client
377  uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
379  uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
380  uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
381  uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
382  uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
383  uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
386 }
387 
389 {
390  // Disconnect signals from client
391  uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
392  uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
393  uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
394  uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
395  uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
396  uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
397  uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
398  uiInterface.NotifyMasternodeListChanged.disconnect(boost::bind(NotifyMasternodeListChanged, this, _1));
400 }
QString formatClientStartupTime() const
CTxMemPool mempool
PeerTableModel * peerTableModel
Definition: clientmodel.h:100
std::string ToString() const
Definition: chain.h:323
void updateNetworkActive(bool networkActive)
bool inInitialBlockDownload() const
Return true if core is doing initial block download.
QString formatSubVersion() const
static void NotifyAlertChanged(ClientModel *clientmodel)
long getMempoolSize() const
Return number of transactions in the mempool.
bool getNetworkActive() const
Return true if network activity in core is enabled.
bool isReleaseVersion() const
int64_t GetBlockTime() const
Definition: chain.h:297
std::atomic< int64_t > cachedBestHeaderTime
Definition: clientmodel.h:96
void updateBanlist()
void setMasternodeList(const CDeterministicMNList &mnList)
Definition: clientmodel.cpp:78
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:1389
int64_t GetStartupTime()
Definition: util.cpp:1429
boost::signals2::signal< void(bool networkActive)> NotifyNetworkActiveChanged
Network activity state changed.
Definition: ui_interface.h:88
int Height() const
Return the maximal height in the chain.
Definition: chain.h:484
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
CCriticalSection cs_main
Definition: validation.cpp:213
void networkActiveChanged(bool networkActive)
BanTableModel * banTableModel
Definition: clientmodel.h:101
int flags
Definition: dash-tx.cpp:462
OptionsModel * getOptionsModel()
size_t getInstantSentLockCount() const
Return number of ISLOCKs.
quint64 getTotalBytesSent() const
std::atomic< int > cachedBestHeaderHeight
Definition: clientmodel.h:95
PeerTableModel * getPeerTableModel()
std::string GetWarnings(const std::string &strFor)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:41
void masternodeListChanged() const
static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress)
void numConnectionsChanged(int count)
boost::signals2::signal< void(double nSyncProgress)> NotifyAdditionalDataSyncProgressChanged
Additional data sync progress changed.
Definition: ui_interface.h:114
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
void alertsChanged(const QString &warnings)
CInstantSendManager * quorumInstantSendManager
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
Definition: ui_interface.h:117
uint256 GetBlockHash() const
Definition: chain.h:292
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyBlockTip
New block has been accepted.
Definition: ui_interface.h:105
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyHeaderTip
Best header has changed.
Definition: ui_interface.h:108
static int64_t nLastHeaderTipUpdateNotification
Definition: clientmodel.cpp:36
const uint256 & GetBlockHash() const
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:62
double getVerificationProgress(const CBlockIndex *tip) const
unsigned long size()
Definition: txmempool.h:660
enum BlockSource getBlockSource() const
Returns enum BlockSource of the current importing/syncing state.
CBlockIndex * pindexBestHeader
Best header we&#39;ve seen so far (used for getheaders queries&#39; starting points).
Definition: validation.cpp:218
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
#define LOCK(cs)
Definition: sync.h:178
quint64 getTotalBytesRecv() const
BlockSource
Definition: clientmodel.h:27
QString getLastBlockHash() const
void unsubscribeFromCoreSignals()
boost::signals2::signal< void(const CDeterministicMNList &)> NotifyMasternodeListChanged
Masternode list has changed.
Definition: ui_interface.h:111
BanTableModel * getBanTableModel()
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
void subscribeToCoreSignals()
NumConnections
Definition: net.h:141
std::atomic_bool fImporting
CDeterministicMNList mnListCached
Definition: clientmodel.h:109
std::string ToString() const
Definition: uint256.cpp:62
CDeterministicMNList getMasternodeList() const
Definition: clientmodel.cpp:88
void islockCountChanged(size_t count)
void refreshMasternodeList()
Definition: clientmodel.cpp:94
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:118
CCriticalSection cs_mnlinst
Definition: clientmodel.h:108
Model for Dash network client.
Definition: clientmodel.h:42
QTimer * pollTimer
Definition: clientmodel.h:103
static void NotifyMasternodeListChanged(ClientModel *clientmodel, const CDeterministicMNList &newList)
size_t getMempoolDynamicUsage() const
Return the dynamic memory usage of the mempool.
std::string FormatFullVersion()
static const int MODEL_UPDATE_DELAY
Definition: guiconstants.h:10
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: ui_interface.h:85
QDateTime getLastBlockDate() const
static void BannedListChanged(ClientModel *clientmodel)
std::atomic_bool fReindex
void updateAlert()
ClientModel(OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:39
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:25
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
const CChainParams & Params()
Return the currently selected parameters.
boost::signals2::signal< void()> NotifyAlertChanged
Status bar alerts changed.
Definition: ui_interface.h:93
void updateTimer()
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: utiltime.cpp:56
static int64_t nLastBlockTipUpdateNotification
Definition: clientmodel.cpp:37
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index.
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
Definition: bantablemodel.h:39
static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:453
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
OptionsModel * optionsModel
Definition: clientmodel.h:99
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes)
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:928
void setNetworkActive(bool active)
Toggle network activity state in core.
QString dataDir() const
CClientUIInterface uiInterface
Definition: ui_interface.cpp:8
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:183
int getNumBlocks() const
void updateNumConnections(int numConnections)
int getHeaderTipHeight() const
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:217
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:1828
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
boost::signals2::signal< void(const std::string &title, int nProgress, bool resume_possible)> ShowProgress
Show progress e.g.
Definition: ui_interface.h:102
int64_t getHeaderTipTime() const
QString formatFullVersion() const
Released under the MIT license