From 18a43552509603ddf83b752fd7b4b973ba1dcf82 Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 16 May 2024 12:27:40 +0100 Subject: [PATCH] update recent_rejects filters on ActiveTipChange Resetting m_recent_rejects once per block is more efficient than comparing hashRecentRejectsChainTip with the chain tip every time we call AlreadyHaveTx. We keep hashRecentRejectsChainTip for now to assert that updates happen correctly; it is removed in the next commit. --- src/net_processing.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 95ef67b160c45..62c4df91a5aab 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -489,6 +489,8 @@ class PeerManagerImpl final : public PeerManager CTxMemPool& pool, node::Warnings& warnings, Options opts); /** Overridden from CValidationInterface. */ + void ActiveTipChange(const CBlockIndex* new_tip, bool) override + EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex, !m_tx_download_mutex); void BlockConnected(ChainstateRole role, const std::shared_ptr& pblock, const CBlockIndex* pindexConnected) override EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex, !m_tx_download_mutex); void BlockDisconnected(const std::shared_ptr &block, const CBlockIndex* pindex) override @@ -2074,6 +2076,22 @@ void PeerManagerImpl::StartScheduledTasks(CScheduler& scheduler) scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta); } +void PeerManagerImpl::ActiveTipChange(const CBlockIndex* new_tip, bool is_ibd) +{ + AssertLockNotHeld(m_mempool.cs); + AssertLockNotHeld(m_tx_download_mutex); + + if (!is_ibd) { + LOCK(m_tx_download_mutex); + // If the chain tip has changed, previously rejected transactions might now be valid, e.g. due + // to a timelock. Reset the rejection filters to give those transactions another chance if we + // see them again. + m_recent_rejects.reset(); + m_recent_rejects_reconsiderable.reset(); + hashRecentRejectsChainTip = new_tip->GetBlockHash(); + } +} + /** * Evict orphan txn pool entries based on a newly connected * block, remember the recently confirmed transactions, and delete tracked @@ -2277,7 +2295,11 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid, bool include_reconside AssertLockHeld(::cs_main); AssertLockHeld(m_tx_download_mutex); - if (m_chainman.ActiveChain().Tip()->GetBlockHash() != hashRecentRejectsChainTip) { + // Since recent_rejects is updated whenever the tip changes, and hashRecentRejectsChainTip is + // not set until the first time it is called outside of IBD, hashRecentRejectsChainTip should + // always be up to date with the current chain tip. + if (!Assume(hashRecentRejectsChainTip == uint256::ZERO || + hashRecentRejectsChainTip == m_chainman.ActiveChain().Tip()->GetBlockHash())) { // If the chain tip has changed previously rejected transactions // might be now valid, e.g. due to a nLockTime'd tx becoming valid, // or a double-spend. Reset the rejects filter and give those