PRCYCoin  2.0.0.7rc1
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-2018 The PIVX developers
4 // Copyright (c) 2018-2020 The DAPS Project developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #include "clientmodel.h"
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 "main.h"
18 #include "masternode-sync.h"
19 #include "masternodeman.h"
20 #include "net.h"
21 #include "netbase.h"
22 #include "guiinterface.h"
23 #include "util.h"
24 
25 #include <stdint.h>
26 
27 #include <QDateTime>
28 #include <QDebug>
29 #include <QTimer>
30 
31 static const int64_t nClientStartupTime = GetTime();
32 // Last tip update notification
33 static int64_t nLastBlockTipUpdateNotification = 0;
34 
35 ClientModel::ClientModel(OptionsModel* optionsModel, QObject* parent) : QObject(parent),
36  optionsModel(optionsModel),
37  peerTableModel(0),
38  banTableModel(0),
39  cacheTip(nullptr),
40  cachedMasternodeCountString(""),
41  cachedReindexing(0), cachedImporting(0),
42  numBlocksAtStartup(-1), pollTimer(0)
43 {
44  peerTableModel = new PeerTableModel(this);
45  banTableModel = new BanTableModel(this);
46  pollTimer = new QTimer(this);
47  connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
48  pollTimer->start(MODEL_UPDATE_DELAY);
49 
50  pollMnTimer = new QTimer(this);
51  connect(pollMnTimer, SIGNAL(timeout()), this, SLOT(updateMnTimer()));
52 
54 }
55 
57 {
59 }
60 
61 int ClientModel::getNumConnections(unsigned int flags) const
62 {
63  LOCK(cs_vNodes);
64  if (flags == CONNECTIONS_ALL) // Shortcut if we want total
65  return vNodes.size();
66 
67  int nNum = 0;
68  for (CNode* pnode : vNodes)
69  if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
70  nNum++;
71 
72  return nNum;
73 }
74 
76 {
77  int ipv4 = 0, ipv6 = 0, onion = 0;
78  mnodeman.CountNetworks(ActiveProtocol(), ipv4, ipv6, onion);
79  int nUnknown = mnodeman.size() - ipv4 - ipv6 - onion;
80  if(nUnknown < 0) nUnknown = 0;
81  return tr("Total: %1 (IPv4: %2 / IPv6: %3 / Tor: %4 / Unknown: %5)").arg(QString::number((int)mnodeman.size())).arg(QString::number((int)ipv4)).arg(QString::number((int)ipv6)).arg(QString::number((int)onion)).arg(QString::number((int)nUnknown));
82 }
83 
85 {
86  if (!cacheTip) {
88  }
89 
90  return cacheTip ? cacheTip->nHeight : 0;
91 }
92 
94 {
96  return numBlocksAtStartup;
97 }
98 
100 {
101  return CNode::GetTotalBytesRecv();
102 }
103 
105 {
106  return CNode::GetTotalBytesSent();
107 }
108 
110 {
111  const int nTime = (cacheTip == nullptr ? Params().GenesisBlock().GetBlockTime() : cacheTip->GetBlockTime());
112  return QDateTime::fromTime_t(nTime);
113 }
114 
116 {
117  const uint256& nHash = (cacheTip == nullptr ? Params().GenesisBlock().GetHash() : cacheTip->GetBlockHash());
118  return QString::fromStdString(nHash.GetHex());
119 }
120 
122 {
124 }
125 
127 {
128  // Get required lock upfront. This avoids the GUI from getting stuck on
129  // periodical polls if the core is holding the locks for a longer time -
130  // for example, during a wallet rescan.
132 }
133 
135 {
136  // Get required lock upfront. This avoids the GUI from getting stuck on
137  // periodical polls if the core is holding the locks for a longer time -
138  // for example, during a wallet rescan.
139  TRY_LOCK(cs_main, lockMain);
140  if (!lockMain)
141  return;
142  QString newMasternodeCountString = getMasternodeCountString();
143 
144  if (cachedMasternodeCountString != newMasternodeCountString) {
145  cachedMasternodeCountString = newMasternodeCountString;
146 
148  }
149 }
150 
152 {
153  if (!pollMnTimer->isActive()) {
154  // no need to update as frequent as data for balances/txes/blocks
155  pollMnTimer->start(MODEL_UPDATE_DELAY * 40);
156  }
157 }
158 
160 {
161  if (pollMnTimer->isActive()) {
162  pollMnTimer->stop();
163  }
164 }
165 
166 void ClientModel::updateNumConnections(int numConnections)
167 {
168  Q_EMIT numConnectionsChanged(numConnections);
169 }
170 
172 {
174 }
175 
177 {
178  return cachedInitialSync;
179 }
180 
182 {
183  if (fReindex)
184  return BLOCK_SOURCE_REINDEX;
185  else if (fImporting)
186  return BLOCK_SOURCE_DISK;
187  else if (getNumConnections() > 0)
188  return BLOCK_SOURCE_NETWORK;
189 
190  return BLOCK_SOURCE_NONE;
191 }
192 
194 {
195  return QString::fromStdString(GetWarnings("statusbar"));
196 }
197 
199 {
200  return optionsModel;
201 }
202 
204 {
205  return peerTableModel;
206 }
207 
209 {
210  return banTableModel;
211 }
212 
214 {
215  return QString::fromStdString(FormatFullVersion());
216 }
217 
219 {
221 }
222 
223 QString ClientModel::clientName() const
224 {
225  return QString::fromStdString(CLIENT_NAME);
226 }
227 
229 {
230  return QDateTime::fromTime_t(nClientStartupTime).toString();
231 }
232 
233 QString ClientModel::dataDir() const
234 {
236 }
237 
239 {
241 }
242 
243 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
244 {
245  // lock free async UI updates in case we have a new block tip
246  // during initial sync, only update the UI if the last update
247  // was > 1000ms (MODEL_UPDATE_DELAY) ago
248  int64_t now = 0;
249  if (initialSync)
250  now = GetTimeMillis();
251 
252  // if we are in-sync, update the UI regardless of last update time
253  if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) {
254  //pass a async signal to the UI thread
255  clientmodel->setCacheTip(pIndex);
256  clientmodel->setCacheImporting(fImporting);
257  clientmodel->setCacheReindexing(fReindex);
258  clientmodel->setCacheInitialSync(initialSync);
259  Q_EMIT clientmodel->numBlocksChanged(pIndex->nHeight);
260  nLastBlockTipUpdateNotification = now;
261  }
262 }
263 
264 // Handlers for core signals
265 static void ShowProgress(ClientModel* clientmodel, const std::string& title, int nProgress)
266 {
267  // emits signal "showProgress"
268  QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
269  Q_ARG(QString, QString::fromStdString(title)),
270  Q_ARG(int, nProgress));
271 }
272 
273 static void NotifyNumConnectionsChanged(ClientModel* clientmodel, int newNumConnections)
274 {
275  // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
276  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
277  Q_ARG(int, newNumConnections));
278 }
279 
280 static void NotifyAlertChanged(ClientModel* clientmodel)
281 {
282  qDebug() << "NotifyAlertChanged";
283  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
284 }
285 
286 static void BannedListChanged(ClientModel *clientmodel)
287 {
288  qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
289  QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
290 }
291 
293 {
294  // Connect signals to client
295  uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
296  uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
297  uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
298  uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
299  uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2));
300 }
301 
303 {
304  // Disconnect signals from client
305  uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
306  uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
307  uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
308  uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
309  uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2));
310 }
311 
312 bool ClientModel::getTorInfo(std::string& ip_port) const
313 {
314  proxyType onion;
315  if (GetProxy((Network) 3, onion) && IsReachable((Network) 3)) {
316  {
318  for (const std::pair<CNetAddr, LocalServiceInfo> &item : mapLocalHost) {
319  if (item.first.IsTor()) {
320  CService addrOnion(LookupNumeric(item.first.ToString().c_str(), item.second.nPort));
321  ip_port = addrOnion.ToStringIPPort();
322  return true;
323  }
324  }
325  }
326  }
327  return false;
328 }
ClientModel::alertsChanged
void alertsChanged(const QString &warnings)
CBlockIndex::GetBlockTime
int64_t GetBlockTime() const
Definition: chain.h:364
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:133
fImporting
std::atomic< bool > fImporting
Definition: main.cpp:80
ClientModel::startMasternodesTimer
void startMasternodesTimer()
Definition: clientmodel.cpp:151
ClientModel::subscribeToCoreSignals
void subscribeToCoreSignals()
Definition: clientmodel.cpp:292
vNodes
std::vector< CNode * > vNodes
Definition: net.cpp:85
CONNECTIONS_IN
@ CONNECTIONS_IN
Definition: clientmodel.h:38
GUIUtil::boostPathToQString
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:799
ClientModel::getLastBlockHash
QString getLastBlockHash() const
Definition: clientmodel.cpp:115
ClientModel::numConnectionsChanged
void numConnectionsChanged(int count)
BLOCK_SOURCE_NONE
@ BLOCK_SOURCE_NONE
Definition: clientmodel.h:30
CONNECTIONS_OUT
@ CONNECTIONS_OUT
Definition: clientmodel.h:39
GetTime
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:19
ClientModel::inInitialBlockDownload
bool inInitialBlockDownload() const
Return true if core is doing initial block download.
Definition: clientmodel.cpp:176
ClientModel::getNumConnections
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:61
base_uint::GetHex
std::string GetHex() const
Definition: arith_uint256.cpp:155
ClientModel::isReleaseVersion
bool isReleaseVersion() const
Definition: clientmodel.cpp:218
chainActive
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:70
ClientModel::numBlocksAtStartup
int numBlocksAtStartup
Definition: clientmodel.h:105
uiInterface
CClientUIInterface uiInterface
Definition: init.cpp:101
CNode::GetTotalBytesRecv
static uint64_t GetTotalBytesRecv()
Definition: net.cpp:2097
ClientModel::getTorInfo
bool getTorInfo(std::string &ip_port) const
Definition: clientmodel.cpp:312
ClientModel::ClientModel
ClientModel(OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:35
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:181
CNode
Information about a peer.
Definition: net.h:306
ClientModel::getBlockSource
enum BlockSource getBlockSource() const
Return true if core is importing blocks.
Definition: clientmodel.cpp:181
flags
int flags
Definition: prcycoin-tx.cpp:297
ClientModel::updateTimer
void updateTimer()
Definition: clientmodel.cpp:126
CClientUIInterface::BannedListChanged
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
Definition: guiinterface.h:110
masternode-sync.h
WITH_LOCK
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:209
CMasternodeMan::size
int size()
Return the number of (unique) Masternodes.
Definition: masternodeman.h:148
clientversion.h
cs_vNodes
RecursiveMutex cs_vNodes
Definition: net.cpp:86
TRY_LOCK
#define TRY_LOCK(cs, name)
Definition: sync.h:186
CONNECTIONS_ALL
@ CONNECTIONS_ALL
Definition: clientmodel.h:40
ClientModel::setCacheImporting
void setCacheImporting(bool import)
Definition: clientmodel.h:91
chainparams.h
guiinterface.h
ClientModel::cacheTip
const CBlockIndex * cacheTip
Definition: clientmodel.h:99
ClientModel::getStatusBarWarnings
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
Definition: clientmodel.cpp:193
masternodeman.h
Network
Network
Definition: netaddress.h:19
BanTableModel
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call.
Definition: bantablemodel.h:39
ClientModel::banTableModel
BanTableModel * banTableModel
Definition: clientmodel.h:97
ClientModel::updateMnTimer
void updateMnTimer()
Definition: clientmodel.cpp:134
proxyType
Definition: netbase.h:28
CService::ToStringIPPort
std::string ToStringIPPort() const
Definition: netaddress.cpp:559
CBlockHeader::GetHash
uint256 GetHash() const
Definition: block.cpp:80
ClientModel::getNumBlocksAtStartup
int getNumBlocksAtStartup()
Definition: clientmodel.cpp:93
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
ActiveProtocol
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
Definition: main.cpp:6844
OptionsModel
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:18
ClientModel::getOptionsModel
OptionsModel * getOptionsModel()
Definition: clientmodel.cpp:198
ClientModel::unsubscribeFromCoreSignals
void unsubscribeFromCoreSignals()
Definition: clientmodel.cpp:302
mnodeman
CMasternodeMan mnodeman
Masternode manager.
Definition: masternodeman.cpp:22
ClientModel::cachedInitialSync
bool cachedInitialSync
Definition: clientmodel.h:103
BLOCK_SOURCE_NETWORK
@ BLOCK_SOURCE_NETWORK
Definition: clientmodel.h:33
ClientModel::cachedMasternodeCountString
QString cachedMasternodeCountString
Definition: clientmodel.h:100
ClientModel::getPeerTableModel
PeerTableModel * getPeerTableModel()
Definition: clientmodel.cpp:203
GetWarnings
std::string GetWarnings(std::string strFor)
Format a string that describes several potential problems detected by the core.
Definition: main.cpp:5739
CBlockHeader::GetBlockTime
int64_t GetBlockTime() const
Definition: block.h:135
IsReachable
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
Definition: net.cpp:280
CLIENT_NAME
const std::string CLIENT_NAME
cs_mapLocalHost
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:74
ClientModel::getMasternodeCountString
QString getMasternodeCountString() const
Definition: clientmodel.cpp:75
ClientModel::setCacheReindexing
void setCacheReindexing(bool reindex)
Definition: clientmodel.h:90
ClientModel::bytesChanged
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
ClientModel::setCacheTip
void setCacheTip(const CBlockIndex *const tip)
Definition: clientmodel.h:89
ClientModel::pollMnTimer
QTimer * pollMnTimer
Definition: clientmodel.h:108
ClientModel::pollTimer
QTimer * pollTimer
Definition: clientmodel.h:107
ClientModel::clientName
QString clientName() const
Definition: clientmodel.cpp:223
CClientUIInterface::NotifyAlertChanged
boost::signals2::signal< void()> NotifyAlertChanged
New, updated or cancelled alert.
Definition: guiinterface.h:95
guiutil.h
ClientModel::formatFullVersion
QString formatFullVersion() const
Definition: clientmodel.cpp:213
CChainParams::GenesisBlock
const CBlock & GenesisBlock() const
Definition: chainparams.h:68
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
ClientModel::peerTableModel
PeerTableModel * peerTableModel
Definition: clientmodel.h:96
ClientModel::optionsModel
OptionsModel * optionsModel
Definition: clientmodel.h:95
PeerTableModel
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call.
Definition: peertablemodel.h:42
ClientModel::updateNumConnections
void updateNumConnections(int numConnections)
Definition: clientmodel.cpp:166
ClientModel::getTotalBytesSent
quint64 getTotalBytesSent() const
Definition: clientmodel.cpp:104
ClientModel::getVerificationProgress
double getVerificationProgress() const
Definition: clientmodel.cpp:121
CBlockIndex::GetBlockHash
uint256 GetBlockHash() const
Definition: chain.h:359
mapLocalHost
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
Definition: net.cpp:75
checkpoints.h
ClientModel::updateBanlist
void updateBanlist()
Definition: clientmodel.cpp:238
GetTimeMillis
int64_t GetTimeMillis()
Definition: utiltime.cpp:31
BLOCK_SOURCE_REINDEX
@ BLOCK_SOURCE_REINDEX
Definition: clientmodel.h:31
CMasternodeMan::CountNetworks
void CountNetworks(int protocolVersion, int &ipv4, int &ipv6, int &onion)
Definition: masternodeman.cpp:393
ClientModel
Model for PRCY network client.
Definition: clientmodel.h:44
Checkpoints::GuessVerificationProgress
double GuessVerificationProgress(const CBlockIndex *pindex, bool fSigchecks)
Guess how far we are in the verification process at the given block index.
Definition: checkpoints.cpp:45
guiconstants.h
ClientModel::setCacheInitialSync
void setCacheInitialSync(bool _initialSync)
Definition: clientmodel.h:92
CNode::GetTotalBytesSent
static uint64_t GetTotalBytesSent()
Definition: net.cpp:2102
fReindex
std::atomic< bool > fReindex
Definition: main.cpp:81
main.h
ClientModel::getNumBlocks
int getNumBlocks()
Definition: clientmodel.cpp:84
LOCK
#define LOCK(cs)
Definition: sync.h:182
ClientModel::formatClientStartupTime
QString formatClientStartupTime() const
Definition: clientmodel.cpp:228
ClientModel::~ClientModel
~ClientModel()
Definition: clientmodel.cpp:56
LookupNumeric
CService LookupNumeric(const char *pszName, int portDefault)
Definition: netbase.cpp:234
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:349
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
GetProxy
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:558
ClientModel::dataDir
QString dataDir() const
Definition: clientmodel.cpp:233
BLOCK_SOURCE_DISK
@ BLOCK_SOURCE_DISK
Definition: clientmodel.h:32
ClientModel::strMasternodesChanged
void strMasternodesChanged(const QString &strMasternodes)
bantablemodel.h
netbase.h
CChain::Tip
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or NULL if none.
Definition: chain.h:596
BlockSource
BlockSource
Definition: clientmodel.h:29
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:80
CClientUIInterface::NotifyBlockTip
boost::signals2::signal< void(bool fInitialDownload, const CBlockIndex *newTip)> NotifyBlockTip
New block has been accepted.
Definition: guiinterface.h:104
peertablemodel.h
CClientUIInterface::ShowProgress
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: guiinterface.h:101
ClientModel::numBlocksChanged
void numBlocksChanged(int count)
net.h
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:162
ClientModel::getLastBlockDate
QDateTime getLastBlockDate() const
Definition: clientmodel.cpp:109
ClientModel::stopMasternodesTimer
void stopMasternodesTimer()
Definition: clientmodel.cpp:159
ClientModel::getTotalBytesRecv
quint64 getTotalBytesRecv() const
Definition: clientmodel.cpp:99
CLIENT_VERSION_IS_RELEASE
#define CLIENT_VERSION_IS_RELEASE
Definition: prcycoin-config.h:15
BanTableModel::refresh
void refresh()
Definition: bantablemodel.cpp:169
clientmodel.h
ClientModel::updateAlert
void updateAlert()
Definition: clientmodel.cpp:171
CClientUIInterface::NotifyNumConnectionsChanged
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: guiinterface.h:92
ClientModel::getBanTableModel
BanTableModel * getBanTableModel()
Definition: clientmodel.cpp:208