Skip to content

Commit 9bd1316

Browse files
committed
Merge #120: Fix multiwallet transaction notifications
2414342 refactor: qt: Use vQueueNotifications.clear() (João Barbosa) 989e579 qt: Make transaction notification queue wallet specific (João Barbosa) 7b3b230 move-only: Define TransactionNotification before TransactionTablePriv (João Barbosa) Pull request description: Currently `vQueueNotifications` holds transactions of any wallet, but the queue is dispatched on a given wallet and it assumes notifications are of that wallet. This means that some transactions can be missed if multiple wallets are loaded. Fix this by having a queue for each wallet. ACKs for top commit: jonasschnelli: utACK 2414342 hebasto: ACK 2414342, I have reviewed the code and it looks OK, I agree it can be merged. ryanofsky: Code review ACK 2414342. Only change is dropping one commit Tree-SHA512: 61beac5a16ed659e3a25ad145dbceafcef963aaf8f9838355298949ec2324e2bd760f59353cd251d30cf0334d8dc1642a1f3821d8a9eec092533b581f6ce86db
2 parents 8a48615 + 2414342 commit 9bd1316

File tree

1 file changed

+39
-36
lines changed

1 file changed

+39
-36
lines changed

src/qt/transactiontablemodel.cpp

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,30 @@ struct TxLessThan
5454
}
5555
};
5656

57+
// queue notifications to show a non freezing progress dialog e.g. for rescan
58+
struct TransactionNotification
59+
{
60+
public:
61+
TransactionNotification() {}
62+
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
63+
hash(_hash), status(_status), showTransaction(_showTransaction) {}
64+
65+
void invoke(QObject *ttm)
66+
{
67+
QString strHash = QString::fromStdString(hash.GetHex());
68+
qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
69+
bool invoked = QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
70+
Q_ARG(QString, strHash),
71+
Q_ARG(int, status),
72+
Q_ARG(bool, showTransaction));
73+
assert(invoked);
74+
}
75+
private:
76+
uint256 hash;
77+
ChangeType status;
78+
bool showTransaction;
79+
};
80+
5781
// Private implementation
5882
class TransactionTablePriv
5983
{
@@ -71,6 +95,12 @@ class TransactionTablePriv
7195
*/
7296
QList<TransactionRecord> cachedWallet;
7397

98+
bool fQueueNotifications = false;
99+
std::vector< TransactionNotification > vQueueNotifications;
100+
101+
void NotifyTransactionChanged(const uint256 &hash, ChangeType status);
102+
void ShowProgress(const std::string &title, int nProgress);
103+
74104
/* Query entire wallet anew from core.
75105
*/
76106
void refreshWallet(interfaces::Wallet& wallet)
@@ -674,34 +704,7 @@ void TransactionTableModel::updateDisplayUnit()
674704
Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount));
675705
}
676706

677-
// queue notifications to show a non freezing progress dialog e.g. for rescan
678-
struct TransactionNotification
679-
{
680-
public:
681-
TransactionNotification() {}
682-
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
683-
hash(_hash), status(_status), showTransaction(_showTransaction) {}
684-
685-
void invoke(QObject *ttm)
686-
{
687-
QString strHash = QString::fromStdString(hash.GetHex());
688-
qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
689-
bool invoked = QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
690-
Q_ARG(QString, strHash),
691-
Q_ARG(int, status),
692-
Q_ARG(bool, showTransaction));
693-
assert(invoked);
694-
}
695-
private:
696-
uint256 hash;
697-
ChangeType status;
698-
bool showTransaction;
699-
};
700-
701-
static bool fQueueNotifications = false;
702-
static std::vector< TransactionNotification > vQueueNotifications;
703-
704-
static void NotifyTransactionChanged(TransactionTableModel *ttm, const uint256 &hash, ChangeType status)
707+
void TransactionTablePriv::NotifyTransactionChanged(const uint256 &hash, ChangeType status)
705708
{
706709
// Find transaction in wallet
707710
// Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
@@ -714,10 +717,10 @@ static void NotifyTransactionChanged(TransactionTableModel *ttm, const uint256 &
714717
vQueueNotifications.push_back(notification);
715718
return;
716719
}
717-
notification.invoke(ttm);
720+
notification.invoke(parent);
718721
}
719722

720-
static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress)
723+
void TransactionTablePriv::ShowProgress(const std::string &title, int nProgress)
721724
{
722725
if (nProgress == 0)
723726
fQueueNotifications = true;
@@ -726,27 +729,27 @@ static void ShowProgress(TransactionTableModel *ttm, const std::string &title, i
726729
{
727730
fQueueNotifications = false;
728731
if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons
729-
bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
732+
bool invoked = QMetaObject::invokeMethod(parent, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
730733
assert(invoked);
731734
}
732735
for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
733736
{
734737
if (vQueueNotifications.size() - i <= 10) {
735-
bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
738+
bool invoked = QMetaObject::invokeMethod(parent, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
736739
assert(invoked);
737740
}
738741

739-
vQueueNotifications[i].invoke(ttm);
742+
vQueueNotifications[i].invoke(parent);
740743
}
741-
std::vector<TransactionNotification >().swap(vQueueNotifications); // clear
744+
vQueueNotifications.clear();
742745
}
743746
}
744747

745748
void TransactionTableModel::subscribeToCoreSignals()
746749
{
747750
// Connect signals to wallet
748-
m_handler_transaction_changed = walletModel->wallet().handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
749-
m_handler_show_progress = walletModel->wallet().handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
751+
m_handler_transaction_changed = walletModel->wallet().handleTransactionChanged(std::bind(&TransactionTablePriv::NotifyTransactionChanged, priv, std::placeholders::_1, std::placeholders::_2));
752+
m_handler_show_progress = walletModel->wallet().handleShowProgress(std::bind(&TransactionTablePriv::ShowProgress, priv, std::placeholders::_1, std::placeholders::_2));
750753
}
751754

752755
void TransactionTableModel::unsubscribeFromCoreSignals()

0 commit comments

Comments
 (0)