aboutsummaryrefslogtreecommitdiff
path: root/src/libwalletqt/Wallet.cpp
diff options
context:
space:
mode:
authorxiphon <xiphon@protonmail.com>2020-10-09 12:04:53 +0000
committerxiphon <xiphon@protonmail.com>2020-10-09 14:11:05 +0000
commit39d9d7d071dd9ed7a942578a7db520ac0ec08f5e (patch)
treece1d65d44cddca4e5860fcb08a0f1a7ff0ff56fd /src/libwalletqt/Wallet.cpp
parentd3943ca2a9e1fa27ec9141ed94e1d4fb530aca31 (diff)
downloadmonzero-gui-39d9d7d071dd9ed7a942578a7db520ac0ec08f5e.tar.gz
monzero-gui-39d9d7d071dd9ed7a942578a7db520ac0ec08f5e.tar.xz
monzero-gui-39d9d7d071dd9ed7a942578a7db520ac0ec08f5e.zip
Wallet: rework wallet refreshing
Diffstat (limited to 'src/libwalletqt/Wallet.cpp')
-rw-r--r--src/libwalletqt/Wallet.cpp107
1 files changed, 79 insertions, 28 deletions
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index 508f105e..454dca29 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -27,6 +27,11 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Wallet.h"
+
+#include <chrono>
+#include <stdexcept>
+#include <thread>
+
#include "PendingTransaction.h"
#include "UnsignedTransaction.h"
#include "TransactionHistory.h"
@@ -50,6 +55,8 @@
#include <QVector>
#include <QMutexLocker>
+#include "qt/ScopeGuard.h"
+
namespace {
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 5;
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 30;
@@ -124,6 +131,19 @@ bool Wallet::disconnected() const
return m_disconnected;
}
+bool Wallet::refreshing() const
+{
+ return m_refreshing;
+}
+
+void Wallet::refreshingSet(bool value)
+{
+ if (m_refreshing.exchange(value) != value)
+ {
+ emit refreshingChanged();
+ }
+}
+
void Wallet::setConnectionStatus(ConnectionStatus value)
{
if (m_connectionStatus == value)
@@ -196,7 +216,7 @@ void Wallet::storeAsync(const QJSValue &callback, const QString &path /* = "" */
{
const auto future = m_scheduler.run(
[this, path] {
- QMutexLocker locker(&m_storeMutex);
+ QMutexLocker locker(&m_asyncMutex);
return QJSValueList({m_walletImpl->store(path.toStdString())});
},
@@ -263,7 +283,7 @@ void Wallet::initAsync(
emit walletCreationHeightChanged();
qDebug() << "init async finished - starting refresh";
connected(true);
- m_walletImpl->startRefresh();
+ startRefresh();
}
});
if (future.first)
@@ -466,41 +486,37 @@ bool Wallet::importKeyImages(const QString& path)
return m_walletImpl->importKeyImages(path.toStdString());
}
-bool Wallet::refresh()
-{
- bool result = m_walletImpl->refresh();
- m_history->refresh(currentSubaddressAccount());
- m_subaddress->refresh(currentSubaddressAccount());
- m_subaddressAccount->getAll();
- if (result)
- emit updated();
- return result;
-}
-
-void Wallet::refreshAsync()
+bool Wallet::refresh(bool historyAndSubaddresses /* = true */)
{
- qDebug() << "refresh async";
- m_walletImpl->refreshAsync();
-}
+ refreshingSet(true);
+ const auto cleanup = sg::make_scope_guard([this]() noexcept {
+ refreshingSet(false);
+ });
-void Wallet::setAutoRefreshInterval(int seconds)
-{
- m_walletImpl->setAutoRefreshInterval(seconds);
-}
+ {
+ QMutexLocker locker(&m_asyncMutex);
-int Wallet::autoRefreshInterval() const
-{
- return m_walletImpl->autoRefreshInterval();
+ bool result = m_walletImpl->refresh();
+ if (historyAndSubaddresses)
+ {
+ m_history->refresh(currentSubaddressAccount());
+ m_subaddress->refresh(currentSubaddressAccount());
+ m_subaddressAccount->getAll();
+ }
+ if (result)
+ emit updated();
+ return result;
+ }
}
-void Wallet::startRefresh() const
+void Wallet::startRefresh()
{
- m_walletImpl->startRefresh();
+ m_refreshEnabled = true;
}
-void Wallet::pauseRefresh() const
+void Wallet::pauseRefresh()
{
- m_walletImpl->pauseRefresh();
+ m_refreshEnabled = false;
}
PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QString &payment_id,
@@ -874,6 +890,8 @@ bool Wallet::parse_uri(const QString &uri, QString &address, QString &payment_id
bool Wallet::rescanSpent()
{
+ QMutexLocker locker(&m_asyncMutex);
+
return m_walletImpl->rescanSpent();
}
@@ -1041,6 +1059,8 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
, m_subaddressModel(nullptr)
, m_subaddressAccount(nullptr)
, m_subaddressAccountModel(nullptr)
+ , m_refreshEnabled(false)
+ , m_refreshing(false)
, m_scheduler(this)
{
m_history = new TransactionHistory(m_walletImpl->history(), this);
@@ -1058,6 +1078,8 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
m_connectionStatusRunning = false;
m_daemonUsername = "";
m_daemonPassword = "";
+
+ startRefreshThread();
}
Wallet::~Wallet()
@@ -1090,3 +1112,32 @@ Wallet::~Wallet()
m_walletListener = NULL;
qDebug("m_walletImpl deleted");
}
+
+void Wallet::startRefreshThread()
+{
+ const auto future = m_scheduler.run([this] {
+ static constexpr const size_t refreshIntervalSec = 10;
+ static constexpr const size_t intervalResolutionMs = 100;
+
+ auto last = std::chrono::steady_clock::now();
+ while (!m_scheduler.stopping())
+ {
+ if (m_refreshEnabled)
+ {
+ const auto now = std::chrono::steady_clock::now();
+ const auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - last).count();
+ if (elapsed >= refreshIntervalSec)
+ {
+ refresh(false);
+ last = std::chrono::steady_clock::now();
+ }
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(intervalResolutionMs));
+ }
+ });
+ if (!future.first)
+ {
+ throw std::runtime_error("failed to start auto refresh thread");
+ }
+}