Raven Core  3.0.0
P2P Digital Currency
clientmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven 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 "clientmodel.h"
7 
8 #include "bantablemodel.h"
9 #include "guiconstants.h"
10 #include "guiutil.h"
11 #include "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 
24 #include <stdint.h>
25 
26 #include <QDebug>
27 #include <QTimer>
28 
29 class CBlockIndex;
30 
31 static int64_t nLastHeaderTipUpdateNotification = 0;
32 static int64_t nLastBlockTipUpdateNotification = 0;
33 
34 ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
35  QObject(parent),
36  optionsModel(_optionsModel),
37  peerTableModel(0),
38  banTableModel(0),
39  pollTimer(0)
40 {
43  peerTableModel = new PeerTableModel(this);
44  banTableModel = new BanTableModel(this);
45  pollTimer = new QTimer(this);
46  connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
47  pollTimer->start(MODEL_UPDATE_DELAY);
48 
50 }
51 
53 {
55 }
56 
57 int ClientModel::getNumConnections(unsigned int flags) const
58 {
60 
61  if(flags == CONNECTIONS_IN)
62  connections = CConnman::CONNECTIONS_IN;
63  else if (flags == CONNECTIONS_OUT)
64  connections = CConnman::CONNECTIONS_OUT;
65  else if (flags == CONNECTIONS_ALL)
66  connections = CConnman::CONNECTIONS_ALL;
67 
68  if(g_connman)
69  return g_connman->GetNodeCount(connections);
70  return 0;
71 }
72 
74 {
75  LOCK(cs_main);
76  return chainActive.Height();
77 }
78 
80 {
81  if (cachedBestHeaderHeight == -1) {
82  // make sure we initially populate the cache via a cs_main lock
83  // otherwise we need to wait for a tip update
84  LOCK(cs_main);
85  if (pindexBestHeader) {
88  }
89  }
91 }
92 
94 {
95  if (cachedBestHeaderTime == -1) {
96  LOCK(cs_main);
97  if (pindexBestHeader) {
100  }
101  }
102  return cachedBestHeaderTime;
103 }
104 
106 {
107  if(!g_connman)
108  return 0;
109  return g_connman->GetTotalBytesRecv();
110 }
111 
113 {
114  if(!g_connman)
115  return 0;
116  return g_connman->GetTotalBytesSent();
117 }
118 
120 {
121  LOCK(cs_main);
122 
123  if (chainActive.Tip())
124  return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
125 
126  return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
127 }
128 
130 {
131  return mempool.size();
132 }
133 
135 {
136  return mempool.DynamicMemoryUsage();
137 }
138 
140 {
141  CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
142  if (!tip)
143  {
144  LOCK(cs_main);
145  tip = chainActive.Tip();
146  }
147  return GuessVerificationProgress(Params().TxData(), tip);
148 }
149 
151 {
152  // no locking required at this point
153  // the following calls will acquire the required lock
156 }
157 
158 void ClientModel::updateNumConnections(int numConnections)
159 {
160  Q_EMIT numConnectionsChanged(numConnections);
161 }
162 
163 void ClientModel::updateNetworkActive(bool networkActive)
164 {
165  Q_EMIT networkActiveChanged(networkActive);
166 }
167 
169 {
171 }
172 
174 {
175  return IsInitialBlockDownload();
176 }
177 
179 {
180  if (fReindex)
181  return BLOCK_SOURCE_REINDEX;
182  else if (fImporting)
183  return BLOCK_SOURCE_DISK;
184  else if (getNumConnections() > 0)
185  return BLOCK_SOURCE_NETWORK;
186 
187  return BLOCK_SOURCE_NONE;
188 }
189 
191 {
192  if (g_connman) {
193  g_connman->SetNetworkActive(active);
194  }
195 }
196 
198 {
199  if (g_connman) {
200  return g_connman->GetNetworkActive();
201  }
202  return false;
203 }
204 
206 {
207  return QString::fromStdString(GetWarnings("gui"));
208 }
209 
211 {
212  return optionsModel;
213 }
214 
216 {
217  return peerTableModel;
218 }
219 
221 {
222  return banTableModel;
223 }
224 
226 {
227  return QString::fromStdString(FormatFullVersion());
228 }
229 
231 {
232  return QString::fromStdString(strSubVersion);
233 }
234 
236 {
238 }
239 
241 {
242  return QDateTime::fromTime_t(GetStartupTime()).toString();
243 }
244 
245 QString ClientModel::dataDir() const
246 {
248 }
249 
251 {
253 }
254 
255 // Handlers for core signals
256 static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
257 {
258  // emits signal "showProgress"
259  QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
260  Q_ARG(QString, QString::fromStdString(title)),
261  Q_ARG(int, nProgress));
262 }
263 
264 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
265 {
266  // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
267  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
268  Q_ARG(int, newNumConnections));
269 }
270 
271 static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
272 {
273  QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
274  Q_ARG(bool, networkActive));
275 }
276 
277 static void NotifyAlertChanged(ClientModel *clientmodel)
278 {
279  qDebug() << "NotifyAlertChanged";
280  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
281 }
282 
283 static void BannedListChanged(ClientModel *clientmodel)
284 {
285  qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
286  QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
287 }
288 
289 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
290 {
291  // lock free async UI updates in case we have a new block tip
292  // during initial sync, only update the UI if the last update
293  // was > 250ms (MODEL_UPDATE_DELAY) ago
294  int64_t now = 0;
295  if (initialSync)
296  now = GetTimeMillis();
297 
298  int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
299 
300  if (fHeader) {
301  // cache best headers time and height to reduce future cs_main locks
302  clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
303  clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
304  }
305  // if we are in-sync, update the UI regardless of last update time
306  if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
307  //pass an async signal to the UI thread
308  QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
309  Q_ARG(int, pIndex->nHeight),
310  Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
311  Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
312  Q_ARG(bool, fHeader));
313  nLastUpdateNotification = now;
314  }
315 }
316 
318 {
319  // Connect signals to client
320  uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
321  uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
322  uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
323  uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
324  uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
325  uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
326  uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
327 }
328 
330 {
331  // Disconnect signals from client
332  uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
333  uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
334  uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
335  uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
336  uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
337  uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
338  uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
339 }
QString formatClientStartupTime() const
CTxMemPool mempool
PeerTableModel * peerTableModel
Definition: clientmodel.h:90
void updateNetworkActive(bool networkActive)
bool inInitialBlockDownload() const
Return true if core is doing initial block download.
QString formatSubVersion() const
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:299
std::atomic< int64_t > cachedBestHeaderTime
Definition: clientmodel.h:86
int flags
Definition: raven-tx.cpp:500
void updateBanlist()
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:1281
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, logging, thread wrappers...
Definition: util.cpp:930
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:479
CCriticalSection cs_main
Global state.
Definition: validation.cpp:72
void networkActiveChanged(bool networkActive)
BanTableModel * banTableModel
Definition: clientmodel.h:91
OptionsModel * getOptionsModel()
quint64 getTotalBytesSent() const
std::atomic< int > cachedBestHeaderHeight
Definition: clientmodel.h:85
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 numConnectionsChanged(int count)
double GuessVerificationProgress(const ChainTxData &data, CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index.
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
void alertsChanged(const QString &warnings)
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
Definition: ui_interface.h:111
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
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
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:57
double getVerificationProgress(const CBlockIndex *tip) const
unsigned long size()
Definition: txmempool.h:648
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:76
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
#define LOCK(cs)
Definition: sync.h:176
quint64 getTotalBytesRecv() const
BlockSource
Definition: clientmodel.h:24
void unsubscribeFromCoreSignals()
BanTableModel * getBanTableModel()
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
void subscribeToCoreSignals()
NumConnections
Definition: net.h:124
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:75
std::atomic_bool fImporting
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:93
Model for Raven network client.
Definition: clientmodel.h:39
QTimer * pollTimer
Definition: clientmodel.h:93
size_t getMempoolDynamicUsage() const
Return the dynamic memory usage of the mempool.
std::string FormatFullVersion()
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: ui_interface.h:85
QDateTime getLastBlockDate() const
std::atomic_bool fReindex
void updateAlert()
ClientModel(OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:34
Interface from Qt to configuration data structure for Raven client.
Definition: optionsmodel.h:23
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:172
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()
Definition: utiltime.cpp:40
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
Definition: bantablemodel.h:38
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:448
#define CLIENT_VERSION_IS_RELEASE
Definition: raven-config.h:15
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:81
OptionsModel * optionsModel
Definition: clientmodel.h:89
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes)
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:572
void setNetworkActive(bool active)
Toggle network activity state in core.
QString dataDir() const
CClientUIInterface uiInterface
Definition: ui_interface.cpp:9
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:185
int getNumBlocks() const
Definition: clientmodel.cpp:73
void updateNumConnections(int numConnections)
int getHeaderTipHeight() const
Definition: clientmodel.cpp:79
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:956
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
Definition: clientmodel.cpp:93
QString formatFullVersion() const