diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -380,7 +380,7 @@ #ifdef ENABLE_WALLET if (WalletModel::isWalletEnabled()) { m_wallet_controller = - new WalletController(node(), platformStyle, optionsModel, this); + new WalletController(*clientModel, platformStyle, this); window->setWalletController(m_wallet_controller); if (paymentServer) { paymentServer->setOptionsModel(optionsModel); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -53,6 +53,7 @@ //! Return number of connections, default is in- and outbound (total) int getNumConnections(NumConnections flags = CONNECTIONS_ALL) const; + int getNumBlocks() const; int getHeaderTipHeight() const; int64_t getHeaderTipTime() const; @@ -70,9 +71,10 @@ bool getProxyInfo(std::string &ip_port) const; - // caches for the best header + // caches for the best header, number of blocks mutable std::atomic cachedBestHeaderHeight; mutable std::atomic cachedBestHeaderTime; + mutable std::atomic m_cached_num_blocks{-1}; private: interfaces::Node &m_node; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -103,6 +103,13 @@ 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) { Q_EMIT numConnectionsChanged(numConnections); } @@ -221,6 +228,8 @@ // cache best headers time and height to reduce future cs_main locks clientmodel->cachedBestHeaderHeight = height; clientmodel->cachedBestHeaderTime = blockTime; + } else { + clientmodel->m_cached_num_blocks = height; } // Throttle GUI notifications about (a) blocks during initial sync, and (b) diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -113,9 +114,10 @@ std::unique_ptr platformStyle( PlatformStyle::instantiate("other")); OptionsModel optionsModel; + ClientModel clientModel(node, &optionsModel); AddWallet(wallet); - WalletModel walletModel(interfaces::MakeWallet(wallet), node, - platformStyle.get(), &optionsModel); + WalletModel walletModel(interfaces::MakeWallet(wallet), clientModel, + platformStyle.get()); RemoveWallet(wallet); EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress); editAddressDialog.setModel(walletModel.getAddressTableModel()); diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -148,9 +149,10 @@ std::unique_ptr platformStyle( PlatformStyle::instantiate("other")); OptionsModel optionsModel; + ClientModel clientModel(node, &optionsModel); AddWallet(wallet); - WalletModel walletModel(interfaces::MakeWallet(wallet), node, - platformStyle.get(), &optionsModel); + WalletModel walletModel(interfaces::MakeWallet(wallet), clientModel, + platformStyle.get()); RemoveWallet(wallet); SendCoinsDialog sendCoinsDialog(platformStyle.get(), &walletModel); diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -170,7 +171,8 @@ int 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()) { TransactionRecord *rec = &cachedWallet[idx]; @@ -184,8 +186,8 @@ interfaces::WalletTxStatus wtx; int numBlocks; int64_t block_time; - if (wallet.tryGetTxStatus(rec->txid, wtx, numBlocks, block_time) && - rec->statusUpdateNeeded(numBlocks)) { + if (rec->statusUpdateNeeded(cur_num_blocks) && + wallet.tryGetTxStatus(rec->txid, wtx, numBlocks, block_time)) { rec->updateStatus(wtx, numBlocks, block_time); } return rec; @@ -669,10 +671,10 @@ QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const { Q_UNUSED(parent); - TransactionRecord *data = priv->index(walletModel->wallet(), row); + TransactionRecord *data = priv->index( + walletModel->wallet(), walletModel->clientModel().getNumBlocks(), row); if (data) { - return createIndex(row, column, - priv->index(walletModel->wallet(), row)); + return createIndex(row, column, data); } return QModelIndex(); } diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h --- a/src/qt/walletcontroller.h +++ b/src/qt/walletcontroller.h @@ -25,6 +25,7 @@ #include #include +class ClientModel; class OptionsModel; class PlatformStyle; class WalletModel; @@ -50,9 +51,8 @@ void removeAndDeleteWallet(WalletModel *wallet_model); 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(); //! Returns wallet models currently open. @@ -76,6 +76,7 @@ private: QThread *const m_activity_thread; QObject *const m_activity_worker; + ClientModel &m_client_model; interfaces::Node &m_node; const PlatformStyle *const m_platform_style; OptionsModel *const m_options_model; diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -22,12 +23,13 @@ #include -WalletController::WalletController(interfaces::Node &node, +WalletController::WalletController(ClientModel &client_model, const PlatformStyle *platform_style, - OptionsModel *options_model, QObject *parent) + QObject *parent) : QObject(parent), m_activity_thread(new QThread(this)), - m_activity_worker(new QObject), m_node(node), - m_platform_style(platform_style), m_options_model(options_model) { + m_activity_worker(new QObject), m_client_model(client_model), + m_node(client_model.node()), m_platform_style(platform_style), + m_options_model(client_model.getOptionsModel()) { m_handler_load_wallet = m_node.handleLoadWallet( [this](std::unique_ptr wallet) { getOrCreateWallet(std::move(wallet)); @@ -105,7 +107,7 @@ // Instantiate model and register it. WalletModel *wallet_model = new WalletModel( - std::move(wallet), m_node, m_platform_style, m_options_model, nullptr); + std::move(wallet), m_client_model, m_platform_style, nullptr); // Handler callback runs in a different thread so fix wallet model thread // affinity. wallet_model->moveToThread(thread()); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -21,6 +21,7 @@ #include class AddressTableModel; +class ClientModel; class OptionsModel; class PlatformStyle; class RecentRequestsTableModel; @@ -48,9 +49,9 @@ public: explicit WalletModel(std::unique_ptr wallet, - interfaces::Node &node, + ClientModel &client_model, const PlatformStyle *platformStyle, - OptionsModel *optionsModel, QObject *parent = nullptr); + QObject *parent = nullptr); ~WalletModel(); // Returned by sendCoins @@ -147,6 +148,7 @@ interfaces::Node &node() const { return m_node; } interfaces::Wallet &wallet() const { return *m_wallet; } + ClientModel &clientModel() const { return m_client_model; } const CChainParams &getChainParams() const; @@ -168,6 +170,7 @@ std::unique_ptr m_handler_show_progress; std::unique_ptr m_handler_watch_only_changed; std::unique_ptr m_handler_can_get_addrs_changed; + ClientModel &m_client_model; interfaces::Node &m_node; bool fHaveWatchOnly; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -27,11 +28,11 @@ #include WalletModel::WalletModel(std::unique_ptr wallet, - interfaces::Node &node, - const PlatformStyle *platformStyle, - OptionsModel *_optionsModel, QObject *parent) - : QObject(parent), m_wallet(std::move(wallet)), m_node(node), - optionsModel(_optionsModel), addressTableModel(nullptr), + ClientModel &client_model, + const PlatformStyle *platformStyle, QObject *parent) + : 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), recentRequestsTableModel(nullptr), cachedEncryptionStatus(Unencrypted), cachedNumBlocks(0) { fHaveWatchOnly = m_wallet->haveWatchOnly();