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