BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
clientmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2018 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 <qt/clientmodel.h>
6 
7 #include <qt/bantablemodel.h>
8 #include <qt/guiconstants.h>
9 #include <qt/guiutil.h>
10 #include <qt/peertablemodel.h>
11 
12 #include <chain.h>
13 #include <chainparams.h>
14 #include <checkpoints.h>
15 #include <clientversion.h>
16 #include <interfaces/handler.h>
17 #include <interfaces/node.h>
18 #include <validation.h>
19 #include <net.h>
20 #include <netbase.h>
21 #include <txmempool.h>
22 #include <ui_interface.h>
23 #include <util.h>
24 #include <warnings.h>
25 
26 #include <stdint.h>
27 
28 #include <QDebug>
29 #include <QTimer>
30 
31 static int64_t nLastHeaderTipUpdateNotification = 0;
32 static int64_t nLastBlockTipUpdateNotification = 0;
33 
34 ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QObject *parent) :
35  QObject(parent),
36  m_node(node),
37  optionsModel(_optionsModel),
38  peerTableModel(0),
39  banTableModel(0),
40  pollTimer(0)
41 {
45  banTableModel = new BanTableModel(m_node, this);
46  pollTimer = new QTimer(this);
47  connect(pollTimer, &QTimer::timeout, this, &ClientModel::updateTimer);
48  pollTimer->start(MODEL_UPDATE_DELAY);
49 
51 }
52 
54 {
56 }
57 
58 int ClientModel::getNumConnections(unsigned int flags) const
59 {
61 
62  if(flags == CONNECTIONS_IN)
63  connections = CConnman::CONNECTIONS_IN;
64  else if (flags == CONNECTIONS_OUT)
65  connections = CConnman::CONNECTIONS_OUT;
66  else if (flags == CONNECTIONS_ALL)
67  connections = CConnman::CONNECTIONS_ALL;
68 
69  return m_node.getNodeCount(connections);
70 }
71 
73 {
74  if (cachedBestHeaderHeight == -1) {
75  // make sure we initially populate the cache via a cs_main lock
76  // otherwise we need to wait for a tip update
77  int height;
78  int64_t blockTime;
79  if (m_node.getHeaderTip(height, blockTime)) {
80  cachedBestHeaderHeight = height;
81  cachedBestHeaderTime = blockTime;
82  }
83  }
85 }
86 
88 {
89  if (cachedBestHeaderTime == -1) {
90  int height;
91  int64_t blockTime;
92  if (m_node.getHeaderTip(height, blockTime)) {
93  cachedBestHeaderHeight = height;
94  cachedBestHeaderTime = blockTime;
95  }
96  }
97  return cachedBestHeaderTime;
98 }
99 
101 {
102  // no locking required at this point
103  // the following calls will acquire the required lock
106 }
107 
108 void ClientModel::updateNumConnections(int numConnections)
109 {
110  Q_EMIT numConnectionsChanged(numConnections);
111 }
112 
113 void ClientModel::updateNetworkActive(bool networkActive)
114 {
115  Q_EMIT networkActiveChanged(networkActive);
116 }
117 
119 {
121 }
122 
124 {
125  if (m_node.getReindex())
126  return BlockSource::REINDEX;
127  else if (m_node.getImporting())
128  return BlockSource::DISK;
129  else if (getNumConnections() > 0)
130  return BlockSource::NETWORK;
131 
132  return BlockSource::NONE;
133 }
134 
136 {
137  return QString::fromStdString(m_node.getWarnings("gui"));
138 }
139 
141 {
142  return optionsModel;
143 }
144 
146 {
147  return peerTableModel;
148 }
149 
151 {
152  return banTableModel;
153 }
154 
156 {
157  return QString::fromStdString(FormatFullVersion());
158 }
159 
161 {
162  return QString::fromStdString(strSubVersion);
163 }
164 
166 {
168 }
169 
171 {
172  return QDateTime::fromTime_t(GetStartupTime()).toString();
173 }
174 
175 QString ClientModel::dataDir() const
176 {
178 }
179 
180 QString ClientModel::blocksDir() const
181 {
183 }
184 
186 {
188 }
189 
190 // Handlers for core signals
191 static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
192 {
193  // emits signal "showProgress"
194  QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
195  Q_ARG(QString, QString::fromStdString(title)),
196  Q_ARG(int, nProgress));
197 }
198 
199 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
200 {
201  // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
202  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
203  Q_ARG(int, newNumConnections));
204 }
205 
206 static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
207 {
208  QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
209  Q_ARG(bool, networkActive));
210 }
211 
212 static void NotifyAlertChanged(ClientModel *clientmodel)
213 {
214  qDebug() << "NotifyAlertChanged";
215  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
216 }
217 
218 static void BannedListChanged(ClientModel *clientmodel)
219 {
220  qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
221  QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
222 }
223 
224 static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int height, int64_t blockTime, double verificationProgress, bool fHeader)
225 {
226  // lock free async UI updates in case we have a new block tip
227  // during initial sync, only update the UI if the last update
228  // was > 250ms (MODEL_UPDATE_DELAY) ago
229  int64_t now = 0;
230  if (initialSync)
231  now = GetTimeMillis();
232 
233  int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
234 
235  if (fHeader) {
236  // cache best headers time and height to reduce future cs_main locks
237  clientmodel->cachedBestHeaderHeight = height;
238  clientmodel->cachedBestHeaderTime = blockTime;
239  }
240  // if we are in-sync, update the UI regardless of last update time
241  if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
242  //pass an async signal to the UI thread
243  QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
244  Q_ARG(int, height),
245  Q_ARG(QDateTime, QDateTime::fromTime_t(blockTime)),
246  Q_ARG(double, verificationProgress),
247  Q_ARG(bool, fHeader));
248  nLastUpdateNotification = now;
249  }
250 }
251 
253 {
254  // Connect signals to client
255  m_handler_show_progress = m_node.handleShowProgress(boost::bind(ShowProgress, this, _1, _2));
256  m_handler_notify_num_connections_changed = m_node.handleNotifyNumConnectionsChanged(boost::bind(NotifyNumConnectionsChanged, this, _1));
257  m_handler_notify_network_active_changed = m_node.handleNotifyNetworkActiveChanged(boost::bind(NotifyNetworkActiveChanged, this, _1));
258  m_handler_notify_alert_changed = m_node.handleNotifyAlertChanged(boost::bind(NotifyAlertChanged, this));
259  m_handler_banned_list_changed = m_node.handleBannedListChanged(boost::bind(BannedListChanged, this));
260  m_handler_notify_block_tip = m_node.handleNotifyBlockTip(boost::bind(BlockTipChanged, this, _1, _2, _3, _4, false));
261  m_handler_notify_header_tip = m_node.handleNotifyHeaderTip(boost::bind(BlockTipChanged, this, _1, _2, _3, _4, true));
262 }
263 
265 {
266  // Disconnect signals from client
267  m_handler_show_progress->disconnect();
270  m_handler_notify_alert_changed->disconnect();
271  m_handler_banned_list_changed->disconnect();
272  m_handler_notify_block_tip->disconnect();
273  m_handler_notify_header_tip->disconnect();
274 }
275 
276 bool ClientModel::getProxyInfo(std::string& ip_port) const
277 {
278  proxyType ipv4, ipv6;
279  if (m_node.getProxy((Network) 1, ipv4) && m_node.getProxy((Network) 2, ipv6)) {
280  ip_port = ipv4.proxy.ToStringIPPort();
281  return true;
282  }
283  return false;
284 }
virtual std::unique_ptr< Handler > handleNotifyHeaderTip(NotifyHeaderTipFn fn)=0
QString formatClientStartupTime() const
PeerTableModel * peerTableModel
Definition: clientmodel.h:90
void updateNetworkActive(bool networkActive)
QString formatSubVersion() const
virtual std::string getWarnings(const std::string &type)=0
Get warnings.
interfaces::Node & m_node
Definition: clientmodel.h:81
bool isReleaseVersion() const
std::atomic< int64_t > cachedBestHeaderTime
Definition: clientmodel.h:78
void updateBanlist()
QString blocksDir() const
virtual size_t getMempoolDynamicUsage()=0
Get mempool dynamic usage.
virtual bool getProxy(Network net, proxyType &proxy_info)=0
Get proxy.
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, thread wrappers, startup time.
Definition: util.cpp:1250
virtual int64_t getTotalBytesRecv()=0
Get total bytes recv.
virtual bool getImporting()=0
Get importing.
virtual size_t getMempoolSize()=0
Get mempool size.
void networkActiveChanged(bool networkActive)
BanTableModel * banTableModel
Definition: clientmodel.h:91
std::unique_ptr< interfaces::Handler > m_handler_show_progress
Definition: clientmodel.h:82
OptionsModel * getOptionsModel()
std::atomic< int > cachedBestHeaderHeight
Definition: clientmodel.h:77
PeerTableModel * getPeerTableModel()
virtual std::unique_ptr< Handler > handleNotifyBlockTip(NotifyBlockTipFn fn)=0
void numConnectionsChanged(int count)
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
void alertsChanged(const QString &warnings)
std::unique_ptr< interfaces::Handler > m_handler_notify_block_tip
Definition: clientmodel.h:87
virtual std::unique_ptr< Handler > handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn)=0
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
#define CLIENT_VERSION_IS_RELEASE
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:58
enum BlockSource getBlockSource() const
Returns enum BlockSource of the current importing/syncing state.
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
BlockSource
Definition: clientmodel.h:29
void unsubscribeFromCoreSignals()
virtual std::unique_ptr< Handler > handleShowProgress(ShowProgressFn fn)=0
BanTableModel * getBanTableModel()
void subscribeToCoreSignals()
Network
Definition: netaddress.h:20
std::unique_ptr< interfaces::Handler > m_handler_banned_list_changed
Definition: clientmodel.h:86
ClientModel(interfaces::Node &node, OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:34
NumConnections
Definition: net.h:119
virtual std::unique_ptr< Handler > handleBannedListChanged(BannedListChangedFn fn)=0
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:89
Model for Bitcoin network client.
Definition: clientmodel.h:44
std::unique_ptr< interfaces::Handler > m_handler_notify_header_tip
Definition: clientmodel.h:88
QTimer * pollTimer
Definition: clientmodel.h:93
std::string FormatFullVersion()
const fs::path & GetBlocksDir(bool fNetSpecific)
Definition: util.cpp:737
virtual bool getReindex()=0
Get reindex.
void updateAlert()
std::unique_ptr< interfaces::Handler > m_handler_notify_num_connections_changed
Definition: clientmodel.h:83
CService proxy
Definition: netbase.h:36
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:29
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:43
std::string ToStringIPPort() const
Definition: netaddress.cpp:565
virtual bool getHeaderTip(int &height, int64_t &block_time)=0
Get header tip height and time.
OptionsModel * optionsModel
Definition: clientmodel.h:89
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes)
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:766
int flags
Definition: bsha3-tx.cpp:509
QString dataDir() const
virtual std::unique_ptr< Handler > handleNotifyAlertChanged(NotifyAlertChangedFn fn)=0
std::unique_ptr< interfaces::Handler > m_handler_notify_network_active_changed
Definition: clientmodel.h:84
void updateNumConnections(int numConnections)
int getHeaderTipHeight() const
Definition: clientmodel.cpp:72
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:768
std::unique_ptr< interfaces::Handler > m_handler_notify_alert_changed
Definition: clientmodel.h:85
virtual std::unique_ptr< Handler > handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn)=0
virtual int64_t getTotalBytesSent()=0
Get total bytes sent.
int64_t getHeaderTipTime() const
Definition: clientmodel.cpp:87
Top-level interface for a bitcoin node (bsha3d process).
Definition: node.h:35
virtual size_t getNodeCount(CConnman::NumConnections flags)=0
Get number of connections.
QString formatFullVersion() const
bool getProxyInfo(std::string &ip_port) const