mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-30 02:15:54 +02:00
Merge bitcoin/bitcoin#30111: locks: introduce mutex for tx download, flush rejection filters once per tip change
c85accecaf[refactor] delete EraseTxNoLock, just use EraseTx (glozow)6ff84069a5remove obsoleted TxOrphanage::m_mutex (glozow)61745c7451lock m_recent_confirmed_transactions using m_tx_download_mutex (glozow)723ea0f9a5remove obsoleted hashRecentRejectsChainTip (glozow)18a4355250update recent_rejects filters on ActiveTipChange (glozow)36f170d879add ValidationInterface::ActiveTipChange (glozow)3eb1307df0guard TxRequest and rejection caches with new mutex (glozow) Pull request description: See #27463 for full project tracking. This contains the first few commits of #30110, which require some thinking about thread safety in review. - Introduce a new `m_tx_download_mutex` which guards the transaction download data structures including `m_txrequest`, the rolling bloom filters, and `m_orphanage`. Later this should become the mutex guarding `TxDownloadManager`. - `m_txrequest` doesn't need to be guarded using `cs_main` anymore - `m_recent_confirmed_transactions` doesn't need its own lock anymore - `m_orphanage` doesn't need its own lock anymore - Adds a new `ValidationInterface` event, `ActiveTipChanged`, which is a synchronous callback whenever the tip of the active chainstate changes. - Flush `m_recent_rejects` and `m_recent_rejects_reconsiderable` on `ActiveTipChanged` just once instead of checking the tip every time `AlreadyHaveTx` is called. This should speed up calls to that function (no longer comparing a block hash each time) and removes the need to lock `cs_main` every time it is called. Motivation: - These data structures need synchronization. While we are holding `m_tx_download_mutex`, these should hold: - a tx hash in `m_txrequest` is not also in `m_orphanage` - a tx hash in `m_txrequest` is not also in `m_recent_rejects` or `m_recent_confirmed_transactions` - In the future, orphan resolution tracking should also be synchronized. If a tx has an entry in the orphan resolution tracker, it is also in `m_orphanage`, and not in `m_txrequest`, etc. - Currently, `cs_main` is used to e.g. sync accesses to `m_txrequest`. We should not broaden the scope of things it locks. - Currently, we need to know the current chainstate every time we call `AlreadyHaveTx` so we can decide whether we should update it. Every call compares the current tip hash with `hashRecentRejectsChainTip`. It is more efficient to have a validation interface callback that updates the rejection filters whenever the chain tip changes. ACKs for top commit: instagibbs: reACKc85accecafdergoegge: Code review ACKc85accecaftheStack: Light code-review ACKc85accecafhebasto: ACKc85accecaf, I have reviewed the code and it looks OK. Tree-SHA512: c3bd524b5de1cafc9a10770dadb484cc479d6d4c687d80dd0f176d339fd95f73b85cb44cb3b6b464d38a52e20feda00aa2a1da5a73339e31831687e4bd0aa0c5
This commit is contained in:
@@ -3473,6 +3473,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
{
|
||||
// Lock transaction pool for at least as long as it takes for connectTrace to be consumed
|
||||
LOCK(MempoolMutex());
|
||||
const bool was_in_ibd = m_chainman.IsInitialBlockDownload();
|
||||
@@ -3549,7 +3550,12 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // release MempoolMutex
|
||||
// Notify external listeners about the new tip, even if pindexFork == pindexNewTip.
|
||||
if (m_chainman.m_options.signals && this == &m_chainman.ActiveChainstate()) {
|
||||
m_chainman.m_options.signals->ActiveTipChange(pindexNewTip, m_chainman.IsInitialBlockDownload());
|
||||
}
|
||||
} // release cs_main
|
||||
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
|
||||
|
||||
if (exited_ibd) {
|
||||
@@ -3768,6 +3774,12 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
||||
// distinguish user-initiated invalidateblock changes from other
|
||||
// changes.
|
||||
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed), *to_mark_failed->pprev);
|
||||
|
||||
// Fire ActiveTipChange now for the current chain tip to make sure clients are notified.
|
||||
// ActivateBestChain may call this as well, but not necessarily.
|
||||
if (m_chainman.m_options.signals) {
|
||||
m_chainman.m_options.signals->ActiveTipChange(m_chain.Tip(), m_chainman.IsInitialBlockDownload());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user