mirror of https://github.com/GOSTSec/gostcoin
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
7.2 KiB
252 lines
7.2 KiB
// Copyright (c) 2017-2018 The Gostcoin Developers |
|
// Distributed under the MIT/X11 software license, see the accompanying |
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php. |
|
// |
|
// I2P-patch |
|
// Copyright (c) 2012-2013 giv |
|
|
|
#include "clientmodel.h" |
|
|
|
#include "guiconstants.h" |
|
#include "optionsmodel.h" |
|
#include "addresstablemodel.h" |
|
#include "transactiontablemodel.h" |
|
|
|
#include "i2p.h" |
|
#include "net.h" |
|
|
|
#include "alert.h" |
|
#include "main.h" |
|
#include "checkpoints.h" |
|
#include "ui_interface.h" |
|
|
|
#include <QDateTime> |
|
#include <QTimer> |
|
|
|
static const int64 nClientStartupTime = GetTime(); |
|
|
|
ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : |
|
QObject(parent), optionsModel(optionsModel), |
|
cachedNumBlocks(0), cachedNumBlocksOfPeers(0), |
|
cachedReindexing(0), cachedImporting(0), |
|
numBlocksAtStartup(-1), pollTimer(0) |
|
{ |
|
pollTimer = new QTimer(this); |
|
pollTimer->setInterval(MODEL_UPDATE_DELAY); |
|
pollTimer->start(); |
|
connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); |
|
|
|
subscribeToCoreSignals(); |
|
} |
|
|
|
ClientModel::~ClientModel() |
|
{ |
|
unsubscribeFromCoreSignals(); |
|
} |
|
|
|
int ClientModel::getNumConnections() const |
|
{ |
|
return vNodes.size(); |
|
} |
|
|
|
int ClientModel::getNumBlocks() const |
|
{ |
|
return nBestHeight; |
|
} |
|
|
|
int ClientModel::getNumBlocksAtStartup() |
|
{ |
|
if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks(); |
|
return numBlocksAtStartup; |
|
} |
|
|
|
QDateTime ClientModel::getLastBlockDate() const |
|
{ |
|
if (pindexBest) |
|
return QDateTime::fromTime_t(pindexBest->GetBlockTime()); |
|
else if(!isTestNet()) |
|
return QDateTime::fromTime_t(1370190760); // Genesis block's time |
|
else |
|
return QDateTime::fromTime_t(1296688602); // Genesis block's time (testnet) |
|
} |
|
|
|
double ClientModel::getVerificationProgress() const |
|
{ |
|
return Checkpoints::GuessVerificationProgress(pindexBest); |
|
} |
|
|
|
void ClientModel::updateTimer() |
|
{ |
|
// 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(); |
|
int newNumBlocksOfPeers = getNumBlocksOfPeers(); |
|
|
|
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state |
|
if (cachedNumBlocks != newNumBlocks || cachedNumBlocksOfPeers != newNumBlocksOfPeers || |
|
cachedReindexing != fReindex || cachedImporting != fImporting) |
|
{ |
|
cachedNumBlocks = newNumBlocks; |
|
cachedNumBlocksOfPeers = newNumBlocksOfPeers; |
|
cachedReindexing = fReindex; |
|
cachedImporting = fImporting; |
|
|
|
// ensure we return the maximum of newNumBlocksOfPeers and newNumBlocks to not create weird displays in the GUI |
|
emit numBlocksChanged(newNumBlocks, std::max(newNumBlocksOfPeers, newNumBlocks)); |
|
} |
|
} |
|
|
|
void ClientModel::updateNumConnections(int numConnections) |
|
{ |
|
emit numConnectionsChanged(numConnections); |
|
} |
|
|
|
void ClientModel::updateAlert(const QString &hash, int status) |
|
{ |
|
// Show error message notification for new alert |
|
if(status == CT_NEW) |
|
{ |
|
uint256 hash_256; |
|
hash_256.SetHex(hash.toStdString()); |
|
CAlert alert = CAlert::getAlertByHash(hash_256); |
|
if(!alert.IsNull()) |
|
{ |
|
emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); |
|
} |
|
} |
|
|
|
emit alertsChanged(getStatusBarWarnings()); |
|
} |
|
|
|
QString ClientModel::formatI2PNativeFullVersion() const |
|
{ |
|
return QString::fromStdString(FormatI2PNativeFullVersion()); |
|
} |
|
|
|
void ClientModel::updateNumI2PConnections(int numI2PConnections) |
|
{ |
|
emit numI2PConnectionsChanged(numI2PConnections); |
|
} |
|
|
|
int ClientModel::getNumI2PConnections() const |
|
{ |
|
return nI2PNodeCount; |
|
} |
|
|
|
bool ClientModel::isI2POnly() const |
|
{ |
|
return IsI2POnly(); |
|
} |
|
|
|
bool ClientModel::isI2PAddressGenerated() const |
|
{ |
|
return I2PSession::Instance().getMyDestination().isGenerated; |
|
} |
|
|
|
bool ClientModel::isTestNet() const |
|
{ |
|
return fTestNet; |
|
} |
|
|
|
bool ClientModel::inInitialBlockDownload() const |
|
{ |
|
return IsInitialBlockDownload(); |
|
} |
|
|
|
enum BlockSource ClientModel::getBlockSource() const |
|
{ |
|
if (fReindex) |
|
return BLOCK_SOURCE_REINDEX; |
|
else if (fImporting) |
|
return BLOCK_SOURCE_DISK; |
|
else if (getNumConnections() > 0) |
|
return BLOCK_SOURCE_NETWORK; |
|
|
|
return BLOCK_SOURCE_NONE; |
|
} |
|
|
|
int ClientModel::getNumBlocksOfPeers() const |
|
{ |
|
return GetNumBlocksOfPeers(); |
|
} |
|
|
|
QString ClientModel::getStatusBarWarnings() const |
|
{ |
|
return QString::fromStdString(GetWarnings("statusbar")); |
|
} |
|
|
|
OptionsModel *ClientModel::getOptionsModel() |
|
{ |
|
return optionsModel; |
|
} |
|
|
|
QString ClientModel::formatFullVersion() const |
|
{ |
|
return QString::fromStdString(FormatFullVersion()); |
|
} |
|
|
|
QString ClientModel::formatBuildDate() const |
|
{ |
|
return QString::fromStdString(CLIENT_DATE); |
|
} |
|
|
|
bool ClientModel::isReleaseVersion() const |
|
{ |
|
return CLIENT_VERSION_IS_RELEASE; |
|
} |
|
|
|
QString ClientModel::clientName() const |
|
{ |
|
return QString::fromStdString(CLIENT_NAME); |
|
} |
|
|
|
QString ClientModel::formatClientStartupTime() const |
|
{ |
|
return QDateTime::fromTime_t(nClientStartupTime).toString(); |
|
} |
|
|
|
// Handlers for core signals |
|
static void NotifyBlocksChanged(ClientModel *clientmodel) |
|
{ |
|
// This notification is too frequent. Don't trigger a signal. |
|
// Don't remove it, though, as it might be useful later. |
|
} |
|
|
|
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections) |
|
{ |
|
// Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections); |
|
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, |
|
Q_ARG(int, newNumConnections)); |
|
} |
|
|
|
static void NotifyNumI2PConnectionsChanged(ClientModel *clientmodel, int newNumI2PConnections) |
|
{ |
|
QMetaObject::invokeMethod(clientmodel, "updateNumI2PConnections", Qt::QueuedConnection, |
|
Q_ARG(int, newNumI2PConnections)); |
|
} |
|
|
|
static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) |
|
{ |
|
OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status); |
|
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection, |
|
Q_ARG(QString, QString::fromStdString(hash.GetHex())), |
|
Q_ARG(int, status)); |
|
} |
|
|
|
void ClientModel::subscribeToCoreSignals() |
|
{ |
|
// Connect signals to client |
|
uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this)); |
|
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); |
|
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); |
|
uiInterface.NotifyNumI2PConnectionsChanged.connect(boost::bind(NotifyNumI2PConnectionsChanged, this, _1)); |
|
} |
|
|
|
void ClientModel::unsubscribeFromCoreSignals() |
|
{ |
|
// Disconnect signals from client |
|
uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this)); |
|
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); |
|
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); |
|
uiInterface.NotifyNumI2PConnectionsChanged.disconnect(boost::bind(NotifyNumI2PConnectionsChanged, this, _1)); |
|
}
|
|
|