Skip to content

Commit 4957051

Browse files
committed
wallet: cache block hash, height and time inside the wallet.
1 parent 33f4788 commit 4957051

File tree

7 files changed

+45
-19
lines changed

7 files changed

+45
-19
lines changed

src/validation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1913,7 +1913,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
19131913
UpdateTip(pindexDelete->pprev);
19141914
// Let wallets know transactions went from 1-confirmed to
19151915
// 0-confirmed or conflicted:
1916-
GetMainSignals().BlockDisconnected(pblock, pindexDelete->nHeight);
1916+
GetMainSignals().BlockDisconnected(pblock, pindexDelete->GetBlockHash(), pindexDelete->nHeight, pindexDelete->GetBlockTime());
19171917

19181918
return true;
19191919
}

src/validationinterface.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct MainSignalsInstance {
3737
*/
3838
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef> &)> BlockConnected;
3939
/** Notifies listeners of a block being disconnected */
40-
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, int nBlockHeight)> BlockDisconnected;
40+
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const uint256& blockHash, int nBlockHeight, int64_t blockTime)> BlockDisconnected;
4141
/** Notifies listeners of a transaction removal from the mempool */
4242
boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
4343
/** Notifies listeners of a new active block chain. */
@@ -98,7 +98,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn)
9898
conns.UpdatedBlockTip = g_signals.m_internals->UpdatedBlockTip.connect(std::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
9999
conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1));
100100
conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
101-
conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1, std::placeholders::_2));
101+
conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
102102
conns.TransactionRemovedFromMempool = g_signals.m_internals->TransactionRemovedFromMempool.connect(std::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, std::placeholders::_1));
103103
conns.SetBestChain = g_signals.m_internals->SetBestChain.connect(std::bind(&CValidationInterface::SetBestChain, pwalletIn, std::placeholders::_1));
104104
conns.Broadcast = g_signals.m_internals->Broadcast.connect(std::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, std::placeholders::_1));
@@ -163,9 +163,9 @@ void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, c
163163
});
164164
}
165165

166-
void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock> &pblock, int nBlockHeight) {
167-
m_internals->m_schedulerClient.AddToProcessQueue([pblock, nBlockHeight, this] {
168-
m_internals->BlockDisconnected(pblock, nBlockHeight);
166+
void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock> &pblock, const uint256& blockHash, int nBlockHeight, int64_t blockTime) {
167+
m_internals->m_schedulerClient.AddToProcessQueue([pblock, blockHash, nBlockHeight, blockTime, this] {
168+
m_internals->BlockDisconnected(pblock, blockHash, nBlockHeight, blockTime);
169169
});
170170
}
171171

src/validationinterface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class CValidationInterface {
9393
*
9494
* Called on a background thread.
9595
*/
96-
virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block, int nBlockHeight) {}
96+
virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const uint256& blockHash, int nBlockHeight, int64_t blockTime) {}
9797
/**
9898
* Notifies listeners of the new active block chain on-disk.
9999
*
@@ -138,7 +138,7 @@ class CMainSignals {
138138
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
139139
void TransactionAddedToMempool(const CTransactionRef &ptxn);
140140
void BlockConnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>> &);
141-
void BlockDisconnected(const std::shared_ptr<const CBlock> &block, int nBlockHeight);
141+
void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const uint256& blockHash, int nBlockHeight, int64_t blockTime);
142142
void SetBestChain(const CBlockLocator &);
143143
void Broadcast(CConnman* connman);
144144
void BlockChecked(const CBlock&, const CValidationState&);

src/wallet/wallet.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,9 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
12781278
{
12791279
LOCK2(cs_main, cs_wallet);
12801280

1281+
m_last_block_processed = pindex->GetBlockHash();
1282+
m_last_block_processed_time = pindex->GetBlockTime();
1283+
m_last_block_processed_height = pindex->nHeight;
12811284
for (size_t i = 0; i < pblock->vtx.size(); i++) {
12821285
SyncTransaction(pblock->vtx[i], CWalletTx::Status::CONFIRMED, pindex, i);
12831286
TransactionRemovedFromMempool(pblock->vtx[i]);
@@ -1301,18 +1304,19 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
13011304

13021305
// Sapling: Update cached incremental witnesses
13031306
ChainTipAdded(pindex, pblock.get(), oldSaplingTree);
1304-
1305-
m_last_block_processed = pindex;
13061307
}
13071308

1308-
void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, int nBlockHeight)
1309+
void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const uint256& blockHash, int nBlockHeight, int64_t blockTime)
13091310
{
13101311
LOCK2(cs_main, cs_wallet);
13111312

13121313
// At block disconnection, this will change an abandoned transaction to
13131314
// be unconfirmed, whether or not the transaction is added back to the mempool.
13141315
// User may have to call abandontransaction again. It may be addressed in the
13151316
// future with a stickier abandoned state or even removing abandontransaction call.
1317+
m_last_block_processed_height = nBlockHeight - 1;
1318+
m_last_block_processed_time = blockTime;
1319+
m_last_block_processed = blockHash;
13161320
for (const CTransactionRef& ptx : pblock->vtx) {
13171321
SyncTransaction(ptx, CWalletTx::Status::UNCONFIRMED, nullptr, 0);
13181322
}
@@ -1328,17 +1332,21 @@ void CWallet::BlockUntilSyncedToCurrentChain() {
13281332
AssertLockNotHeld(cs_main);
13291333
AssertLockNotHeld(cs_wallet);
13301334

1331-
if (m_last_block_processed) {
1335+
{
13321336
// Skip the queue-draining stuff if we know we're caught up with
13331337
// chainActive.Tip()...
13341338
// We could also take cs_wallet here, and call m_last_block_processed
13351339
// protected by cs_wallet instead of cs_main, but as long as we need
13361340
// cs_main here anyway, its easier to just call it cs_main-protected.
1341+
uint256 last_block_hash = WITH_LOCK(cs_wallet, return m_last_block_processed);
13371342
LOCK(cs_main);
13381343
const CBlockIndex* initialChainTip = chainActive.Tip();
13391344

1340-
if (m_last_block_processed->GetAncestor(initialChainTip->nHeight) == initialChainTip) {
1341-
return;
1345+
if (!last_block_hash.IsNull()) {
1346+
auto it = mapBlockIndex.find(last_block_hash);
1347+
if (it == mapBlockIndex.end() || it->second->GetAncestor(initialChainTip->nHeight) == initialChainTip) {
1348+
return;
1349+
}
13421350
}
13431351
}
13441352

@@ -4191,7 +4199,15 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
41914199
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
41924200
}
41934201

4194-
walletInstance->m_last_block_processed = chainActive.Tip();
4202+
{
4203+
LOCK(walletInstance->cs_wallet);
4204+
const CBlockIndex* tip = chainActive.Tip();
4205+
if (tip) {
4206+
walletInstance->m_last_block_processed = tip->GetBlockHash();
4207+
walletInstance->m_last_block_processed_height = tip->nHeight;
4208+
walletInstance->m_last_block_processed_time = tip->GetBlockTime();
4209+
}
4210+
}
41954211
RegisterValidationInterface(walletInstance);
41964212

41974213
if (chainActive.Tip() && chainActive.Tip() != pindexRescan) {

src/wallet/wallet.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,15 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
579579
*
580580
* Protected by cs_main (see BlockUntilSyncedToCurrentChain)
581581
*/
582-
const CBlockIndex* m_last_block_processed{nullptr};
582+
uint256 m_last_block_processed GUARDED_BY(cs_wallet) = UINT256_ZERO;
583+
584+
/* Height of last block processed is used by wallet to know depth of transactions
585+
* without relying on Chain interface beyond asynchronous updates. For safety, we
586+
* initialize it to -1. Height is a pointer on node's tip and doesn't imply
587+
* that the wallet has scanned sequentially all blocks up to this one.
588+
*/
589+
int m_last_block_processed_height GUARDED_BY(cs_wallet) = -1;
590+
int64_t m_last_block_processed_time GUARDED_BY(cs_wallet) = 0;
583591

584592
int64_t nNextResend;
585593
int64_t nLastResend;
@@ -636,6 +644,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
636644
bool IsHDEnabled() const;
637645
//! Whether the wallet supports Sapling or not //
638646
bool IsSaplingUpgradeEnabled() const;
647+
//! Return the height of the last processed block
648+
int GetLastBlockHeight() const { return m_last_block_processed_height; }
639649

640650
/* SPKM Helpers */
641651
const CKeyingMaterial& GetEncryptionKey() const;
@@ -903,7 +913,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
903913
bool LoadToWallet(CWalletTx& wtxIn);
904914
void TransactionAddedToMempool(const CTransactionRef& tx) override;
905915
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
906-
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, int nBlockHeight) override;
916+
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const uint256& blockHash, int nBlockHeight, int64_t blockTime) override;
907917
bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, CWalletTx::Status status, const uint256& blockHash, int posInBlock, bool fUpdate);
908918
void EraseFromWallet(const uint256& hash);
909919

src/zmq/zmqnotificationinterface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void CZMQNotificationInterface::BlockConnected(const std::shared_ptr<const CBloc
172172
}
173173
}
174174

175-
void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, int nBlockHeight)
175+
void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const uint256& blockHash, int nBlockHeight, int64_t blockTime)
176176
{
177177
for (const CTransactionRef& ptx : pblock->vtx) {
178178
// Do a normal notify for each transaction removed in block disconnection

src/zmq/zmqnotificationinterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class CZMQNotificationInterface : public CValidationInterface
2727
// CValidationInterface
2828
void TransactionAddedToMempool(const CTransactionRef& tx) override;
2929
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::vector<CTransactionRef>& vtxConflicted) override;
30-
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, int nBlockHeight) override;
30+
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const uint256& blockHash, int nBlockHeight, int64_t blockTime) override;
3131
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
3232

3333
private:

0 commit comments

Comments
 (0)