Skip to content

Commit 2f86720

Browse files
committed
Added best block hash to the NotifyHeaderTip and NotifyBlockTip signals.
[ClientModel] best header/block hash cached.
1 parent cfe22a5 commit 2f86720

File tree

11 files changed

+57
-34
lines changed

11 files changed

+57
-34
lines changed

src/interfaces/node.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ class NodeImpl : public Node
187187
LOCK(::cs_main);
188188
return ::ChainActive().Height();
189189
}
190+
uint256 getBestBlockHash() override
191+
{
192+
const CBlockIndex* tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
193+
return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
194+
}
190195
int64_t getLastBlockTime() override
191196
{
192197
LOCK(::cs_main);
@@ -310,15 +315,15 @@ class NodeImpl : public Node
310315
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
311316
{
312317
return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
313-
fn(sync_state, block->nHeight, block->GetBlockTime(),
318+
fn(sync_state, block->GetBlockHash(), block->nHeight, block->GetBlockTime(),
314319
GuessVerificationProgress(Params().TxData(), block));
315320
}));
316321
}
317322
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
318323
{
319324
return MakeHandler(
320325
::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
321-
fn(sync_state, block->nHeight, block->GetBlockTime(),
326+
fn(sync_state, block->GetBlockHash(), block->nHeight, block->GetBlockTime(),
322327
/* verification progress is unused when a header was received */ 0);
323328
}));
324329
}

src/interfaces/node.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ class Node
149149
//! Get num blocks.
150150
virtual int getNumBlocks() = 0;
151151

152+
//! Get best block hash.
153+
virtual uint256 getBestBlockHash() = 0;
154+
152155
//! Get last block time.
153156
virtual int64_t getLastBlockTime() = 0;
154157

@@ -250,12 +253,12 @@ class Node
250253

251254
//! Register handler for block tip messages.
252255
using NotifyBlockTipFn =
253-
std::function<void(SynchronizationState, int height, int64_t block_time, double verification_progress)>;
256+
std::function<void(SynchronizationState, const uint256& block_hash, int height, int64_t block_time, double verification_progress)>;
254257
virtual std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) = 0;
255258

256259
//! Register handler for header tip messages.
257260
using NotifyHeaderTipFn =
258-
std::function<void(SynchronizationState, int height, int64_t block_time, double verification_progress)>;
261+
std::function<void(SynchronizationState, const uint256& block_hash, int height, int64_t block_time, double verification_progress)>;
259262
virtual std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0;
260263

261264
//! Return pointer to internal chain interface, useful for testing.

src/interfaces/wallet.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,13 @@ class WalletImpl : public Wallet
351351
}
352352
return result;
353353
}
354-
bool tryGetBalances(WalletBalances& balances, int& num_blocks) override
354+
bool tryGetBalances(WalletBalances& balances, uint256& block_hash) override
355355
{
356356
TRY_LOCK(m_wallet->cs_wallet, locked_wallet);
357357
if (!locked_wallet) {
358358
return false;
359359
}
360-
num_blocks = m_wallet->GetLastBlockHeight();
360+
block_hash = m_wallet->GetLastBlockHash();
361361
balances = getBalances();
362362
return true;
363363
}

src/interfaces/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class Wallet
203203
virtual WalletBalances getBalances() = 0;
204204

205205
//! Get balances if possible without blocking.
206-
virtual bool tryGetBalances(WalletBalances& balances, int& num_blocks) = 0;
206+
virtual bool tryGetBalances(WalletBalances& balances, uint256& block_hash) = 0;
207207

208208
//! Get balance.
209209
virtual CAmount getBalance() = 0;

src/qt/clientmodel.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ int ClientModel::getNumBlocks() const
114114
return m_cached_num_blocks;
115115
}
116116

117+
uint256 ClientModel::getBestBlockHash()
118+
{
119+
LOCK(m_cached_tip_mutex);
120+
if (m_cached_tip_blocks.IsNull()) {
121+
m_cached_tip_blocks = m_node.getBestBlockHash();
122+
}
123+
return m_cached_tip_blocks;
124+
}
125+
117126
void ClientModel::updateNumConnections(int numConnections)
118127
{
119128
Q_EMIT numConnectionsChanged(numConnections);
@@ -235,14 +244,15 @@ static void BannedListChanged(ClientModel *clientmodel)
235244
assert(invoked);
236245
}
237246

238-
static void BlockTipChanged(ClientModel* clientmodel, SynchronizationState sync_state, int height, int64_t blockTime, double verificationProgress, bool fHeader)
247+
static void BlockTipChanged(ClientModel* clientmodel, SynchronizationState sync_state, const uint256 block_hash, int height, int64_t blockTime, double verificationProgress, bool fHeader)
239248
{
240249
if (fHeader) {
241250
// cache best headers time and height to reduce future cs_main locks
242251
clientmodel->cachedBestHeaderHeight = height;
243252
clientmodel->cachedBestHeaderTime = blockTime;
244253
} else {
245254
clientmodel->m_cached_num_blocks = height;
255+
WITH_LOCK(clientmodel->m_cached_tip_mutex, clientmodel->m_cached_tip_blocks = block_hash;);
246256
}
247257

248258
// Throttle GUI notifications about (a) blocks during initial sync, and (b) both blocks and headers during reindex.
@@ -271,8 +281,8 @@ void ClientModel::subscribeToCoreSignals()
271281
m_handler_notify_network_active_changed = m_node.handleNotifyNetworkActiveChanged(std::bind(NotifyNetworkActiveChanged, this, std::placeholders::_1));
272282
m_handler_notify_alert_changed = m_node.handleNotifyAlertChanged(std::bind(NotifyAlertChanged, this));
273283
m_handler_banned_list_changed = m_node.handleBannedListChanged(std::bind(BannedListChanged, this));
274-
m_handler_notify_block_tip = m_node.handleNotifyBlockTip(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, false));
275-
m_handler_notify_header_tip = m_node.handleNotifyHeaderTip(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, true));
284+
m_handler_notify_block_tip = m_node.handleNotifyBlockTip(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, false));
285+
m_handler_notify_header_tip = m_node.handleNotifyHeaderTip(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, true));
276286
}
277287

278288
void ClientModel::unsubscribeFromCoreSignals()

src/qt/clientmodel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
#include <atomic>
1212
#include <memory>
13+
#include <sync.h>
14+
#include <uint256.h>
1315

1416
class BanTableModel;
1517
class CBlockIndex;
@@ -57,6 +59,7 @@ class ClientModel : public QObject
5759
//! Return number of connections, default is in- and outbound (total)
5860
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
5961
int getNumBlocks() const;
62+
uint256 getBestBlockHash();
6063
int getHeaderTipHeight() const;
6164
int64_t getHeaderTipTime() const;
6265

@@ -79,6 +82,9 @@ class ClientModel : public QObject
7982
mutable std::atomic<int64_t> cachedBestHeaderTime;
8083
mutable std::atomic<int> m_cached_num_blocks{-1};
8184

85+
Mutex m_cached_tip_mutex;
86+
uint256 m_cached_tip_blocks GUARDED_BY(m_cached_tip_mutex){};
87+
8288
private:
8389
interfaces::Node& m_node;
8490
std::unique_ptr<interfaces::Handler> m_handler_show_progress;

src/qt/transactionrecord.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const interface
162162
return parts;
163163
}
164164

165-
void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, int numBlocks, int64_t block_time)
165+
void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, const uint256& block_hash, int numBlocks, int64_t block_time)
166166
{
167167
// Determine transaction status
168168

@@ -174,7 +174,7 @@ void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, int
174174
idx);
175175
status.countsForBalance = wtx.is_trusted && !(wtx.blocks_to_maturity > 0);
176176
status.depth = wtx.depth_in_main_chain;
177-
status.cur_num_blocks = numBlocks;
177+
status.m_cur_block_hash = block_hash;
178178

179179
const bool up_to_date = ((int64_t)QDateTime::currentMSecsSinceEpoch() / 1000 - block_time < MAX_BLOCK_TIME_GAP);
180180
if (up_to_date && !wtx.is_final) {
@@ -233,9 +233,9 @@ void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, int
233233
status.needsUpdate = false;
234234
}
235235

236-
bool TransactionRecord::statusUpdateNeeded(int numBlocks) const
236+
bool TransactionRecord::statusUpdateNeeded(const uint256& block_hash) const
237237
{
238-
return status.cur_num_blocks != numBlocks || status.needsUpdate;
238+
return status.m_cur_block_hash != block_hash || status.needsUpdate;
239239
}
240240

241241
QString TransactionRecord::getTxHash() const

src/qt/transactionrecord.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ struct WalletTxStatus;
2323
class TransactionStatus
2424
{
2525
public:
26-
TransactionStatus():
27-
countsForBalance(false), sortKey(""),
28-
matures_in(0), status(Unconfirmed), depth(0), open_for(0), cur_num_blocks(-1)
26+
TransactionStatus() : countsForBalance(false), sortKey(""),
27+
matures_in(0), status(Unconfirmed), depth(0), open_for(0)
2928
{ }
3029

3130
enum Status {
@@ -61,8 +60,8 @@ class TransactionStatus
6160
finalization */
6261
/**@}*/
6362

64-
/** Current number of blocks (to know whether cached status is still valid) */
65-
int cur_num_blocks;
63+
/** Current block hash (to know whether cached status is still valid) */
64+
uint256 m_cur_block_hash{};
6665

6766
bool needsUpdate;
6867
};
@@ -138,11 +137,11 @@ class TransactionRecord
138137

139138
/** Update status from core wallet tx.
140139
*/
141-
void updateStatus(const interfaces::WalletTxStatus& wtx, int numBlocks, int64_t block_time);
140+
void updateStatus(const interfaces::WalletTxStatus& wtx, const uint256& block_hash, int numBlocks, int64_t block_time);
142141

143142
/** Return whether a status update is needed.
144143
*/
145-
bool statusUpdateNeeded(int numBlocks) const;
144+
bool statusUpdateNeeded(const uint256& block_hash) const;
146145
};
147146

148147
#endif // BITCOIN_QT_TRANSACTIONRECORD_H

src/qt/transactiontablemodel.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class TransactionTablePriv
176176
return cachedWallet.size();
177177
}
178178

179-
TransactionRecord *index(interfaces::Wallet& wallet, const int cur_num_blocks, const int idx)
179+
TransactionRecord* index(interfaces::Wallet& wallet, const uint256& cur_block_hash, const int idx)
180180
{
181181
if(idx >= 0 && idx < cachedWallet.size())
182182
{
@@ -192,8 +192,8 @@ class TransactionTablePriv
192192
interfaces::WalletTxStatus wtx;
193193
int numBlocks;
194194
int64_t block_time;
195-
if (rec->statusUpdateNeeded(cur_num_blocks) && wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time)) {
196-
rec->updateStatus(wtx, numBlocks, block_time);
195+
if (rec->statusUpdateNeeded(cur_block_hash) && wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time)) {
196+
rec->updateStatus(wtx, cur_block_hash, numBlocks, block_time);
197197
}
198198
return rec;
199199
}
@@ -664,7 +664,7 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
664664
QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
665665
{
666666
Q_UNUSED(parent);
667-
TransactionRecord *data = priv->index(walletModel->wallet(), walletModel->getNumBlocks(), row);
667+
TransactionRecord* data = priv->index(walletModel->wallet(), walletModel->clientModel().getBestBlockHash(), row);
668668
if(data)
669669
{
670670
return createIndex(row, column, data);

src/qt/walletmodel.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel
4646
transactionTableModel(nullptr),
4747
recentRequestsTableModel(nullptr),
4848
cachedEncryptionStatus(Unencrypted),
49-
cachedNumBlocks(0),
5049
timer(new QTimer(this))
5150
{
5251
fHaveWatchOnly = m_wallet->haveWatchOnly();
@@ -88,24 +87,23 @@ void WalletModel::pollBalanceChanged()
8887
{
8988
// Avoid recomputing wallet balances unless a TransactionChanged or
9089
// BlockTip notification was received.
91-
if (!fForceCheckBalanceChanged && cachedNumBlocks == m_client_model->getNumBlocks()) return;
90+
if (!fForceCheckBalanceChanged && m_cached_last_update_tip == m_client_model->getBestBlockHash()) return;
9291

9392
// Try to get balances and return early if locks can't be acquired. This
9493
// avoids the GUI from getting stuck on periodical polls if the core is
9594
// holding the locks for a longer time - for example, during a wallet
9695
// rescan.
9796
interfaces::WalletBalances new_balances;
98-
int numBlocks = -1;
99-
if (!m_wallet->tryGetBalances(new_balances, numBlocks)) {
97+
uint256 block_hash;
98+
if (!m_wallet->tryGetBalances(new_balances, block_hash)) {
10099
return;
101100
}
102101

103-
if(fForceCheckBalanceChanged || numBlocks != cachedNumBlocks)
104-
{
102+
if (fForceCheckBalanceChanged || block_hash != m_cached_last_update_tip) {
105103
fForceCheckBalanceChanged = false;
106104

107105
// Balance and number of transactions might have changed
108-
cachedNumBlocks = numBlocks;
106+
m_cached_last_update_tip = block_hash;
109107

110108
checkBalanceChanged(new_balances);
111109
if(transactionTableModel)

0 commit comments

Comments
 (0)