From 4470acf076289831ac60bcbafb6b3afa0e98e99d Mon Sep 17 00:00:00 2001 From: Gleb Naumenko Date: Sat, 20 Mar 2021 12:50:02 +0200 Subject: [PATCH] p2p: Forget peer's reconciliation state on disconnect --- src/net_processing.cpp | 1 + src/node/txreconciliation.cpp | 14 ++++++++++++++ src/node/txreconciliation.h | 6 ++++++ 3 files changed, 21 insertions(+) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index a10b6bfc471..af8afe235e3 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1494,6 +1494,7 @@ void PeerManagerImpl::FinalizeNode(const CNode& node) } WITH_LOCK(g_cs_orphans, m_orphanage.EraseForPeer(nodeid)); m_txrequest.DisconnectedPeer(nodeid); + if (m_txreconciliation) m_txreconciliation->ForgetPeer(nodeid); m_num_preferred_download_peers -= state->fPreferredDownload; m_peers_downloading_from -= (state->nBlocksInFlight != 0); assert(m_peers_downloading_from >= 0); diff --git a/src/node/txreconciliation.cpp b/src/node/txreconciliation.cpp index dfac2ad82ed..d8cb1564759 100644 --- a/src/node/txreconciliation.cpp +++ b/src/node/txreconciliation.cpp @@ -54,6 +54,15 @@ public: Assert(m_states.emplace(peer_id, local_salt).second); return local_salt; } + + void ForgetPeer(NodeId peer_id) EXCLUSIVE_LOCKS_REQUIRED(!m_txreconciliation_mutex) + { + AssertLockNotHeld(m_txreconciliation_mutex); + LOCK(m_txreconciliation_mutex); + if (m_states.erase(peer_id)) { + LogPrintLevel(BCLog::TXRECONCILIATION, BCLog::Level::Debug, "Forget txreconciliation state of peer=%d\n", peer_id); + } + } }; TxReconciliationTracker::TxReconciliationTracker() : m_impl{std::make_unique()} {} @@ -64,3 +73,8 @@ uint64_t TxReconciliationTracker::PreRegisterPeer(NodeId peer_id) { return m_impl->PreRegisterPeer(peer_id); } + +void TxReconciliationTracker::ForgetPeer(NodeId peer_id) +{ + m_impl->ForgetPeer(peer_id); +} diff --git a/src/node/txreconciliation.h b/src/node/txreconciliation.h index 6e94a51cf24..b8e9b649c08 100644 --- a/src/node/txreconciliation.h +++ b/src/node/txreconciliation.h @@ -61,6 +61,12 @@ public: * This function must be called only once per peer. */ uint64_t PreRegisterPeer(NodeId peer_id); + + /** + * Attempts to forget txreconciliation-related state of the peer (if we previously stored any). + * After this, we won't be able to reconcile transactions with the peer. + */ + void ForgetPeer(NodeId peer_id); }; #endif // BITCOIN_NODE_TXRECONCILIATION_H