From d54ba447a7243862e5384e5b045b2e02eeb68496 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:22:34 +0000 Subject: [PATCH 1/7] net: use ForEachNode instead of manually iterating through vNodes ForEachNode is publicly available, which will help us extract the functions from CConnman in a subsequent commit --- src/net.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index d39a891f8b07b..0326d4fd78a51 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3934,52 +3934,49 @@ void CConnman::RelayTransaction(const CTransaction& tx, const bool is_dstx) } void CConnman::RelayInv(CInv &inv, const int minProtoVersion) { - LOCK(cs_vNodes); - for (const auto& pnode : vNodes) { + ForEachNode([&](CNode* pnode) { if (pnode->nVersion < minProtoVersion || !pnode->CanRelay()) - continue; + return; pnode->PushInventory(inv); - } + }); } void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const int minProtoVersion) { - LOCK(cs_vNodes); - for (const auto& pnode : vNodes) { + ForEachNode([&](CNode* pnode) { if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || pnode->IsBlockOnlyConn()) { - continue; + return; } { LOCK(pnode->m_tx_relay->cs_filter); if (!pnode->m_tx_relay->fRelayTxes) { - continue; + return; } if (pnode->m_tx_relay->pfilter && !pnode->m_tx_relay->pfilter->IsRelevantAndUpdate(relatedTx)) { - continue; + return; } } pnode->PushInventory(inv); - } + }); } void CConnman::RelayInvFiltered(CInv &inv, const uint256& relatedTxHash, const int minProtoVersion) { - LOCK(cs_vNodes); - for (const auto& pnode : vNodes) { + ForEachNode([&](CNode* pnode) { if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || pnode->IsBlockOnlyConn()) { - continue; + return; } { LOCK(pnode->m_tx_relay->cs_filter); if (!pnode->m_tx_relay->fRelayTxes) { - continue; + return; } if (pnode->m_tx_relay->pfilter && !pnode->m_tx_relay->pfilter->contains(relatedTxHash)) { - continue; + return; } } pnode->PushInventory(inv); - } + }); } void CConnman::RecordBytesRecv(uint64_t bytes) From 0323c6ca174bdda5926d90a775b848abb2af74f8 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:31:52 +0000 Subject: [PATCH 2/7] net: move Relay{Inv, InvFiltered, Transaction} out of CConnman --- src/coinjoin/server.cpp | 4 ++-- src/governance/object.cpp | 2 +- src/governance/vote.cpp | 2 +- src/llmq/blockprocessor.cpp | 2 +- src/llmq/chainlocks.cpp | 2 +- src/llmq/ehf_signals.cpp | 2 +- src/llmq/instantsend.cpp | 4 ++-- src/net.cpp | 26 +++++++++++++------------- src/net.h | 17 +++++++++++------ src/spork.cpp | 2 +- 10 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/coinjoin/server.cpp b/src/coinjoin/server.cpp index 250e965c61920..77731c77d0c1f 100644 --- a/src/coinjoin/server.cpp +++ b/src/coinjoin/server.cpp @@ -348,7 +348,7 @@ void CCoinJoinServer::CommitFinalTransaction() LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CommitFinalTransaction -- TRANSMITTING DSTX\n"); CInv inv(MSG_DSTX, hashTx); - connman.RelayInv(inv); + RelayInv(connman, inv); // Tell the clients it was successful RelayCompletedTransaction(MSG_SUCCESS); @@ -459,7 +459,7 @@ void CCoinJoinServer::ConsumeCollateral(const CTransactionRef& txref) const if (!ATMPIfSaneFee(m_chainstate, mempool, txref, false /* bypass_limits */)) { LogPrint(BCLog::COINJOIN, "%s -- AcceptToMemoryPool failed\n", __func__); } else { - connman.RelayTransaction(*txref, static_cast(m_dstxman.GetDSTX(txref->GetHash()))); + RelayTransaction(connman, *txref, static_cast(m_dstxman.GetDSTX(txref->GetHash()))); LogPrint(BCLog::COINJOIN, "%s -- Collateral was consumed\n", __func__); } } diff --git a/src/governance/object.cpp b/src/governance/object.cpp index dfd28b3879ee8..109c2bb2bd49c 100644 --- a/src/governance/object.cpp +++ b/src/governance/object.cpp @@ -651,7 +651,7 @@ void CGovernanceObject::Relay(CConnman& connman, const CMasternodeSync& mn_sync) } CInv inv(MSG_GOVERNANCE_OBJECT, GetHash()); - connman.RelayInv(inv, minProtoVersion); + RelayInv(connman, inv, minProtoVersion); } void CGovernanceObject::UpdateSentinelVariables(const CDeterministicMNList& tip_mn_list) diff --git a/src/governance/vote.cpp b/src/governance/vote.cpp index 859aee529c089..a1000426cae62 100644 --- a/src/governance/vote.cpp +++ b/src/governance/vote.cpp @@ -136,7 +136,7 @@ void CGovernanceVote::Relay(CConnman& connman, const CMasternodeSync& mn_sync, c } CInv inv(MSG_GOVERNANCE_OBJECT_VOTE, GetHash()); - connman.RelayInv(inv); + RelayInv(connman, inv); } void CGovernanceVote::UpdateHash() const diff --git a/src/llmq/blockprocessor.cpp b/src/llmq/blockprocessor.cpp index a1f75e7ce28c8..4f118f24331e1 100644 --- a/src/llmq/blockprocessor.cpp +++ b/src/llmq/blockprocessor.cpp @@ -666,7 +666,7 @@ void CQuorumBlockProcessor::AddMineableCommitment(const CFinalCommitment& fqc) // We only relay the new commitment if it's new or better then the old one if (relay) { CInv inv(MSG_QUORUM_FINAL_COMMITMENT, commitmentHash); - connman.RelayInv(inv); + RelayInv(connman, inv); } } diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index c5f3b0f525ab3..e55a4c9e98651 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -161,7 +161,7 @@ PeerMsgRet CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq // Note: do not hold cs while calling RelayInv AssertLockNotHeld(cs); - connman.RelayInv(clsigInv); + RelayInv(connman, clsigInv); if (pindex == nullptr) { // we don't know the block/header for this CLSIG yet, so bail out for now diff --git a/src/llmq/ehf_signals.cpp b/src/llmq/ehf_signals.cpp index 178254af4b398..70703c36a0b9e 100644 --- a/src/llmq/ehf_signals.cpp +++ b/src/llmq/ehf_signals.cpp @@ -139,7 +139,7 @@ void CEHFSignalsHandler::HandleNewRecoveredSig(const CRecoveredSig& recoveredSig LOCK(cs_main); const MempoolAcceptResult result = AcceptToMemoryPool(chainstate, mempool, tx_to_sent, /* bypass_limits */ false); if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) { - connman.RelayTransaction(*tx_to_sent, /*is_dstx=*/ false); + RelayTransaction(connman, *tx_to_sent, /*is_dstx=*/ false); } else { LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig -- AcceptToMemoryPool failed: %s\n", result.m_state.ToString()); } diff --git a/src/llmq/instantsend.cpp b/src/llmq/instantsend.cpp index c0ba51d3bd617..06020ff275a4d 100644 --- a/src/llmq/instantsend.cpp +++ b/src/llmq/instantsend.cpp @@ -1051,11 +1051,11 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has CInv inv(MSG_ISDLOCK, hash); if (tx != nullptr) { - connman.RelayInvFiltered(inv, *tx, ISDLOCK_PROTO_VERSION); + RelayInvFiltered(connman, inv, *tx, ISDLOCK_PROTO_VERSION); } else { // we don't have the TX yet, so we only filter based on txid. Later when that TX arrives, we will re-announce // with the TX taken into account. - connman.RelayInvFiltered(inv, islock->txid, ISDLOCK_PROTO_VERSION); + RelayInvFiltered(connman, inv, islock->txid, ISDLOCK_PROTO_VERSION); } ResolveBlockConflicts(hash, *islock); diff --git a/src/net.cpp b/src/net.cpp index 0326d4fd78a51..94a656214ec3d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3926,24 +3926,17 @@ bool CConnman::DisconnectNode(NodeId id) return false; } -void CConnman::RelayTransaction(const CTransaction& tx, const bool is_dstx) -{ - uint256 hash = tx.GetHash(); - CInv inv(is_dstx ? MSG_DSTX : MSG_TX, hash); - RelayInv(inv); -} - -void CConnman::RelayInv(CInv &inv, const int minProtoVersion) { - ForEachNode([&](CNode* pnode) { +void RelayInv(CConnman& connman, CInv &inv, const int minProtoVersion) { + connman.ForEachNode([&](CNode* pnode) { if (pnode->nVersion < minProtoVersion || !pnode->CanRelay()) return; pnode->PushInventory(inv); }); } -void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const int minProtoVersion) +void RelayInvFiltered(CConnman& connman, CInv &inv, const CTransaction& relatedTx, const int minProtoVersion) { - ForEachNode([&](CNode* pnode) { + connman.ForEachNode([&](CNode* pnode) { if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || pnode->IsBlockOnlyConn()) { return; } @@ -3960,9 +3953,9 @@ void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const }); } -void CConnman::RelayInvFiltered(CInv &inv, const uint256& relatedTxHash, const int minProtoVersion) +void RelayInvFiltered(CConnman& connman, CInv &inv, const uint256& relatedTxHash, const int minProtoVersion) { - ForEachNode([&](CNode* pnode) { + connman.ForEachNode([&](CNode* pnode) { if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || pnode->IsBlockOnlyConn()) { return; } @@ -3979,6 +3972,13 @@ void CConnman::RelayInvFiltered(CInv &inv, const uint256& relatedTxHash, const i }); } +void RelayTransaction(CConnman& connman, const CTransaction& tx, const bool is_dstx) +{ + uint256 hash = tx.GetHash(); + CInv inv(is_dstx ? MSG_DSTX : MSG_TX, hash); + RelayInv(connman, inv); +} + void CConnman::RecordBytesRecv(uint64_t bytes) { LOCK(cs_totalBytesRecv); diff --git a/src/net.h b/src/net.h index a2a11b346c20e..58a0432e86d09 100644 --- a/src/net.h +++ b/src/net.h @@ -1116,12 +1116,6 @@ friend class CNode; std::vector CopyNodeVector(std::function cond = AllNodes); void ReleaseNodeVector(const std::vector& vecNodes); - void RelayTransaction(const CTransaction& tx, const bool is_dstx); - void RelayInv(CInv &inv, const int minProtoVersion = MIN_PEER_PROTO_VERSION); - void RelayInvFiltered(CInv &inv, const CTransaction &relatedTx, const int minProtoVersion = MIN_PEER_PROTO_VERSION); - // This overload will not update node filters, so use it only for the cases when other messages will update related transaction data in filters - void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION); - // Addrman functions /** * Return all or many randomly selected addresses, optionally by network. @@ -1530,6 +1524,17 @@ friend class CNode; friend struct ConnmanTestMsg; }; +void RelayInv(CConnman& connman, CInv &inv, const int minProtoVersion = MIN_PEER_PROTO_VERSION); +void RelayInvFiltered(CConnman& connman, CInv &inv, const CTransaction &relatedTx, + const int minProtoVersion = MIN_PEER_PROTO_VERSION); +/** + * This overload will not update node filters, so use it only for the cases + * when other messages will update related transaction data in filters + */ +void RelayInvFiltered(CConnman& connman, CInv &inv, const uint256 &relatedTxHash, + const int minProtoVersion = MIN_PEER_PROTO_VERSION); +void RelayTransaction(CConnman& connman, const CTransaction& tx, const bool is_dstx); + /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval); diff --git a/src/spork.cpp b/src/spork.cpp index 2a27e6821fca6..19896e1081fa7 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -454,5 +454,5 @@ std::optional CSporkMessage::GetSignerKeyID() const void CSporkMessage::Relay(CConnman& connman) const { CInv inv(MSG_SPORK, GetHash()); - connman.RelayInv(inv); + RelayInv(connman, inv); } From c3f1ac22913615282ef9a74bebca57fa37df3b5b Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 18 Apr 2024 10:45:13 +0000 Subject: [PATCH 3/7] net: retire CConnman::RelayTransaction, use PeerManager::RelayTransaction --- src/coinjoin/context.cpp | 4 ++-- src/coinjoin/context.h | 3 ++- src/coinjoin/server.cpp | 3 ++- src/coinjoin/server.h | 5 ++++- src/init.cpp | 2 +- src/llmq/context.cpp | 2 +- src/llmq/ehf_signals.cpp | 15 ++++++++------- src/llmq/ehf_signals.h | 13 +++++++------ src/net.cpp | 7 ------- src/net.h | 1 - src/test/util/setup_common.cpp | 2 +- test/lint/lint-circular-dependencies.sh | 10 +++++----- 12 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 46ec89a156c12..3a0dd047af6c3 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -15,13 +15,13 @@ CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - bool relay_txes) : + const std::unique_ptr& peerman, bool relay_txes) : dstxman{std::make_unique()}, #ifdef ENABLE_WALLET walletman{std::make_unique(connman, dmnman, mn_metaman, mempool, mn_sync, queueman)}, queueman {relay_txes ? std::make_unique(connman, *walletman, dmnman, mn_metaman, mn_sync) : nullptr}, #endif // ENABLE_WALLET - server{std::make_unique(chainstate, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, mn_sync)} + server{std::make_unique(chainstate, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, mn_sync, peerman)} {} CJContext::~CJContext() {} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index 881daed6d0cd8..e3a7432cf99ca 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -21,6 +21,7 @@ class CDSTXManager; class CMasternodeMetaMan; class CMasternodeSync; class CTxMemPool; +class PeerManager; #ifdef ENABLE_WALLET class CCoinJoinClientQueueManager; @@ -32,7 +33,7 @@ struct CJContext { CJContext(const CJContext&) = delete; CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - bool relay_txes); + const std::unique_ptr& peerman, bool relay_txes); ~CJContext(); const std::unique_ptr dstxman; diff --git a/src/coinjoin/server.cpp b/src/coinjoin/server.cpp index 77731c77d0c1f..868786de38ce2 100644 --- a/src/coinjoin/server.cpp +++ b/src/coinjoin/server.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include