2222#include < QDebug>
2323#include < QTimer>
2424
25+ class CBlockIndex ;
26+
2527static const int64_t nClientStartupTime = GetTime();
28+ static int64_t nLastBlockTipUpdateNotification = 0 ;
2629
2730ClientModel::ClientModel (OptionsModel *optionsModel, QObject *parent) :
2831 QObject(parent),
2932 optionsModel(optionsModel),
3033 peerTableModel(0 ),
3134 banTableModel(0 ),
32- cachedNumBlocks(0 ),
33- cachedBlockDate(QDateTime()),
34- cachedReindexing(0 ),
35- cachedImporting(0 ),
3635 pollTimer(0 )
3736{
3837 peerTableModel = new PeerTableModel (this );
@@ -99,40 +98,21 @@ size_t ClientModel::getMempoolDynamicUsage() const
9998 return mempool.DynamicMemoryUsage ();
10099}
101100
102- double ClientModel::getVerificationProgress () const
101+ double ClientModel::getVerificationProgress (const CBlockIndex *tipIn ) const
103102{
104- LOCK (cs_main);
105- return Checkpoints::GuessVerificationProgress (Params ().Checkpoints (), chainActive.Tip ());
103+ CBlockIndex *tip = const_cast <CBlockIndex *>(tipIn);
104+ if (!tip)
105+ {
106+ LOCK (cs_main);
107+ tip = chainActive.Tip ();
108+ }
109+ return Checkpoints::GuessVerificationProgress (Params ().Checkpoints (), tip);
106110}
107111
108112void ClientModel::updateTimer ()
109113{
110- // Get required lock upfront. This avoids the GUI from getting stuck on
111- // periodical polls if the core is holding the locks for a longer time -
112- // for example, during a wallet rescan.
113- TRY_LOCK (cs_main, lockMain);
114- if (!lockMain)
115- return ;
116-
117- // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
118- // Periodically check and update with a timer.
119- int newNumBlocks = getNumBlocks ();
120- QDateTime newBlockDate = getLastBlockDate ();
121-
122- // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
123- if (cachedNumBlocks != newNumBlocks ||
124- cachedBlockDate != newBlockDate ||
125- cachedReindexing != fReindex ||
126- cachedImporting != fImporting )
127- {
128- cachedNumBlocks = newNumBlocks;
129- cachedBlockDate = newBlockDate;
130- cachedReindexing = fReindex ;
131- cachedImporting = fImporting ;
132-
133- Q_EMIT numBlocksChanged (newNumBlocks, newBlockDate);
134- }
135-
114+ // no locking required at this point
115+ // the following calls will aquire the required lock
136116 Q_EMIT mempoolSizeChanged (getMempoolSize (), getMempoolDynamicUsage ());
137117 Q_EMIT bytesChanged (getTotalBytesRecv (), getTotalBytesSent ());
138118}
@@ -261,13 +241,31 @@ static void BannedListChanged(ClientModel *clientmodel)
261241 QMetaObject::invokeMethod (clientmodel, " updateBanlist" , Qt::QueuedConnection);
262242}
263243
244+ static void BlockTipChanged (ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
245+ {
246+ // lock free async UI updates in case we have a new block tip
247+ // during initial sync, only update the UI if the last update
248+ // was > 250ms (MODEL_UPDATE_DELAY) ago
249+ int64_t now = 0 ;
250+ if (initialSync)
251+ now = GetTimeMillis ();
252+
253+ // if we are in-sync, update the UI regardless of last update time
254+ if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) {
255+ // pass a async signal to the UI thread
256+ Q_EMIT clientmodel->numBlocksChanged (pIndex->nHeight , QDateTime::fromTime_t (pIndex->GetBlockTime ()), clientmodel->getVerificationProgress (pIndex));
257+ nLastBlockTipUpdateNotification = now;
258+ }
259+ }
260+
264261void ClientModel::subscribeToCoreSignals ()
265262{
266263 // Connect signals to client
267264 uiInterface.ShowProgress .connect (boost::bind (ShowProgress, this , _1, _2));
268265 uiInterface.NotifyNumConnectionsChanged .connect (boost::bind (NotifyNumConnectionsChanged, this , _1));
269266 uiInterface.NotifyAlertChanged .connect (boost::bind (NotifyAlertChanged, this , _1, _2));
270267 uiInterface.BannedListChanged .connect (boost::bind (BannedListChanged, this ));
268+ uiInterface.NotifyBlockTip .connect (boost::bind (BlockTipChanged, this , _1, _2));
271269}
272270
273271void ClientModel::unsubscribeFromCoreSignals ()
@@ -277,4 +275,5 @@ void ClientModel::unsubscribeFromCoreSignals()
277275 uiInterface.NotifyNumConnectionsChanged .disconnect (boost::bind (NotifyNumConnectionsChanged, this , _1));
278276 uiInterface.NotifyAlertChanged .disconnect (boost::bind (NotifyAlertChanged, this , _1, _2));
279277 uiInterface.BannedListChanged .disconnect (boost::bind (BannedListChanged, this ));
278+ uiInterface.NotifyBlockTip .disconnect (boost::bind (BlockTipChanged, this , _1, _2));
280279}
0 commit comments