Fabcoin Core  0.16.2
P2P Digital Currency
clientmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2017 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.
4 
5 #include <clientmodel.h>
6 
7 #include <bantablemodel.h>
8 #include <guiconstants.h>
9 #include <guiutil.h>
10 #include <peertablemodel.h>
11 
12 #include <chain.h>
13 #include <chainparams.h>
14 #include <checkpoints.h>
15 #include <clientversion.h>
16 #include <validation.h>
17 #include <net.h>
18 #include <txmempool.h>
19 #include <ui_interface.h>
20 #include <util.h>
21 #include <warnings.h>
22 #include <wallet/wallet.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 
210 void ClientModel::getGasInfo(uint64_t& blockGasLimit, uint64_t& minGasPrice, uint64_t& nGasPrice) const
211 {
212  LOCK(cs_main);
213 
214  FascDGP fascDGP(globalState.get(), fGettingValuesDGP);
215  blockGasLimit = fascDGP.getBlockGasLimit(chainActive.Height());
216  minGasPrice = CAmount(fascDGP.getMinGasPrice(chainActive.Height()));
217  nGasPrice = (minGasPrice>DEFAULT_GAS_PRICE)?minGasPrice:DEFAULT_GAS_PRICE;
218 }
219 
221 {
222  return optionsModel;
223 }
224 
226 {
227  return peerTableModel;
228 }
229 
231 {
232  return banTableModel;
233 }
234 
236 {
237  return QString::fromStdString(FormatFullVersion());
238 }
239 
241 {
242  return QString::fromStdString(strSubVersion);
243 }
244 
246 {
248 }
249 
251 {
252  return QDateTime::fromTime_t(GetStartupTime()).toString();
253 }
254 
255 QString ClientModel::dataDir() const
256 {
258 }
259 
261 {
263 }
264 
265 // Handlers for core signals
266 static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
267 {
268  // emits signal "showProgress"
269  QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
270  Q_ARG(QString, QString::fromStdString(title)),
271  Q_ARG(int, nProgress));
272 }
273 
274 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
275 {
276  // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
277  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
278  Q_ARG(int, newNumConnections));
279 }
280 
281 static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
282 {
283  QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
284  Q_ARG(bool, networkActive));
285 }
286 
287 static void NotifyAlertChanged(ClientModel *clientmodel)
288 {
289  qDebug() << "NotifyAlertChanged";
290  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
291 }
292 
293 static void BannedListChanged(ClientModel *clientmodel)
294 {
295  qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
296  QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
297 }
298 
299 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
300 {
301  // Wallet batch mode checks
302  if(pIndex)
303  {
304  int64_t secs = GetTime() - pIndex->GetBlockTime();
305  bool batchMode = secs >= 90*60 ? true : false;
306  if(batchMode)
307  {
308  initialSync |= batchMode;
310  {
311  fBatchProcessingMode = true;
312  }
313  }
314  }
315 
316  // lock free async UI updates in case we have a new block tip
317  // during initial sync, only update the UI if the last update
318  // was > 250ms (MODEL_UPDATE_DELAY) ago
319  int64_t now = 0;
320  if (initialSync)
321  now = GetTimeMillis();
322 
323  int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
324 
325  if (fHeader) {
326  // cache best headers time and height to reduce future cs_main locks
327  clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
328  clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
329  }
330  // if we are in-sync, update the UI regardless of last update time
331  if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
332  //pass an async signal to the UI thread
333  QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
334  Q_ARG(int, pIndex->nHeight),
335  Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
336  Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
337  Q_ARG(bool, fHeader));
338  if(!fHeader && !fBatchProcessingMode)
339  {
340  QMetaObject::invokeMethod(clientmodel, "tipChanged", Qt::QueuedConnection);
341  }
342  nLastUpdateNotification = now;
343  }
344 }
345 
347 {
348  // Connect signals to client
349  uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
350  uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
351  uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
352  uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
353  uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
354  uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
355  uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
356 }
357 
359 {
360  // Disconnect signals from client
361  uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
362  uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
363  uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
364  uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
365  uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
366  uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
367  uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
368 }
CTxMemPool mempool
PeerTableModel * peerTableModel
Definition: clientmodel.h:91
void updateNetworkActive(bool networkActive)
std::atomic< int64_t > cachedBestHeaderTime
Definition: clientmodel.h:87
void updateBanlist()
double getVerificationProgress(const CBlockIndex *tip) const
quint64 getTotalBytesRecv() const
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, logging, thread wrappers...
Definition: util.cpp:980
bool getNetworkActive() const
Return true if network activity in core is enabled.
boost::signals2::signal< void(bool networkActive)> NotifyNetworkActiveChanged
Network activity state changed.
Definition: ui_interface.h:87
CCriticalSection cs_main
Definition: validation.cpp:77
bool fReindex
Definition: validation.cpp:86
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:57
void networkActiveChanged(bool networkActive)
BanTableModel * banTableModel
Definition: clientmodel.h:92
OptionsModel * getOptionsModel()
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:920
std::atomic< int > cachedBestHeaderHeight
Definition: clientmodel.h:86
QString formatClientStartupTime() const
PeerTableModel * getPeerTableModel()
size_t getMempoolDynamicUsage() const
Return the dynamic memory usage of the mempool.
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
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.
bool isReleaseVersion() const
void alertsChanged(const QString &warnings)
QString dataDir() const
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
Definition: ui_interface.h:110
int64_t CAmount
Amount in lius (Can be negative)
Definition: amount.h:15
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
bool fBatchProcessingMode
Definition: wallet.cpp:50
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyBlockTip
New block has been accepted.
Definition: ui_interface.h:104
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyHeaderTip
Best header has changed.
Definition: ui_interface.h:107
bool inInitialBlockDownload() const
Return true if core is doing initial block download.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:512
int Height() const
Return the maximal height in the chain.
Definition: chain.h:543
unsigned long size()
Definition: txmempool.h:659
CBlockIndex * pindexBestHeader
Best header we&#39;ve seen so far (used for getheaders queries&#39; starting points).
Definition: validation.cpp:81
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
#define LOCK(cs)
Definition: sync.h:175
QDateTime getLastBlockDate() const
BlockSource
Definition: clientmodel.h:23
uint64_t getBlockGasLimit(unsigned int blockHeight)
Definition: fascDGP.cpp:76
#define CLIENT_VERSION_IS_RELEASE
void unsubscribeFromCoreSignals()
QString formatSubVersion() const
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: ui_interface.h:98
BanTableModel * getBanTableModel()
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
void subscribeToCoreSignals()
std::string GetWarnings(const std::string &strFor)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:40
int getHeaderTipHeight() const
Definition: clientmodel.cpp:79
NumConnections
Definition: net.h:124
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:80
std::atomic_bool fImporting
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:88
Model for Fabcoin network client.
Definition: clientmodel.h:38
QTimer * pollTimer
Definition: clientmodel.h:94
std::string FormatFullVersion()
int getNumBlocks() const
Definition: clientmodel.cpp:73
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: ui_interface.h:84
quint64 getTotalBytesSent() const
void updateAlert()
ClientModel(OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:34
Interface from Qt to configuration data structure for Fabcoin client.
Definition: optionsmodel.h:22
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:177
const CChainParams & Params()
Return the currently selected parameters.
boost::signals2::signal< void()> NotifyAlertChanged
Status bar alerts changed.
Definition: ui_interface.h:92
void updateTimer()
int64_t GetTimeMillis()
Definition: utiltime.cpp:39
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
Definition: bantablemodel.h:37
int64_t getHeaderTipTime() const
Definition: clientmodel.cpp:93
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:75
OptionsModel * optionsModel
Definition: clientmodel.h:90
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes)
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:623
void setNetworkActive(bool active)
Toggle network activity state in core.
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
Definition: utiltime.cpp:19
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:193
void updateNumConnections(int numConnections)
int64_t GetBlockTime() const
Definition: chain.h:329
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:869
long getMempoolSize() const
Return number of transactions in the mempool.
QString formatFullVersion() const
enum BlockSource getBlockSource() const
Returns enum BlockSource of the current importing/syncing state.
std::unique_ptr< FascState > globalState
Global state.
Definition: validation.cpp:70
bool fGettingValuesDGP
Definition: validation.cpp:74
void getGasInfo(uint64_t &blockGasLimit, uint64_t &minGasPrice, uint64_t &nGasPrice) const
Get the information about the needed gas.