Anoncoin  0.9.4
P2P Digital Currency
clientmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2013 The Bitcoin developers
2 // Copyright (c) 2013-2015 The Anoncoin Core developers
3 // Distributed under the MIT/X11 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 "guiconstants.h"
9 #include "peertablemodel.h"
10 
11 #include "alert.h"
12 #include "chainparams.h"
13 #include "checkpoints.h"
14 #include "main.h"
15 #include "net.h"
16 #include "ui_interface.h"
17 
18 #ifdef ENABLE_I2PSAM
19 #include "i2pwrapper.h" // Include for i2p interface
20 #endif
21 
22 #include <stdint.h>
23 
24 #include <QDateTime>
25 #include <QDebug>
26 #include <QTimer>
27 
28 static const int64_t nClientStartupTime = GetTime();
29 
30 ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
31  QObject(parent),
32  optionsModel(optionsModel),
33  peerTableModel(0),
34  cachedNumBlocks(0),
35  cachedReindexing(0), cachedImporting(0),
36  numBlocksAtStartup(-1), pollTimer(0)
37 {
38  peerTableModel = new PeerTableModel(this);
39  pollTimer = new QTimer(this);
40  connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
41  pollTimer->start(MODEL_UPDATE_DELAY);
42 
44 }
45 
47 {
49 }
50 
51 int ClientModel::getNumConnections(unsigned int flags) const
52 {
53  LOCK(cs_vNodes);
54  if (flags == CONNECTIONS_ALL) // Shortcut if we want total
55  return vNodes.size();
56 
57  int nNum = 0;
58  BOOST_FOREACH(CNode* pnode, vNodes)
59  if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
60  nNum++;
61 
62  return nNum;
63 }
64 
66 {
67  LOCK(cs_main);
68  return chainActive.Height();
69 }
70 
72 {
74  return numBlocksAtStartup;
75 }
76 
78 {
79  return CNode::GetTotalBytesRecv();
80 }
81 
83 {
84  return CNode::GetTotalBytesSent();
85 }
86 
88 {
89  LOCK(cs_main);
90  if (chainActive.Tip())
91  return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
92  else
93  return QDateTime::fromTime_t(Params().GenesisBlock().nTime); // Genesis block's time of current network
94 }
95 
97 {
98  LOCK(cs_main);
100 }
101 
103 {
104  // Get required lock upfront. This avoids the GUI from getting stuck on
105  // periodical polls if the core is holding the locks for a longer time -
106  // for example, during a wallet rescan.
107  TRY_LOCK(cs_main, lockMain);
108  if(!lockMain)
109  return;
110  // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
111  // Periodically check and update with a timer.
112  int newNumBlocks = getNumBlocks();
113 
114  // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
115  if (cachedNumBlocks != newNumBlocks ||
117  {
118  cachedNumBlocks = newNumBlocks;
121 
122  emit numBlocksChanged(newNumBlocks);
123  }
124 
126 }
127 
128 void ClientModel::updateNumConnections(int numConnections)
129 {
130  emit numConnectionsChanged(numConnections);
131 }
132 
133 void ClientModel::updateAlert(const QString &hash, int status)
134 {
135  // Show error message notification for new alert
136  if(status == CT_NEW)
137  {
138  uint256 hash_256;
139  hash_256.SetHex(hash.toStdString());
140  CAlert alert = CAlert::getAlertByHash(hash_256);
141  if(!alert.IsNull())
142  {
143  emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR);
144  }
145  }
146 
148 }
149 
151 {
152  QString netname(QString::fromStdString(Params().DataDir()));
153  if(netname.isEmpty())
154  netname = "main";
155  return netname;
156 }
157 
158 #ifdef ENABLE_I2PSAM
159 /**********************************************************************
160  * These I2P functions handle values for the view
161  */
162 QString ClientModel::formatI2PNativeFullVersion() const
163 {
164  return QString::fromStdString(FormatI2PNativeFullVersion());
165 }
166 
167 void ClientModel::updateNumI2PConnections(int numI2PConnections)
168 {
169  emit numI2PConnectionsChanged(numI2PConnections);
170 }
171 
172 int ClientModel::getNumI2PConnections() const
173 {
174  return nI2PNodeCount;
175 }
176 
177 QString ClientModel::getPublicI2PKey() const
178 {
179  return IsI2PEnabled() ? QString::fromStdString(I2PSession::Instance().getMyDestination().pub) : QString( "Not Available" );
180 }
181 
182 QString ClientModel::getPrivateI2PKey() const
183 {
184  return IsI2PEnabled() ? QString::fromStdString(I2PSession::Instance().getMyDestination().priv) : QString( "Not Available" );
185 }
186 
187 bool ClientModel::isI2PAddressGenerated() const
188 {
189  return IsI2PEnabled() ? I2PSession::Instance().getMyDestination().isGenerated : false;
190 }
191 
192 bool ClientModel::isI2POnly() const
193 {
194  return IsI2POnly();
195 }
196 
197 bool ClientModel::isTorOnly() const
198 {
199  return IsTorOnly();
200 }
201 
202 bool ClientModel::isDarknetOnly() const
203 {
204  return IsDarknetOnly();
205 }
206 
207 bool ClientModel::isBehindDarknet() const
208 {
209  return IsBehindDarknet();
210 }
211 
212 QString ClientModel::getB32Address(const QString& destination) const
213 {
214  return IsI2PEnabled() ? QString::fromStdString(I2PSession::GenerateB32AddressFromDestination(destination.toStdString())) : QString( "Not Available" );
215 }
216 
217 void ClientModel::generateI2PDestination(QString& pub, QString& priv) const
218 {
219  SAM::FullDestination generatedDest( "Not Available", "Not Available", false );
220  if( IsI2PEnabled() )
221  generatedDest = I2PSession::Instance().destGenerate();
222  pub = QString::fromStdString(generatedDest.pub);
223  priv = QString::fromStdString(generatedDest.priv);
224 }
225 #endif // ENABLE_I2PSAM
226 
228 {
229  return IsInitialBlockDownload();
230 }
231 
233 {
234  if (fReindex)
235  return BLOCK_SOURCE_REINDEX;
236  else if (fImporting)
237  return BLOCK_SOURCE_DISK;
238  else if (getNumConnections() > 0)
239  return BLOCK_SOURCE_NETWORK;
240 
241  return BLOCK_SOURCE_NONE;
242 }
243 
245 {
246  return QString::fromStdString(GetWarnings("statusbar"));
247 }
248 
250 {
251  return optionsModel;
252 }
253 
255 {
256  return peerTableModel;
257 }
258 
260 {
261  return QString::fromStdString(FormatFullVersion());
262 }
263 
265 {
266  return QString::fromStdString(CLIENT_DATE);
267 }
268 
270 {
272 }
273 
274 QString ClientModel::clientName() const
275 {
276  return QString::fromStdString(CLIENT_NAME);
277 }
278 
280 {
281  return QDateTime::fromTime_t(nClientStartupTime).toString();
282 }
283 
284 // Handlers for core signals
285 static void NotifyBlocksChanged(ClientModel *clientmodel)
286 {
287  // This notification is too frequent. Don't trigger a signal.
288  // Don't remove it, though, as it might be useful later.
289 }
290 
291 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
292 {
293  // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
294  QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
295  Q_ARG(int, newNumConnections));
296 }
297 
298 #ifdef ENABLE_I2PSAM
299 static void NotifyNumI2PConnectionsChanged(ClientModel *clientmodel, int newNumI2PConnections)
300 {
301  QMetaObject::invokeMethod(clientmodel, "updateNumI2PConnections", Qt::QueuedConnection,
302  Q_ARG(int, newNumI2PConnections));
303 }
304 #endif // ENABLE_I2PSAM
305 
306 static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
307 {
308  qDebug() << "NotifyAlertChanged : " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status);
309  QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
310  Q_ARG(QString, QString::fromStdString(hash.GetHex())),
311  Q_ARG(int, status));
312 }
313 
315 {
316  // Connect signals to client
317  uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
318  uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
319  uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
320 #ifdef ENABLE_I2PSAM
321  uiInterface.NotifyNumI2PConnectionsChanged.connect(boost::bind(NotifyNumI2PConnectionsChanged, this, _1));
322 #endif
323 }
324 
326 {
327  // Disconnect signals from client
328  uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this));
329  uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
330  uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
331 #ifdef ENABLE_I2PSAM
332  uiInterface.NotifyNumI2PConnectionsChanged.disconnect(boost::bind(NotifyNumI2PConnectionsChanged, this, _1));
333 #endif
334 }
335 
void numBlocksChanged(int count)
CClientUIInterface uiInterface
Definition: util.cpp:100
void SetHex(const char *psz)
Definition: uint256.h:306
void message(const QString &title, const QString &message, unsigned int style)
Fired when a message should be reported to the user.
PeerTableModel * peerTableModel
Definition: clientmodel.h:102
static uint64_t GetTotalBytesRecv()
Definition: net.cpp:2157
#define TRY_LOCK(cs, name)
Definition: sync.h:159
bool fImporting
Definition: main.cpp:47
const SAM::FullDestination & getMyDestination() const
Definition: i2pwrapper.cpp:135
static SAM::StreamSessionAdapter & Instance()
Definition: i2pwrapper.h:68
quint64 getTotalBytesRecv() const
Definition: clientmodel.cpp:77
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:51
CCriticalSection cs_main
Definition: main.cpp:38
string GetWarnings(string strFor)
Definition: main.cpp:3093
OptionsModel * getOptionsModel()
QString formatClientStartupTime() const
PeerTableModel * getPeerTableModel()
bool fReindex
Definition: main.cpp:48
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
std::string strStatusBar
Definition: alert.h:47
void numConnectionsChanged(int count)
Note signal functions like this are created here in the header file, yet no source implmentation will...
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:43
bool isReleaseVersion() const
void alertsChanged(const QString &warnings)
QString getNetworkName() const
Return network (main, testnetX, regtest)
vector< CNode * > vNodes
Definition: net.cpp:74
bool IsNull() const
Definition: alert.cpp:95
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
#define CLIENT_VERSION_IS_RELEASE
Definition: clientversion.h:30
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 NULL if none.
Definition: main.h:1024
int Height() const
Return the maximal height in the chain.
Definition: main.h:1055
bool cachedImporting
Definition: clientmodel.h:106
double getVerificationProgress() const
Definition: clientmodel.cpp:96
ChangeType
General change type (added, updated, removed).
Definition: ui_interface.h:26
bool fInbound
Definition: net.h:256
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
Definition: main.cpp:1246
An alert is a combination of a serialized CUnsignedAlert and a signature.
Definition: alert.h:76
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call...
#define LOCK(cs)
Definition: sync.h:157
QDateTime getLastBlockDate() const
Definition: clientmodel.cpp:87
BlockSource
Definition: clientmodel.h:30
void updateAlert(const QString &hash, int status)
void unsubscribeFromCoreSignals()
QString clientName() const
void subscribeToCoreSignals()
QString formatBuildDate() const
const std::string CLIENT_NAME
static uint64_t GetTotalBytesSent()
Definition: net.cpp:2163
std::string GetHex() const
Definition: uint256.h:298
Model for Anoncoin network client.
Definition: clientmodel.h:45
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks)
int64_t GetTime()
Definition: util.cpp:1220
int cachedNumBlocks
Definition: clientmodel.h:104
QTimer * pollTimer
Definition: clientmodel.h:110
std::string FormatFullVersion()
const std::string CLIENT_DATE
int getNumBlocks() const
Definition: clientmodel.cpp:65
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: ui_interface.h:93
quint64 getTotalBytesSent() const
Definition: clientmodel.cpp:82
256-bit unsigned integer
Definition: uint256.h:532
int numBlocksAtStartup
Definition: clientmodel.h:108
bool cachedReindexing
Definition: clientmodel.h:105
ClientModel(OptionsModel *optionsModel, QObject *parent=0)
Definition: clientmodel.cpp:30
boost::signals2::signal< void(const uint256 &hash, ChangeType status)> NotifyAlertChanged
New, updated or cancelled alert.
Definition: ui_interface.h:99
Interface from Qt to configuration data structure for Anoncoin client.
Definition: optionsmodel.h:27
const CChainParams & Params()
Return the currently selected parameters.
void updateTimer()
From: https://qt-project.org/doc/qt-5-snapshot/signalsandslots.html A slot is a function that is call...
static CAlert getAlertByHash(const uint256 &hash)
Definition: alert.cpp:160
boost::signals2::signal< void()> NotifyBlocksChanged
Block chain changed.
Definition: ui_interface.h:90
static std::string GenerateB32AddressFromDestination(const std::string &destination)
Definition: i2pwrapper.cpp:203
SAM::FullDestination destGenerate() const
Definition: i2pwrapper.cpp:119
OptionsModel * optionsModel
Definition: clientmodel.h:101
int getNumBlocksAtStartup()
Definition: clientmodel.cpp:71
Information about a peer.
Definition: net.h:223
void updateNumConnections(int numConnections)
int64_t GetBlockTime() const
Definition: main.h:820
QString formatFullVersion() const
CCriticalSection cs_vNodes
Definition: net.cpp:75
enum BlockSource getBlockSource() const
Return true if core is importing blocks.