From d013cb4f5cf7627f75241a4a6bbfe345dd8a2dd1 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 22 Jun 2023 13:41:44 +0300 Subject: [PATCH 1/2] feat(gui): refresh the whole wallet instead of processing individual updates for huge notification queues --- src/qt/transactiontablemodel.cpp | 31 ++++++++++++++++++++++--------- src/qt/transactiontablemodel.h | 2 ++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index ba076a4aea0bc..5668838238d36 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -74,6 +74,7 @@ class TransactionTablePriv void refreshWallet(interfaces::Wallet& wallet) { qDebug() << "TransactionTablePriv::refreshWallet"; + parent->beginResetModel(); cachedWallet.clear(); { for (const auto& wtx : wallet.getWalletTxs()) { @@ -82,6 +83,7 @@ class TransactionTablePriv } } } + parent->endResetModel(); } /* Update our model of the wallet incrementally, to synchronize our model of the wallet @@ -244,6 +246,11 @@ TransactionTableModel::~TransactionTableModel() delete priv; } +void TransactionTableModel::refreshWallet() +{ + priv->refreshWallet(walletModel->wallet()); +} + /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ void TransactionTableModel::updateAmountColumnTitle() { @@ -803,18 +810,24 @@ static void ShowProgress(TransactionTableModel *ttm, const std::string &title, i if (nProgress == 100) { fQueueNotifications = false; - if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons - bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); - assert(invoked); - } - for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) - { - if (vQueueNotifications.size() - i <= 10) { - bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); + if (vQueueNotifications.size() < 10000) { + if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons + bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); assert(invoked); } + for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) + { + if (vQueueNotifications.size() - i <= 10) { + bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); + assert(invoked); + } - vQueueNotifications[i].invoke(ttm); + vQueueNotifications[i].invoke(ttm); + } + } else { + // it's much faster to just refresh the whole thing instead + bool invoked = QMetaObject::invokeMethod(ttm, "refreshWallet", Qt::QueuedConnection); + assert(invoked); } std::vector().swap(vQueueNotifications); // clear } diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 5d1f6aadc1e74..16e85b935ea06 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -113,6 +113,8 @@ class TransactionTableModel : public QAbstractTableModel QVariant txAddressDecoration(const TransactionRecord *wtx) const; public Q_SLOTS: + /* Refresh the whole wallet, helpful for huge notification queues */ + void refreshWallet(); /* New transaction, or transaction changed status */ void updateTransaction(const QString &hash, int status, bool showTransaction); void updateAddressBook(const QString &address, const QString &label, From 3ccd0a567fbfbcc1310f031f7d60f78c5d8139b6 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 26 Jun 2023 23:02:21 +0300 Subject: [PATCH 2/2] fix: wrap in try/catch, show an error message when an exception is caught --- src/qt/transactiontablemodel.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 5668838238d36..9dc74a7ed7e5f 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -23,6 +23,7 @@ #include #include #include +#include // Amount column is right-aligned it contains numbers @@ -75,13 +76,15 @@ class TransactionTablePriv { qDebug() << "TransactionTablePriv::refreshWallet"; parent->beginResetModel(); - cachedWallet.clear(); - { + try { + cachedWallet.clear(); for (const auto& wtx : wallet.getWalletTxs()) { if (TransactionRecord::showTransaction()) { cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, wtx)); } } + } catch(const std::exception& e) { + QMessageBox::critical(nullptr, PACKAGE_NAME, QString("Failed to refresh wallet table: ") + QString::fromStdString(e.what())); } parent->endResetModel(); }