Skip to content

Commit 3eb8b1c

Browse files
author
MarcoFalke
committed
Merge #17905: gui: Avoid redundant tx status updates
96cb597 gui: Avoid redundant tx status updates (Russell Yanofsky) Pull request description: This PR is part of the [process separation project](https://github.com/bitcoin/bitcoin/projects/10). In `TransactionTablePriv::index`, avoid calling `interfaces::Wallet::tryGetTxStatus` if the status is up to date as of the most recent `NotifyBlockTip` notification. Store height from the most recent notification in a new `ClientModel::cachedNumBlocks` variable in order to check this. This avoids floods of IPC traffic from `tryGetTxStatus` with #10102 when there are a lot of transactions. It might also make the GUI a little more efficient even when there is no IPC. ACKs for top commit: promag: Code review ACK 96cb597. hebasto: ACK 96cb597 Tree-SHA512: fce597bf52a813ad4923110d0a39229ea09e1631e0d580ea18cffb09e58cdbb4b111a40a9a9270ff16d8163cd47b0bd9f1fe7e3a6c7ebb19198f049f8dd1aa46
2 parents 7591759 + 96cb597 commit 3eb8b1c

10 files changed

+46
-16
lines changed

src/qt/bitcoin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ void BitcoinApplication::initializeResult(bool success)
336336
window->setClientModel(clientModel);
337337
#ifdef ENABLE_WALLET
338338
if (WalletModel::isWalletEnabled()) {
339-
m_wallet_controller = new WalletController(m_node, platformStyle, optionsModel, this);
339+
m_wallet_controller = new WalletController(*clientModel, platformStyle, this);
340340
window->setWalletController(m_wallet_controller);
341341
if (paymentServer) {
342342
paymentServer->setOptionsModel(optionsModel);

src/qt/clientmodel.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ int64_t ClientModel::getHeaderTipTime() const
105105
return cachedBestHeaderTime;
106106
}
107107

108+
int ClientModel::getNumBlocks() const
109+
{
110+
if (m_cached_num_blocks == -1) {
111+
m_cached_num_blocks = m_node.getNumBlocks();
112+
}
113+
return m_cached_num_blocks;
114+
}
115+
108116
void ClientModel::updateNumConnections(int numConnections)
109117
{
110118
Q_EMIT numConnectionsChanged(numConnections);
@@ -241,6 +249,8 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int heig
241249
// cache best headers time and height to reduce future cs_main locks
242250
clientmodel->cachedBestHeaderHeight = height;
243251
clientmodel->cachedBestHeaderTime = blockTime;
252+
} else {
253+
clientmodel->m_cached_num_blocks = height;
244254
}
245255

246256
// During initial sync, block notifications, and header notifications from reindexing are both throttled.

src/qt/clientmodel.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class ClientModel : public QObject
5656

5757
//! Return number of connections, default is in- and outbound (total)
5858
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
59+
int getNumBlocks() const;
5960
int getHeaderTipHeight() const;
6061
int64_t getHeaderTipTime() const;
6162

@@ -73,9 +74,10 @@ class ClientModel : public QObject
7374

7475
bool getProxyInfo(std::string& ip_port) const;
7576

76-
// caches for the best header
77+
// caches for the best header, number of blocks
7778
mutable std::atomic<int> cachedBestHeaderHeight;
7879
mutable std::atomic<int64_t> cachedBestHeaderTime;
80+
mutable std::atomic<int> m_cached_num_blocks{-1};
7981

8082
private:
8183
interfaces::Node& m_node;

src/qt/test/addressbooktests.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <interfaces/chain.h>
1010
#include <interfaces/node.h>
11+
#include <qt/clientmodel.h>
1112
#include <qt/editaddressdialog.h>
1213
#include <qt/optionsmodel.h>
1314
#include <qt/platformstyle.h>
@@ -106,8 +107,9 @@ void TestAddAddressesToSendBook(interfaces::Node& node)
106107
// Initialize relevant QT models.
107108
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
108109
OptionsModel optionsModel(node);
110+
ClientModel clientModel(node, &optionsModel);
109111
AddWallet(wallet);
110-
WalletModel walletModel(interfaces::MakeWallet(wallet), node, platformStyle.get(), &optionsModel);
112+
WalletModel walletModel(interfaces::MakeWallet(wallet), clientModel, platformStyle.get());
111113
RemoveWallet(wallet);
112114
EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress);
113115
editAddressDialog.setModel(walletModel.getAddressTableModel());

src/qt/test/wallettests.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <interfaces/chain.h>
99
#include <interfaces/node.h>
1010
#include <qt/bitcoinamountfield.h>
11+
#include <qt/clientmodel.h>
1112
#include <qt/optionsmodel.h>
1213
#include <qt/platformstyle.h>
1314
#include <qt/qvalidatedlineedit.h>
@@ -168,8 +169,9 @@ void TestGUI(interfaces::Node& node)
168169
SendCoinsDialog sendCoinsDialog(platformStyle.get());
169170
TransactionView transactionView(platformStyle.get());
170171
OptionsModel optionsModel(node);
172+
ClientModel clientModel(node, &optionsModel);
171173
AddWallet(wallet);
172-
WalletModel walletModel(interfaces::MakeWallet(wallet), node, platformStyle.get(), &optionsModel);
174+
WalletModel walletModel(interfaces::MakeWallet(wallet), clientModel, platformStyle.get());
173175
RemoveWallet(wallet);
174176
sendCoinsDialog.setModel(&walletModel);
175177
transactionView.setModel(&walletModel);

src/qt/transactiontablemodel.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <qt/transactiontablemodel.h>
66

77
#include <qt/addresstablemodel.h>
8+
#include <qt/clientmodel.h>
89
#include <qt/guiconstants.h>
910
#include <qt/guiutil.h>
1011
#include <qt/optionsmodel.h>
@@ -175,7 +176,7 @@ class TransactionTablePriv
175176
return cachedWallet.size();
176177
}
177178

178-
TransactionRecord *index(interfaces::Wallet& wallet, int idx)
179+
TransactionRecord *index(interfaces::Wallet& wallet, const int cur_num_blocks, const int idx)
179180
{
180181
if(idx >= 0 && idx < cachedWallet.size())
181182
{
@@ -191,7 +192,7 @@ class TransactionTablePriv
191192
interfaces::WalletTxStatus wtx;
192193
int numBlocks;
193194
int64_t block_time;
194-
if (wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time) && rec->statusUpdateNeeded(numBlocks)) {
195+
if (rec->statusUpdateNeeded(cur_num_blocks) && wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time)) {
195196
rec->updateStatus(wtx, numBlocks, block_time);
196197
}
197198
return rec;
@@ -663,10 +664,10 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
663664
QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
664665
{
665666
Q_UNUSED(parent);
666-
TransactionRecord *data = priv->index(walletModel->wallet(), row);
667+
TransactionRecord *data = priv->index(walletModel->wallet(), walletModel->clientModel().getNumBlocks(), row);
667668
if(data)
668669
{
669-
return createIndex(row, column, priv->index(walletModel->wallet(), row));
670+
return createIndex(row, column, data);
670671
}
671672
return QModelIndex();
672673
}

src/qt/walletcontroller.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <qt/walletcontroller.h>
66

77
#include <qt/askpassphrasedialog.h>
8+
#include <qt/clientmodel.h>
89
#include <qt/createwalletdialog.h>
910
#include <qt/guiconstants.h>
1011
#include <qt/guiutil.h>
@@ -24,13 +25,14 @@
2425
#include <QTimer>
2526
#include <QWindow>
2627

27-
WalletController::WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent)
28+
WalletController::WalletController(ClientModel& client_model, const PlatformStyle* platform_style, QObject* parent)
2829
: QObject(parent)
2930
, m_activity_thread(new QThread(this))
3031
, m_activity_worker(new QObject)
31-
, m_node(node)
32+
, m_client_model(client_model)
33+
, m_node(client_model.node())
3234
, m_platform_style(platform_style)
33-
, m_options_model(options_model)
35+
, m_options_model(client_model.getOptionsModel())
3436
{
3537
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
3638
getOrCreateWallet(std::move(wallet));
@@ -104,7 +106,7 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wal
104106
}
105107

106108
// Instantiate model and register it.
107-
WalletModel* wallet_model = new WalletModel(std::move(wallet), m_node, m_platform_style, m_options_model, nullptr);
109+
WalletModel* wallet_model = new WalletModel(std::move(wallet), m_client_model, m_platform_style, nullptr);
108110
// Handler callback runs in a different thread so fix wallet model thread affinity.
109111
wallet_model->moveToThread(thread());
110112
wallet_model->setParent(this);

src/qt/walletcontroller.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <QTimer>
2222
#include <QString>
2323

24+
class ClientModel;
2425
class OptionsModel;
2526
class PlatformStyle;
2627
class WalletModel;
@@ -47,7 +48,7 @@ class WalletController : public QObject
4748
void removeAndDeleteWallet(WalletModel* wallet_model);
4849

4950
public:
50-
WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent);
51+
WalletController(ClientModel& client_model, const PlatformStyle* platform_style, QObject* parent);
5152
~WalletController();
5253

5354
//! Returns wallet models currently open.
@@ -70,6 +71,7 @@ class WalletController : public QObject
7071
private:
7172
QThread* const m_activity_thread;
7273
QObject* const m_activity_worker;
74+
ClientModel& m_client_model;
7375
interfaces::Node& m_node;
7476
const PlatformStyle* const m_platform_style;
7577
OptionsModel* const m_options_model;

src/qt/walletmodel.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <qt/walletmodel.h>
1010

1111
#include <qt/addresstablemodel.h>
12+
#include <qt/clientmodel.h>
1213
#include <qt/guiconstants.h>
1314
#include <qt/guiutil.h>
1415
#include <qt/optionsmodel.h>
@@ -34,8 +35,13 @@
3435
#include <QTimer>
3536

3637

37-
WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *_optionsModel, QObject *parent) :
38-
QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(nullptr),
38+
WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent) :
39+
QObject(parent),
40+
m_wallet(std::move(wallet)),
41+
m_client_model(client_model),
42+
m_node(client_model.node()),
43+
optionsModel(client_model.getOptionsModel()),
44+
addressTableModel(nullptr),
3945
transactionTableModel(nullptr),
4046
recentRequestsTableModel(nullptr),
4147
cachedEncryptionStatus(Unencrypted),

src/qt/walletmodel.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
enum class OutputType;
2525

2626
class AddressTableModel;
27+
class ClientModel;
2728
class OptionsModel;
2829
class PlatformStyle;
2930
class RecentRequestsTableModel;
@@ -52,7 +53,7 @@ class WalletModel : public QObject
5253
Q_OBJECT
5354

5455
public:
55-
explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *optionsModel, QObject *parent = nullptr);
56+
explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent = nullptr);
5657
~WalletModel();
5758

5859
enum StatusCode // Returned by sendCoins
@@ -143,6 +144,7 @@ class WalletModel : public QObject
143144

144145
interfaces::Node& node() const { return m_node; }
145146
interfaces::Wallet& wallet() const { return *m_wallet; }
147+
ClientModel& clientModel() const { return m_client_model; }
146148

147149
QString getWalletName() const;
148150
QString getDisplayName() const;
@@ -159,6 +161,7 @@ class WalletModel : public QObject
159161
std::unique_ptr<interfaces::Handler> m_handler_show_progress;
160162
std::unique_ptr<interfaces::Handler> m_handler_watch_only_changed;
161163
std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
164+
ClientModel& m_client_model;
162165
interfaces::Node& m_node;
163166

164167
bool fHaveWatchOnly;

0 commit comments

Comments
 (0)