PIVX Core  5.6.99
P2P Digital Currency
clientmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2014 The Bitcoin developers
2 // Copyright (c) 2014-2015 The Dash developers
3 // Copyright (c) 2015-2022 The PIVX Core developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "clientmodel.h"
8 
9 #include "bantablemodel.h"
10 #include "guiconstants.h"
11 #include "guiutil.h"
12 #include "peertablemodel.h"
13 
14 #include "chainparams.h"
15 #include "checkpoints.h"
16 #include "clientversion.h"
17 #include "interfaces/handler.h"
18 #include "mapport.h"
19 #include "masternodeman.h"
20 #include "net.h"
21 #include "netbase.h"
22 #include "guiinterface.h"
23 #include "util/system.h"
24 #include "validation.h"
25 #include "warnings.h"
26 
27 #include <stdint.h>
28 
29 #include <QDebug>
30 #include <QTimer>
31 
32 static const int64_t nClientStartupTime = GetTime();
33 // Last tip update notification
34 static int64_t nLastBlockTipUpdateNotification = 0;
35 
36 ClientModel::ClientModel(OptionsModel* optionsModel, QObject* parent) : QObject(parent),
37  optionsModel(optionsModel),
38  peerTableModel(0),
39  banTableModel(0),
40  cacheTip(nullptr),
41  cachedMasternodeCountString(""),
42  cachedReindexing(0), cachedImporting(0),
43  numBlocksAtStartup(-1), pollTimer(0)
44 {
45  peerTableModel = new PeerTableModel(this);
46  banTableModel = new BanTableModel(this);
47  pollTimer = new QTimer(this);
48  connect(pollTimer, &QTimer::timeout, this, &ClientModel::updateTimer);
49  pollTimer->start(MODEL_UPDATE_DELAY);
50 
51  pollMnTimer = new QTimer(this);
52  connect(pollMnTimer, &QTimer::timeout, this, &ClientModel::updateMnTimer);
54 
56 }
57 
59 {
61 }
62 
63 int ClientModel::getNumConnections(unsigned int flags) const
64 {
66 
67  if(flags == CONNECTIONS_IN)
68  connections = CConnman::CONNECTIONS_IN;
69  else if (flags == CONNECTIONS_OUT)
70  connections = CConnman::CONNECTIONS_OUT;
71  else if (flags == CONNECTIONS_ALL)
72  connections = CConnman::CONNECTIONS_ALL;
73 
74  if (g_connman)
75  return g_connman->GetNodeCount(connections);
76  return 0;
77 }
78 
80 {
81  const auto& info = mnodeman.getMNsInfo();
82  int unknown = std::max(0, info.total - info.ipv4 - info.ipv6 - info.onion);
83  m_cached_masternodes_count = info.total;
84  return tr("Total: %1 (IPv4: %2 / IPv6: %3 / Tor: %4 / Unknown: %5)").arg(QString::number(info.total))
85  .arg(QString::number(info.ipv4))
86  .arg(QString::number(info.ipv6))
87  .arg(QString::number(info.onion))
88  .arg(QString::number(unknown));
89 }
90 
92 {
93  if (!cachedMasternodeCountString.isEmpty()) {
95  }
96 
97  // Force an update
100 }
101 
103 {
104  if (!cacheTip) {
105  cacheTip = WITH_LOCK(cs_main, return chainActive.Tip(););
106  }
107 
108  return cacheTip ? cacheTip->nHeight : 0;
109 }
110 
112 {
114  return numBlocksAtStartup;
115 }
116 
118 {
119  if(!g_connman)
120  return 0;
121  return g_connman->GetTotalBytesRecv();
122 }
123 
125 {
126  if(!g_connman)
127  return 0;
128  return g_connman->GetTotalBytesSent();
129 }
130 
132 {
133  const int nTime = (cacheTip == nullptr ? Params().GenesisBlock().GetBlockTime() : cacheTip->GetBlockTime());
134  return QDateTime::fromTime_t(nTime);
135 }
136 
138 {
139  const uint256& nHash = (cacheTip == nullptr ? Params().GenesisBlock().GetHash() : cacheTip->GetBlockHash());
140  return QString::fromStdString(nHash.GetHex());
141 }
142 
144 {
145  return cacheTip == nullptr ? Params().GenesisBlock().GetHash() : cacheTip->GetBlockHash();
146 }
147 
149 {
150  return cacheTip == nullptr ? 0 : cacheTip->nHeight;
151 }
152 
154 {
155  return cacheTip == nullptr ? Params().GenesisBlock().GetBlockTime() : cacheTip->GetBlockTime();
156 }
157 
159 {
160  return cacheTip;
161 }
162 
164 {
166 }
167 
169 {
170  // Get required lock upfront. This avoids the GUI from getting stuck on
171  // periodical polls if the core is holding the locks for a longer time -
172  // for example, during a wallet rescan.
174 }
175 
177 {
178  // Following method is locking the mnmanager mutex for now,
179  // future: move to an event based update.
180  QString newMasternodeCountString = getMasternodeCountString();
181 
182  if (cachedMasternodeCountString != newMasternodeCountString) {
183  cachedMasternodeCountString = newMasternodeCountString;
184 
186  }
187 }
188 
190 {
191  if (!pollMnTimer->isActive()) {
192  // no need to update as frequent as data for balances/txes/blocks
193  pollMnTimer->start(MODEL_UPDATE_DELAY * 40);
194  }
195 }
196 
198 {
199  if (pollMnTimer->isActive()) {
200  pollMnTimer->stop();
201  }
202 }
203 
204 void ClientModel::updateNumConnections(int numConnections)
205 {
206  Q_EMIT numConnectionsChanged(numConnections);
207 }
208 
209 void ClientModel::updateNetworkActive(bool networkActive)
210 {
211  Q_EMIT networkActiveChanged(networkActive);
212 }
213 
215 {
217 }
218 
220 {
221  return cachedInitialSync;
222 }
223 
225 {
226  if (fReindex)
227  return BLOCK_SOURCE_REINDEX;
228  else if (fImporting)
229  return BLOCK_SOURCE_DISK;
230  else if (getNumConnections() > 0)
231  return BLOCK_SOURCE_NETWORK;
232 
233  return BLOCK_SOURCE_NONE;
234 }
235 
237 {
238  if (g_connman) {
239  g_connman->SetNetworkActive(active);
240  }
241 }
242 
244 {
245  if (g_connman) {
246  return g_connman->GetNetworkActive();
247  }
248  return false;
249 }
250 
252 {
253  return QString::fromStdString(GetWarnings("statusbar"));
254 }
255 
257 {
258  return optionsModel;
259 }
260 
262 {
263  return peerTableModel;
264 }
265 
267 {
268  return banTableModel;
269 }
270 
272 {
273  return QString::fromStdString(FormatFullVersion());
274 }
275 
277 {
279 }
280 
281 QString ClientModel::clientName() const
282 {
283  return QString::fromStdString(CLIENT_NAME);
284 }
285 
287 {
288  return QDateTime::fromTime_t(nClientStartupTime).toString();
289 }
290 
291 QString ClientModel::dataDir() const
292 {
294 }
295 
297 {
299 }
300 
301 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
302 {
303  // lock free async UI updates in case we have a new block tip
304  // during initial sync, only update the UI if the last update
305  // was > 1000ms (MODEL_UPDATE_DELAY) ago
306  int64_t now = 0;
307  if (initialSync)
308  now = GetTimeMillis();
309 
310  // if we are in-sync, update the UI regardless of last update time
311  if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) {
312  //pass a async signal to the UI thread
313  clientmodel->setCacheTip(pIndex);
314  clientmodel->setCacheImporting(fImporting);
315  clientmodel->setCacheReindexing(fReindex);
316  clientmodel->setCacheInitialSync(initialSync);
317  Q_EMIT clientmodel->numBlocksChanged(pIndex->nHeight);
318  nLastBlockTipUpdateNotification = now;
319  }
320 }
321 
322 // Handlers for core signals
323 static void ShowProgress(ClientModel* clientmodel, const std::string& title, int nProgress)
324 {
325  // emits signal "showProgress"
326  QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
327  Q_ARG(QString, QString::fromStdString(title)),
328  Q_ARG(int, nProgress));
329 }
330 
331 static void NotifyNumConnectionsChanged(ClientModel* clientmodel, int newNumConnections)
332 {
333  // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
334  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
335  Q_ARG(int, newNumConnections));
336 }
337 
338 static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
339 {
340  QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
341  Q_ARG(bool, networkActive));
342 }
343 
344 static void NotifyAlertChanged(ClientModel* clientmodel)
345 {
346  qDebug() << "NotifyAlertChanged";
347  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
348 }
349 
350 static void BannedListChanged(ClientModel *clientmodel)
351 {
352  qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
353  QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
354 }
355 
357 {
358  // Connect signals to client
359  m_handler_show_progress = interfaces::MakeHandler(uiInterface.ShowProgress.connect(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2)));
360  m_handler_notify_num_connections_changed = interfaces::MakeHandler(uiInterface.NotifyNumConnectionsChanged.connect(std::bind(NotifyNumConnectionsChanged, this, std::placeholders::_1)));
361  m_handler_notify_net_activity_changed = interfaces::MakeHandler(uiInterface.NotifyNetworkActiveChanged.connect(std::bind(NotifyNetworkActiveChanged, this, std::placeholders::_1)));
362  m_handler_notify_alert_changed = interfaces::MakeHandler(uiInterface.NotifyAlertChanged.connect(std::bind(NotifyAlertChanged, this)));
363  m_handler_banned_list_changed = interfaces::MakeHandler(uiInterface.BannedListChanged.connect(std::bind(BannedListChanged, this)));
364  m_handler_notify_block_tip = interfaces::MakeHandler(uiInterface.NotifyBlockTip.connect(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2)));
365 }
366 
368 {
369  // Disconnect signals from client
370  m_handler_show_progress->disconnect();
373  m_handler_notify_alert_changed->disconnect();
374  m_handler_banned_list_changed->disconnect();
375  m_handler_notify_block_tip->disconnect();
376 }
377 
378 void ClientModel::mapPort(bool use_upnp, bool use_natpmp) {
379  StartMapPort(use_upnp, use_natpmp);
380 }
381 
382 bool ClientModel::getTorInfo(std::string& ip_port) const
383 {
384  proxyType onion;
385  if (GetProxy((Network) 3, onion) && IsReachable((Network) 3)) {
386  {
388  for (const std::pair<const CNetAddr, LocalServiceInfo>& item : mapLocalHost) {
389  if (item.first.IsTor()) {
390  CService addrOnion(LookupNumeric(item.first.ToString(), item.second.nPort));
391  ip_port = addrOnion.ToStringIPPort();
392  return true;
393  }
394  }
395  }
396  }
397  return false;
398 }
const CChainParams & Params()
Return the currently selected parameters.
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call.
Definition: bantablemodel.h:39
int64_t GetBlockTime() const
Definition: block.h:72
uint256 GetHash() const
Definition: block.cpp:15
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
uint256 GetBlockHash() const
Definition: chain.h:215
int64_t GetBlockTime() const
Definition: chain.h:216
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:151
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
const CBlock & GenesisBlock() const
Definition: chainparams.h:76
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: guiinterface.h:102
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: guiinterface.h:90
boost::signals2::signal< void()> NotifyAlertChanged
New, updated or cancelled alert.
Definition: guiinterface.h:96
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
Definition: guiinterface.h:108
boost::signals2::signal< void(bool fInitialDownload, const CBlockIndex *newTip)> NotifyBlockTip
New block has been accepted.
Definition: guiinterface.h:105
boost::signals2::signal< void(bool networkActive)> NotifyNetworkActiveChanged
Network activity state changed.
Definition: guiinterface.h:93
NumConnections
Definition: net.h:148
@ CONNECTIONS_IN
Definition: net.h:150
@ CONNECTIONS_NONE
Definition: net.h:149
@ CONNECTIONS_ALL
Definition: net.h:152
@ CONNECTIONS_OUT
Definition: net.h:151
CMasternodeMan::MNsInfo getMNsInfo() const
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:484
std::string ToStringIPPort() const
Definition: netaddress.cpp:945
Model for PIVX network client.
Definition: clientmodel.h:50
void updateAlert()
std::unique_ptr< interfaces::Handler > m_handler_banned_list_changed
Definition: clientmodel.h:119
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
QString getLastBlockHash() const
void updateBanlist()
void setNetworkActive(bool active)
Toggle network activity state in core.
QString cachedMasternodeCountString
Definition: clientmodel.h:128
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
void setCacheReindexing(bool reindex)
Definition: clientmodel.h:96
int numBlocksAtStartup
Definition: clientmodel.h:133
bool getTorInfo(std::string &ip_port) const
void updateMnTimer()
std::unique_ptr< interfaces::Handler > m_handler_show_progress
Definition: clientmodel.h:115
QString clientName() const
int64_t getLastBlockProcessedTime() const
void setCacheTip(const CBlockIndex *const tip)
Definition: clientmodel.h:95
uint256 getLastBlockProcessed() const
quint64 getTotalBytesRecv() const
std::unique_ptr< interfaces::Handler > m_handler_notify_alert_changed
Definition: clientmodel.h:118
quint64 getTotalBytesSent() const
void startMasternodesTimer()
PeerTableModel * getPeerTableModel()
void numBlocksChanged(int count)
void updateNetworkActive(bool networkActive)
int getNumBlocksAtStartup()
double getVerificationProgress() const
void setCacheImporting(bool import)
Definition: clientmodel.h:97
void updateNumConnections(int numConnections)
void stopMasternodesTimer()
void updateTimer()
QDateTime getLastBlockDate() const
void strMasternodesChanged(const QString &strMasternodes)
void numConnectionsChanged(int count)
int getNumBlocks()
bool isTipCached() const
QString getMasternodeCountString()
Definition: clientmodel.cpp:79
QTimer * pollMnTimer
Definition: clientmodel.h:136
std::unique_ptr< interfaces::Handler > m_handler_notify_block_tip
Definition: clientmodel.h:120
bool getNetworkActive() const
Return true if network activity in core is enabled.
QString formatClientStartupTime() const
QString getMasternodesCountString()
Definition: clientmodel.cpp:91
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:63
enum BlockSource getBlockSource() const
Return true if core is importing blocks.
static void mapPort(bool use_upnp, bool use_natpmp)
Set the automatic port mapping options.
void setCacheInitialSync(bool _initialSync)
Definition: clientmodel.h:98
std::atomic< bool > cachedInitialSync
Definition: clientmodel.h:131
std::unique_ptr< interfaces::Handler > m_handler_notify_num_connections_changed
Definition: clientmodel.h:116
OptionsModel * optionsModel
Definition: clientmodel.h:123
BanTableModel * banTableModel
Definition: clientmodel.h:125
BanTableModel * getBanTableModel()
void unsubscribeFromCoreSignals()
QTimer * pollTimer
Definition: clientmodel.h:135
std::unique_ptr< interfaces::Handler > m_handler_notify_net_activity_changed
Definition: clientmodel.h:117
void alertsChanged(const QString &warnings)
QString dataDir() const
OptionsModel * getOptionsModel()
QString formatFullVersion() const
std::atomic_int m_cached_masternodes_count
Definition: clientmodel.h:138
PeerTableModel * peerTableModel
Definition: clientmodel.h:124
int getLastBlockProcessedHeight() const
ClientModel(OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:36
const CBlockIndex * cacheTip
Definition: clientmodel.h:127
bool isReleaseVersion() const
bool inInitialBlockDownload() const
Return true if core is doing initial block download.
void subscribeToCoreSignals()
void networkActiveChanged(bool networkActive)
Interface from Qt to configuration data structure for PIVX client.
Definition: optionsmodel.h:22
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call.
std::string GetHex() const
Definition: uint256.cpp:21
256-bit opaque blob.
Definition: uint256.h:138
@ CONNECTIONS_IN
Definition: clientmodel.h:43
@ CONNECTIONS_OUT
Definition: clientmodel.h:44
@ CONNECTIONS_ALL
Definition: clientmodel.h:45
BlockSource
Definition: clientmodel.h:34
@ BLOCK_SOURCE_NETWORK
Definition: clientmodel.h:38
@ BLOCK_SOURCE_DISK
Definition: clientmodel.h:37
@ BLOCK_SOURCE_NONE
Definition: clientmodel.h:35
@ BLOCK_SOURCE_REINDEX
Definition: clientmodel.h:36
std::string FormatFullVersion()
const std::string CLIENT_NAME
CClientUIInterface uiInterface
Definition: init.cpp:109
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:90
@ LOCK
Definition: lockunlock.h:16
void StartMapPort(bool use_upnp, bool use_natpmp)
Definition: mapport.cpp:327
CMasternodeMan mnodeman
Masternode manager.
double GuessVerificationProgress(const CBlockIndex *pindex, bool fSigchecks)
Guess how far we are in the verification process at the given block index.
Definition: checkpoints.cpp:43
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:681
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
Definition: handler.cpp:26
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
Definition: net.cpp:92
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:91
bool IsReachable(enum Network net)
Definition: net.cpp:253
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
Network
A network type.
Definition: netaddress.h:44
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:605
CService LookupNumeric(const std::string &name, int portDefault)
Definition: netbase.cpp:209
#define CLIENT_VERSION_IS_RELEASE
Definition: pivx-config.h:15
int flags
Definition: pivx-tx.cpp:400
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:724
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: utiltime.cpp:61
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
Definition: utiltime.cpp:27
std::atomic< bool > fImporting
Definition: validation.cpp:94
std::atomic< bool > fReindex
Definition: validation.cpp:95
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:84
std::string GetWarnings(const std::string &strFor)
Definition: warnings.cpp:47