Skip to content

Commit 36f170d

Browse files
committed
add ValidationInterface::ActiveTipChange
This is a synchronous callback notifying clients of all tip changes. It allows clients to respond to a new block immediately after it is connected. The synchronicity is important for things like m_recent_rejects, in which a transaction's validity can change (rejected vs accepted) when this event is processed. For example, the transaction might have a timelock condition that has just been met. This is distinct from something like m_recent_confirmed_transactions, in which the validation outcome is the same (valid vs already-have), so it does not need to be reset immediately.
1 parent 3eb1307 commit 36f170d

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

src/validation.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3488,6 +3488,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
34883488

34893489
{
34903490
LOCK(cs_main);
3491+
{
34913492
// Lock transaction pool for at least as long as it takes for connectTrace to be consumed
34923493
LOCK(MempoolMutex());
34933494
const bool was_in_ibd = m_chainman.IsInitialBlockDownload();
@@ -3564,7 +3565,12 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
35643565
break;
35653566
}
35663567
}
3567-
}
3568+
} // release MempoolMutex
3569+
// Notify external listeners about the new tip, even if pindexFork == pindexNewTip.
3570+
if (m_chainman.m_options.signals && this == &m_chainman.ActiveChainstate()) {
3571+
m_chainman.m_options.signals->ActiveTipChange(pindexNewTip, m_chainman.IsInitialBlockDownload());
3572+
}
3573+
} // release cs_main
35683574
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
35693575

35703576
if (exited_ibd) {
@@ -3783,6 +3789,12 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
37833789
// distinguish user-initiated invalidateblock changes from other
37843790
// changes.
37853791
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed), *to_mark_failed->pprev);
3792+
3793+
// Fire ActiveTipChange now for the current chain tip to make sure clients are notified.
3794+
// ActivateBestChain may call this as well, but not necessarily.
3795+
if (m_chainman.m_options.signals) {
3796+
m_chainman.m_options.signals->ActiveTipChange(m_chain.Tip(), m_chainman.IsInitialBlockDownload());
3797+
}
37863798
}
37873799
return true;
37883800
}

src/validationinterface.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ void ValidationSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlo
183183
fInitialDownload);
184184
}
185185

186+
void ValidationSignals::ActiveTipChange(const CBlockIndex *new_tip, bool is_ibd)
187+
{
188+
LOG_EVENT("%s: new block hash=%s block height=%d", __func__, new_tip->GetBlockHash().ToString(), new_tip->nHeight);
189+
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.ActiveTipChange(new_tip, is_ibd); });
190+
}
191+
186192
void ValidationSignals::TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t mempool_sequence)
187193
{
188194
auto event = [tx, mempool_sequence, this] {

src/validationinterface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class CValidationInterface {
6161
* Called on a background thread. Only called for the active chainstate.
6262
*/
6363
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
64+
/**
65+
* Notifies listeners any time the block chain tip changes, synchronously.
66+
*/
67+
virtual void ActiveTipChange(const CBlockIndex* new_tip, bool is_ibd) {};
6468
/**
6569
* Notifies listeners of a transaction having been added to mempool.
6670
*
@@ -214,6 +218,7 @@ class ValidationSignals {
214218
void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);
215219

216220
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
221+
void ActiveTipChange(const CBlockIndex*, bool);
217222
void TransactionAddedToMempool(const NewMempoolTransactionInfo&, uint64_t mempool_sequence);
218223
void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);
219224
void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>&, unsigned int nBlockHeight);

0 commit comments

Comments
 (0)