@ -22,17 +22,16 @@
# include <QDebug>
# include <QDebug>
# include <QTimer>
# include <QTimer>
class CBlockIndex ;
static const int64_t nClientStartupTime = GetTime ( ) ;
static const int64_t nClientStartupTime = GetTime ( ) ;
static int64_t nLastBlockTipUpdateNotification = 0 ;
ClientModel : : ClientModel ( OptionsModel * optionsModel , QObject * parent ) :
ClientModel : : ClientModel ( OptionsModel * optionsModel , QObject * parent ) :
QObject ( parent ) ,
QObject ( parent ) ,
optionsModel ( optionsModel ) ,
optionsModel ( optionsModel ) ,
peerTableModel ( 0 ) ,
peerTableModel ( 0 ) ,
banTableModel ( 0 ) ,
banTableModel ( 0 ) ,
cachedNumBlocks ( 0 ) ,
cachedBlockDate ( QDateTime ( ) ) ,
cachedReindexing ( 0 ) ,
cachedImporting ( 0 ) ,
pollTimer ( 0 )
pollTimer ( 0 )
{
{
peerTableModel = new PeerTableModel ( this ) ;
peerTableModel = new PeerTableModel ( this ) ;
@ -99,40 +98,21 @@ size_t ClientModel::getMempoolDynamicUsage() const
return mempool . DynamicMemoryUsage ( ) ;
return mempool . DynamicMemoryUsage ( ) ;
}
}
double ClientModel : : getVerificationProgress ( ) const
double ClientModel : : getVerificationProgress ( const CBlockIndex * tipIn ) const
{
CBlockIndex * tip = const_cast < CBlockIndex * > ( tipIn ) ;
if ( ! tip )
{
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
return Checkpoints : : GuessVerificationProgress ( Params ( ) . Checkpoints ( ) , chainActive . Tip ( ) ) ;
tip = chainActive . Tip ( ) ;
}
return Checkpoints : : GuessVerificationProgress ( Params ( ) . Checkpoints ( ) , tip ) ;
}
}
void ClientModel : : updateTimer ( )
void ClientModel : : updateTimer ( )
{
{
// Get required lock upfront. This avoids the GUI from getting stuck on
// no locking required at this point
// periodical polls if the core is holding the locks for a longer time -
// the following calls will aquire the required lock
// for example, during a wallet rescan.
TRY_LOCK ( cs_main , lockMain ) ;
if ( ! lockMain )
return ;
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
// Periodically check and update with a timer.
int newNumBlocks = getNumBlocks ( ) ;
QDateTime newBlockDate = getLastBlockDate ( ) ;
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
if ( cachedNumBlocks ! = newNumBlocks | |
cachedBlockDate ! = newBlockDate | |
cachedReindexing ! = fReindex | |
cachedImporting ! = fImporting )
{
cachedNumBlocks = newNumBlocks ;
cachedBlockDate = newBlockDate ;
cachedReindexing = fReindex ;
cachedImporting = fImporting ;
Q_EMIT numBlocksChanged ( newNumBlocks , newBlockDate ) ;
}
Q_EMIT mempoolSizeChanged ( getMempoolSize ( ) , getMempoolDynamicUsage ( ) ) ;
Q_EMIT mempoolSizeChanged ( getMempoolSize ( ) , getMempoolDynamicUsage ( ) ) ;
Q_EMIT bytesChanged ( getTotalBytesRecv ( ) , getTotalBytesSent ( ) ) ;
Q_EMIT bytesChanged ( getTotalBytesRecv ( ) , getTotalBytesSent ( ) ) ;
}
}
@ -261,6 +241,23 @@ static void BannedListChanged(ClientModel *clientmodel)
QMetaObject : : invokeMethod ( clientmodel , " updateBanlist " , Qt : : QueuedConnection ) ;
QMetaObject : : invokeMethod ( clientmodel , " updateBanlist " , Qt : : QueuedConnection ) ;
}
}
static void BlockTipChanged ( ClientModel * clientmodel , bool initialSync , const CBlockIndex * pIndex )
{
// lock free async UI updates in case we have a new block tip
// during initial sync, only update the UI if the last update
// was > 250ms (MODEL_UPDATE_DELAY) ago
int64_t now = 0 ;
if ( initialSync )
now = GetTimeMillis ( ) ;
// if we are in-sync, update the UI regardless of last update time
if ( ! initialSync | | now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY ) {
//pass a async signal to the UI thread
Q_EMIT clientmodel - > numBlocksChanged ( pIndex - > nHeight , QDateTime : : fromTime_t ( pIndex - > GetBlockTime ( ) ) , clientmodel - > getVerificationProgress ( pIndex ) ) ;
nLastBlockTipUpdateNotification = now ;
}
}
void ClientModel : : subscribeToCoreSignals ( )
void ClientModel : : subscribeToCoreSignals ( )
{
{
// Connect signals to client
// Connect signals to client
@ -268,6 +265,7 @@ void ClientModel::subscribeToCoreSignals()
uiInterface . NotifyNumConnectionsChanged . connect ( boost : : bind ( NotifyNumConnectionsChanged , this , _1 ) ) ;
uiInterface . NotifyNumConnectionsChanged . connect ( boost : : bind ( NotifyNumConnectionsChanged , this , _1 ) ) ;
uiInterface . NotifyAlertChanged . connect ( boost : : bind ( NotifyAlertChanged , this , _1 , _2 ) ) ;
uiInterface . NotifyAlertChanged . connect ( boost : : bind ( NotifyAlertChanged , this , _1 , _2 ) ) ;
uiInterface . BannedListChanged . connect ( boost : : bind ( BannedListChanged , this ) ) ;
uiInterface . BannedListChanged . connect ( boost : : bind ( BannedListChanged , this ) ) ;
uiInterface . NotifyBlockTip . connect ( boost : : bind ( BlockTipChanged , this , _1 , _2 ) ) ;
}
}
void ClientModel : : unsubscribeFromCoreSignals ( )
void ClientModel : : unsubscribeFromCoreSignals ( )
@ -277,4 +275,5 @@ void ClientModel::unsubscribeFromCoreSignals()
uiInterface . NotifyNumConnectionsChanged . disconnect ( boost : : bind ( NotifyNumConnectionsChanged , this , _1 ) ) ;
uiInterface . NotifyNumConnectionsChanged . disconnect ( boost : : bind ( NotifyNumConnectionsChanged , this , _1 ) ) ;
uiInterface . NotifyAlertChanged . disconnect ( boost : : bind ( NotifyAlertChanged , this , _1 , _2 ) ) ;
uiInterface . NotifyAlertChanged . disconnect ( boost : : bind ( NotifyAlertChanged , this , _1 , _2 ) ) ;
uiInterface . BannedListChanged . disconnect ( boost : : bind ( BannedListChanged , this ) ) ;
uiInterface . BannedListChanged . disconnect ( boost : : bind ( BannedListChanged , this ) ) ;
uiInterface . NotifyBlockTip . disconnect ( boost : : bind ( BlockTipChanged , this , _1 , _2 ) ) ;
}
}