mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
gui: Avoid redundant tx status updates
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.
This commit is contained in:
@@ -336,7 +336,7 @@ void BitcoinApplication::initializeResult(bool success)
|
|||||||
window->setClientModel(clientModel);
|
window->setClientModel(clientModel);
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (WalletModel::isWalletEnabled()) {
|
if (WalletModel::isWalletEnabled()) {
|
||||||
m_wallet_controller = new WalletController(m_node, platformStyle, optionsModel, this);
|
m_wallet_controller = new WalletController(*clientModel, platformStyle, this);
|
||||||
window->setWalletController(m_wallet_controller);
|
window->setWalletController(m_wallet_controller);
|
||||||
if (paymentServer) {
|
if (paymentServer) {
|
||||||
paymentServer->setOptionsModel(optionsModel);
|
paymentServer->setOptionsModel(optionsModel);
|
||||||
|
|||||||
@@ -105,6 +105,14 @@ int64_t ClientModel::getHeaderTipTime() const
|
|||||||
return cachedBestHeaderTime;
|
return cachedBestHeaderTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ClientModel::getNumBlocks() const
|
||||||
|
{
|
||||||
|
if (m_cached_num_blocks == -1) {
|
||||||
|
m_cached_num_blocks = m_node.getNumBlocks();
|
||||||
|
}
|
||||||
|
return m_cached_num_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
void ClientModel::updateNumConnections(int numConnections)
|
void ClientModel::updateNumConnections(int numConnections)
|
||||||
{
|
{
|
||||||
Q_EMIT numConnectionsChanged(numConnections);
|
Q_EMIT numConnectionsChanged(numConnections);
|
||||||
@@ -241,6 +249,8 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int heig
|
|||||||
// cache best headers time and height to reduce future cs_main locks
|
// cache best headers time and height to reduce future cs_main locks
|
||||||
clientmodel->cachedBestHeaderHeight = height;
|
clientmodel->cachedBestHeaderHeight = height;
|
||||||
clientmodel->cachedBestHeaderTime = blockTime;
|
clientmodel->cachedBestHeaderTime = blockTime;
|
||||||
|
} else {
|
||||||
|
clientmodel->m_cached_num_blocks = height;
|
||||||
}
|
}
|
||||||
// if we are in-sync or if we notify a header update, update the UI regardless of last update time
|
// if we are in-sync or if we notify a header update, update the UI regardless of last update time
|
||||||
if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
|
if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
|
|
||||||
//! Return number of connections, default is in- and outbound (total)
|
//! Return number of connections, default is in- and outbound (total)
|
||||||
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
|
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
|
||||||
|
int getNumBlocks() const;
|
||||||
int getHeaderTipHeight() const;
|
int getHeaderTipHeight() const;
|
||||||
int64_t getHeaderTipTime() const;
|
int64_t getHeaderTipTime() const;
|
||||||
|
|
||||||
@@ -73,9 +74,10 @@ public:
|
|||||||
|
|
||||||
bool getProxyInfo(std::string& ip_port) const;
|
bool getProxyInfo(std::string& ip_port) const;
|
||||||
|
|
||||||
// caches for the best header
|
// caches for the best header, number of blocks
|
||||||
mutable std::atomic<int> cachedBestHeaderHeight;
|
mutable std::atomic<int> cachedBestHeaderHeight;
|
||||||
mutable std::atomic<int64_t> cachedBestHeaderTime;
|
mutable std::atomic<int64_t> cachedBestHeaderTime;
|
||||||
|
mutable std::atomic<int> m_cached_num_blocks{-1};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
interfaces::Node& m_node;
|
interfaces::Node& m_node;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
|
#include <qt/clientmodel.h>
|
||||||
#include <qt/editaddressdialog.h>
|
#include <qt/editaddressdialog.h>
|
||||||
#include <qt/optionsmodel.h>
|
#include <qt/optionsmodel.h>
|
||||||
#include <qt/platformstyle.h>
|
#include <qt/platformstyle.h>
|
||||||
@@ -101,8 +102,9 @@ void TestAddAddressesToSendBook(interfaces::Node& node)
|
|||||||
// Initialize relevant QT models.
|
// Initialize relevant QT models.
|
||||||
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
|
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
|
||||||
OptionsModel optionsModel(node);
|
OptionsModel optionsModel(node);
|
||||||
|
ClientModel clientModel(node, &optionsModel);
|
||||||
AddWallet(wallet);
|
AddWallet(wallet);
|
||||||
WalletModel walletModel(interfaces::MakeWallet(wallet), node, platformStyle.get(), &optionsModel);
|
WalletModel walletModel(interfaces::MakeWallet(wallet), clientModel, platformStyle.get());
|
||||||
RemoveWallet(wallet);
|
RemoveWallet(wallet);
|
||||||
EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress);
|
EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress);
|
||||||
editAddressDialog.setModel(walletModel.getAddressTableModel());
|
editAddressDialog.setModel(walletModel.getAddressTableModel());
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
#include <qt/bitcoinamountfield.h>
|
#include <qt/bitcoinamountfield.h>
|
||||||
|
#include <qt/clientmodel.h>
|
||||||
#include <qt/optionsmodel.h>
|
#include <qt/optionsmodel.h>
|
||||||
#include <qt/platformstyle.h>
|
#include <qt/platformstyle.h>
|
||||||
#include <qt/qvalidatedlineedit.h>
|
#include <qt/qvalidatedlineedit.h>
|
||||||
@@ -165,8 +166,9 @@ void TestGUI(interfaces::Node& node)
|
|||||||
SendCoinsDialog sendCoinsDialog(platformStyle.get());
|
SendCoinsDialog sendCoinsDialog(platformStyle.get());
|
||||||
TransactionView transactionView(platformStyle.get());
|
TransactionView transactionView(platformStyle.get());
|
||||||
OptionsModel optionsModel(node);
|
OptionsModel optionsModel(node);
|
||||||
|
ClientModel clientModel(node, &optionsModel);
|
||||||
AddWallet(wallet);
|
AddWallet(wallet);
|
||||||
WalletModel walletModel(interfaces::MakeWallet(wallet), node, platformStyle.get(), &optionsModel);
|
WalletModel walletModel(interfaces::MakeWallet(wallet), clientModel, platformStyle.get());
|
||||||
RemoveWallet(wallet);
|
RemoveWallet(wallet);
|
||||||
sendCoinsDialog.setModel(&walletModel);
|
sendCoinsDialog.setModel(&walletModel);
|
||||||
transactionView.setModel(&walletModel);
|
transactionView.setModel(&walletModel);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <qt/transactiontablemodel.h>
|
#include <qt/transactiontablemodel.h>
|
||||||
|
|
||||||
#include <qt/addresstablemodel.h>
|
#include <qt/addresstablemodel.h>
|
||||||
|
#include <qt/clientmodel.h>
|
||||||
#include <qt/guiconstants.h>
|
#include <qt/guiconstants.h>
|
||||||
#include <qt/guiutil.h>
|
#include <qt/guiutil.h>
|
||||||
#include <qt/optionsmodel.h>
|
#include <qt/optionsmodel.h>
|
||||||
@@ -175,7 +176,7 @@ public:
|
|||||||
return cachedWallet.size();
|
return cachedWallet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionRecord *index(interfaces::Wallet& wallet, int idx)
|
TransactionRecord *index(interfaces::Wallet& wallet, const int cur_num_blocks, const int idx)
|
||||||
{
|
{
|
||||||
if(idx >= 0 && idx < cachedWallet.size())
|
if(idx >= 0 && idx < cachedWallet.size())
|
||||||
{
|
{
|
||||||
@@ -191,7 +192,7 @@ public:
|
|||||||
interfaces::WalletTxStatus wtx;
|
interfaces::WalletTxStatus wtx;
|
||||||
int numBlocks;
|
int numBlocks;
|
||||||
int64_t block_time;
|
int64_t block_time;
|
||||||
if (wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time) && rec->statusUpdateNeeded(numBlocks)) {
|
if (rec->statusUpdateNeeded(cur_num_blocks) && wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time)) {
|
||||||
rec->updateStatus(wtx, numBlocks, block_time);
|
rec->updateStatus(wtx, numBlocks, block_time);
|
||||||
}
|
}
|
||||||
return rec;
|
return rec;
|
||||||
@@ -663,10 +664,10 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
|
|||||||
QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
TransactionRecord *data = priv->index(walletModel->wallet(), row);
|
TransactionRecord *data = priv->index(walletModel->wallet(), walletModel->clientModel().getNumBlocks(), row);
|
||||||
if(data)
|
if(data)
|
||||||
{
|
{
|
||||||
return createIndex(row, column, priv->index(walletModel->wallet(), row));
|
return createIndex(row, column, data);
|
||||||
}
|
}
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <qt/walletcontroller.h>
|
#include <qt/walletcontroller.h>
|
||||||
|
|
||||||
#include <qt/askpassphrasedialog.h>
|
#include <qt/askpassphrasedialog.h>
|
||||||
|
#include <qt/clientmodel.h>
|
||||||
#include <qt/createwalletdialog.h>
|
#include <qt/createwalletdialog.h>
|
||||||
#include <qt/guiconstants.h>
|
#include <qt/guiconstants.h>
|
||||||
#include <qt/guiutil.h>
|
#include <qt/guiutil.h>
|
||||||
@@ -24,13 +25,14 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
|
|
||||||
WalletController::WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent)
|
WalletController::WalletController(ClientModel& client_model, const PlatformStyle* platform_style, QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_activity_thread(new QThread(this))
|
, m_activity_thread(new QThread(this))
|
||||||
, m_activity_worker(new QObject)
|
, m_activity_worker(new QObject)
|
||||||
, m_node(node)
|
, m_client_model(client_model)
|
||||||
|
, m_node(client_model.node())
|
||||||
, m_platform_style(platform_style)
|
, m_platform_style(platform_style)
|
||||||
, m_options_model(options_model)
|
, m_options_model(client_model.getOptionsModel())
|
||||||
{
|
{
|
||||||
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
|
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
|
||||||
getOrCreateWallet(std::move(wallet));
|
getOrCreateWallet(std::move(wallet));
|
||||||
@@ -104,7 +106,7 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wal
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate model and register it.
|
// Instantiate model and register it.
|
||||||
WalletModel* wallet_model = new WalletModel(std::move(wallet), m_node, m_platform_style, m_options_model, nullptr);
|
WalletModel* wallet_model = new WalletModel(std::move(wallet), m_client_model, m_platform_style, nullptr);
|
||||||
// Handler callback runs in a different thread so fix wallet model thread affinity.
|
// Handler callback runs in a different thread so fix wallet model thread affinity.
|
||||||
wallet_model->moveToThread(thread());
|
wallet_model->moveToThread(thread());
|
||||||
wallet_model->setParent(this);
|
wallet_model->setParent(this);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
class ClientModel;
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
class PlatformStyle;
|
class PlatformStyle;
|
||||||
class WalletModel;
|
class WalletModel;
|
||||||
@@ -47,7 +48,7 @@ class WalletController : public QObject
|
|||||||
void removeAndDeleteWallet(WalletModel* wallet_model);
|
void removeAndDeleteWallet(WalletModel* wallet_model);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent);
|
WalletController(ClientModel& client_model, const PlatformStyle* platform_style, QObject* parent);
|
||||||
~WalletController();
|
~WalletController();
|
||||||
|
|
||||||
//! Returns wallet models currently open.
|
//! Returns wallet models currently open.
|
||||||
@@ -70,6 +71,7 @@ Q_SIGNALS:
|
|||||||
private:
|
private:
|
||||||
QThread* const m_activity_thread;
|
QThread* const m_activity_thread;
|
||||||
QObject* const m_activity_worker;
|
QObject* const m_activity_worker;
|
||||||
|
ClientModel& m_client_model;
|
||||||
interfaces::Node& m_node;
|
interfaces::Node& m_node;
|
||||||
const PlatformStyle* const m_platform_style;
|
const PlatformStyle* const m_platform_style;
|
||||||
OptionsModel* const m_options_model;
|
OptionsModel* const m_options_model;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <qt/walletmodel.h>
|
#include <qt/walletmodel.h>
|
||||||
|
|
||||||
#include <qt/addresstablemodel.h>
|
#include <qt/addresstablemodel.h>
|
||||||
|
#include <qt/clientmodel.h>
|
||||||
#include <qt/guiconstants.h>
|
#include <qt/guiconstants.h>
|
||||||
#include <qt/optionsmodel.h>
|
#include <qt/optionsmodel.h>
|
||||||
#include <qt/paymentserver.h>
|
#include <qt/paymentserver.h>
|
||||||
@@ -32,8 +33,13 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
|
||||||
WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *_optionsModel, QObject *parent) :
|
WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent) :
|
||||||
QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(nullptr),
|
QObject(parent),
|
||||||
|
m_wallet(std::move(wallet)),
|
||||||
|
m_client_model(client_model),
|
||||||
|
m_node(client_model.node()),
|
||||||
|
optionsModel(client_model.getOptionsModel()),
|
||||||
|
addressTableModel(nullptr),
|
||||||
transactionTableModel(nullptr),
|
transactionTableModel(nullptr),
|
||||||
recentRequestsTableModel(nullptr),
|
recentRequestsTableModel(nullptr),
|
||||||
cachedEncryptionStatus(Unencrypted),
|
cachedEncryptionStatus(Unencrypted),
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
enum class OutputType;
|
enum class OutputType;
|
||||||
|
|
||||||
class AddressTableModel;
|
class AddressTableModel;
|
||||||
|
class ClientModel;
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
class PlatformStyle;
|
class PlatformStyle;
|
||||||
class RecentRequestsTableModel;
|
class RecentRequestsTableModel;
|
||||||
@@ -52,7 +53,7 @@ class WalletModel : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *optionsModel, QObject *parent = nullptr);
|
explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent = nullptr);
|
||||||
~WalletModel();
|
~WalletModel();
|
||||||
|
|
||||||
enum StatusCode // Returned by sendCoins
|
enum StatusCode // Returned by sendCoins
|
||||||
@@ -145,6 +146,7 @@ public:
|
|||||||
|
|
||||||
interfaces::Node& node() const { return m_node; }
|
interfaces::Node& node() const { return m_node; }
|
||||||
interfaces::Wallet& wallet() const { return *m_wallet; }
|
interfaces::Wallet& wallet() const { return *m_wallet; }
|
||||||
|
ClientModel& clientModel() const { return m_client_model; }
|
||||||
|
|
||||||
QString getWalletName() const;
|
QString getWalletName() const;
|
||||||
QString getDisplayName() const;
|
QString getDisplayName() const;
|
||||||
@@ -161,6 +163,7 @@ private:
|
|||||||
std::unique_ptr<interfaces::Handler> m_handler_show_progress;
|
std::unique_ptr<interfaces::Handler> m_handler_show_progress;
|
||||||
std::unique_ptr<interfaces::Handler> m_handler_watch_only_changed;
|
std::unique_ptr<interfaces::Handler> m_handler_watch_only_changed;
|
||||||
std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
|
std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
|
||||||
|
ClientModel& m_client_model;
|
||||||
interfaces::Node& m_node;
|
interfaces::Node& m_node;
|
||||||
|
|
||||||
bool fHaveWatchOnly;
|
bool fHaveWatchOnly;
|
||||||
|
|||||||
Reference in New Issue
Block a user