async connectionStatus and init

This commit is contained in:
Jaquee 2017-01-31 10:32:41 +01:00
parent cb3281dee8
commit eb909e1ae7
2 changed files with 73 additions and 21 deletions

View File

@ -16,6 +16,8 @@
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QList> #include <QList>
#include <QVector> #include <QVector>
#include <QMutex>
#include <QMutexLocker>
namespace { namespace {
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 10; static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 10;
@ -54,7 +56,7 @@ public:
virtual void newBlock(uint64_t height) virtual void newBlock(uint64_t height)
{ {
// qDebug() << __FUNCTION__; // qDebug() << __FUNCTION__;
emit m_wallet->newBlock(height); emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
} }
virtual void updated() virtual void updated()
@ -103,17 +105,35 @@ bool Wallet::testnet() const
return m_walletImpl->testnet(); return m_walletImpl->testnet();
} }
Wallet::ConnectionStatus Wallet::connected() const
void Wallet::updateConnectionStatusAsync()
{ {
// cache connection status QFuture<Monero::Wallet::ConnectionStatus> future = QtConcurrent::run(m_walletImpl, &Monero::Wallet::connected);
if (!m_initialized || m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl) { QFutureWatcher<Monero::Wallet::ConnectionStatus> *connectionWatcher = new QFutureWatcher<Monero::Wallet::ConnectionStatus>();
m_initialized = true;
ConnectionStatus newStatus = static_cast<ConnectionStatus>(m_walletImpl->connected()); connect(connectionWatcher, &QFutureWatcher<Monero::Wallet::ConnectionStatus>::finished, [=]() {
QFuture<Monero::Wallet::ConnectionStatus> future = connectionWatcher->future();
connectionWatcher->deleteLater();
ConnectionStatus newStatus = static_cast<ConnectionStatus>(future.result());
if (newStatus != m_connectionStatus) { if (newStatus != m_connectionStatus) {
m_connectionStatus = newStatus; m_connectionStatus = newStatus;
emit connectionStatusChanged(); emit connectionStatusChanged(newStatus);
} }
// Release lock
m_connectionStatusRunning = false;
});
connectionWatcher->setFuture(future);
}
Wallet::ConnectionStatus Wallet::connected(bool forceCheck)
{
qDebug() << "Checking connection status";
// cache connection status
if (forceCheck || !m_initialized || (m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl && !m_connectionStatusRunning) || m_connectionStatusTime.elapsed() > 30000) {
m_connectionStatusRunning = true;
m_initialized = true;
m_connectionStatusTime.restart(); m_connectionStatusTime.restart();
updateConnectionStatusAsync();
} }
return m_connectionStatus; return m_connectionStatus;
@ -151,17 +171,38 @@ bool Wallet::store(const QString &path)
bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight) bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight)
{ {
return m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit); qDebug() << "init non async";
}
void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight)
{
if (isRecovering){ if (isRecovering){
qDebug() << "RESTORING"; qDebug() << "RESTORING";
m_walletImpl->setRecoveringFromSeed(true); m_walletImpl->setRecoveringFromSeed(true);
m_walletImpl->setRefreshFromBlockHeight(restoreHeight); m_walletImpl->setRefreshFromBlockHeight(restoreHeight);
} }
m_walletImpl->initAsync(daemonAddress.toStdString(), upperTransactionLimit); m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit);
return true;
}
void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight)
{
qDebug() << "initAsync: " + daemonAddress;
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
emit connectionStatusChanged(m_connectionStatus);
QFuture<bool> future = QtConcurrent::run(this, &Wallet::init,
daemonAddress, upperTransactionLimit, isRecovering, restoreHeight);
QFutureWatcher<bool> * watcher = new QFutureWatcher<bool>();
connect(watcher, &QFutureWatcher<bool>::finished,
this, [this, watcher, daemonAddress, upperTransactionLimit, isRecovering, restoreHeight]() {
QFuture<bool> future = watcher->future();
watcher->deleteLater();
if(future.result()){
qDebug() << "init async finished - starting refresh";
connected(true);
m_walletImpl->startRefresh();
}
});
watcher->setFuture(future);
} }
//! create a view only wallet //! create a view only wallet
@ -220,6 +261,7 @@ quint64 Wallet::daemonBlockChainTargetHeight() const
if (m_daemonBlockChainTargetHeight == 0 if (m_daemonBlockChainTargetHeight == 0
|| m_daemonBlockChainTargetHeightTime.elapsed() / 1000 > m_daemonBlockChainTargetHeightTtl) { || m_daemonBlockChainTargetHeightTime.elapsed() / 1000 > m_daemonBlockChainTargetHeightTtl) {
m_daemonBlockChainTargetHeight = m_walletImpl->daemonBlockChainTargetHeight(); m_daemonBlockChainTargetHeight = m_walletImpl->daemonBlockChainTargetHeight();
// Target height is set to 0 if daemon is synced. // Target height is set to 0 if daemon is synced.
// Use current height from daemon when target height < current height // Use current height from daemon when target height < current height
if (m_daemonBlockChainTargetHeight < m_daemonBlockChainHeight){ if (m_daemonBlockChainTargetHeight < m_daemonBlockChainHeight){
@ -242,6 +284,7 @@ bool Wallet::refresh()
void Wallet::refreshAsync() void Wallet::refreshAsync()
{ {
qDebug() << "refresh async";
m_walletImpl->refreshAsync(); m_walletImpl->refreshAsync();
} }
@ -273,13 +316,14 @@ void Wallet::createTransactionAsync(const QString &dst_addr, const QString &paym
QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransaction, QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransaction,
dst_addr, payment_id,amount, mixin_count, priority); dst_addr, payment_id,amount, mixin_count, priority);
QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>(); QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<PendingTransaction*>::finished, connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
this, [this, watcher,dst_addr,payment_id,mixin_count]() { this, [this, watcher,dst_addr,payment_id,mixin_count]() {
QFuture<PendingTransaction*> future = watcher->future(); QFuture<PendingTransaction*> future = watcher->future();
watcher->deleteLater(); watcher->deleteLater();
emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count); emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count);
}); });
watcher->setFuture(future);
} }
PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id, PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id,
@ -299,13 +343,14 @@ void Wallet::createTransactionAllAsync(const QString &dst_addr, const QString &p
QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransactionAll, QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransactionAll,
dst_addr, payment_id, mixin_count, priority); dst_addr, payment_id, mixin_count, priority);
QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>(); QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<PendingTransaction*>::finished, connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
this, [this, watcher,dst_addr,payment_id,mixin_count]() { this, [this, watcher,dst_addr,payment_id,mixin_count]() {
QFuture<PendingTransaction*> future = watcher->future(); QFuture<PendingTransaction*> future = watcher->future();
watcher->deleteLater(); watcher->deleteLater();
emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count); emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count);
}); });
watcher->setFuture(future);
} }
PendingTransaction *Wallet::createSweepUnmixableTransaction() PendingTransaction *Wallet::createSweepUnmixableTransaction()
@ -319,13 +364,14 @@ void Wallet::createSweepUnmixableTransactionAsync()
{ {
QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createSweepUnmixableTransaction); QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createSweepUnmixableTransaction);
QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>(); QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<PendingTransaction*>::finished, connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
this, [this, watcher]() { this, [this, watcher]() {
QFuture<PendingTransaction*> future = watcher->future(); QFuture<PendingTransaction*> future = watcher->future();
watcher->deleteLater(); watcher->deleteLater();
emit transactionCreated(future.result(),"","",0); emit transactionCreated(future.result(),"","",0);
}); });
watcher->setFuture(future);
} }
UnsignedTransaction * Wallet::loadTxFile(const QString &fileName) UnsignedTransaction * Wallet::loadTxFile(const QString &fileName)
@ -542,6 +588,7 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
m_daemonBlockChainHeightTime.restart(); m_daemonBlockChainHeightTime.restart();
m_daemonBlockChainTargetHeightTime.restart(); m_daemonBlockChainTargetHeightTime.restart();
m_initialized = false; m_initialized = false;
m_connectionStatusRunning = false;
} }
Wallet::~Wallet() Wallet::~Wallet()

View File

@ -3,6 +3,8 @@
#include <QObject> #include <QObject>
#include <QTime> #include <QTime>
#include <QMutex>
#include <QtConcurrent/QtConcurrent>
#include "wallet/wallet2_api.h" // we need to have an access to the Monero::Wallet::Status enum here; #include "wallet/wallet2_api.h" // we need to have an access to the Monero::Wallet::Status enum here;
#include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here; #include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here;
@ -75,7 +77,8 @@ public:
bool testnet() const; bool testnet() const;
//! returns whether the wallet is connected, and version status //! returns whether the wallet is connected, and version status
ConnectionStatus connected() const; ConnectionStatus connected(bool forceCheck = false);
void updateConnectionStatusAsync();
//! returns true if wallet was ever synchronized //! returns true if wallet was ever synchronized
bool synchronized() const; bool synchronized() const;
@ -98,10 +101,10 @@ public:
Q_INVOKABLE bool store(const QString &path = ""); Q_INVOKABLE bool store(const QString &path = "");
//! initializes wallet //! initializes wallet
Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering = false, quint64 restoreHeight = 0); Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit = 0, bool isRecovering = false, quint64 restoreHeight = 0);
//! initializes wallet asynchronously //! initializes wallet asynchronously
Q_INVOKABLE void initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering = false, quint64 restoreHeight = 0); Q_INVOKABLE void initAsync(const QString &daemonAddress, quint64 upperTransactionLimit = 0, bool isRecovering = false, quint64 restoreHeight = 0);
//! create a view only wallet //! create a view only wallet
Q_INVOKABLE bool createViewOnly(const QString &path, const QString &password) const; Q_INVOKABLE bool createViewOnly(const QString &path, const QString &password) const;
@ -231,13 +234,13 @@ signals:
void moneySpent(const QString &txId, quint64 amount); void moneySpent(const QString &txId, quint64 amount);
void moneyReceived(const QString &txId, quint64 amount); void moneyReceived(const QString &txId, quint64 amount);
void unconfirmedMoneyReceived(const QString &txId, quint64 amount); void unconfirmedMoneyReceived(const QString &txId, quint64 amount);
void newBlock(quint64 height); void newBlock(quint64 height, quint64 targetHeight);
void historyModelChanged() const; void historyModelChanged() const;
// emitted when transaction is created async // emitted when transaction is created async
void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount); void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount);
void connectionStatusChanged() const; void connectionStatusChanged(ConnectionStatus status) const;
private: private:
Wallet(QObject * parent = nullptr); Wallet(QObject * parent = nullptr);
@ -266,6 +269,8 @@ private:
mutable bool m_initialized; mutable bool m_initialized;
AddressBook * m_addressBook; AddressBook * m_addressBook;
mutable AddressBookModel * m_addressBookModel; mutable AddressBookModel * m_addressBookModel;
QMutex m_connectionStatusMutex;
bool m_connectionStatusRunning;
}; };