diff --git a/src/governance/governance.cpp b/src/governance/governance.cpp index 89336190ed..dc88ac524e 100644 --- a/src/governance/governance.cpp +++ b/src/governance/governance.cpp @@ -157,10 +157,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, Pe uint256 nHash = govobj.GetHash(); - { - LOCK(cs_main); - EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT, nHash)); - } + WITH_LOCK(::cs_main, peerman.EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT, nHash))); if (!m_mn_sync->IsBlockchainSynced()) { LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECT -- masternode list not synced\n"); @@ -223,11 +220,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, Pe vRecv >> vote; uint256 nHash = vote.GetHash(); - - { - LOCK(cs_main); - EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT_VOTE, nHash)); - } + WITH_LOCK(::cs_main, peerman.EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT_VOTE, nHash))); // Ignore such messages until masternode list is synced if (!m_mn_sync->IsBlockchainSynced()) { @@ -1222,13 +1215,13 @@ void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nH connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MNGOVERNANCESYNC, nHash, filter)); } -int CGovernanceManager::RequestGovernanceObjectVotes(CNode& peer, CConnman& connman) const +int CGovernanceManager::RequestGovernanceObjectVotes(CNode& peer, CConnman& connman, const PeerManager& peerman) const { const std::vector vNodeCopy{&peer}; - return RequestGovernanceObjectVotes(vNodeCopy, connman); + return RequestGovernanceObjectVotes(vNodeCopy, connman, peerman); } -int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& vNodesCopy, CConnman& connman) const +int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& vNodesCopy, CConnman& connman, const PeerManager& peerman) const { static std::map > mapAskedRecently; @@ -1304,7 +1297,7 @@ int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& // stop early to prevent setAskFor overflow { LOCK(cs_main); - size_t nProjectedSize = GetRequestedObjectCount(pnode->GetId()) + nProjectedVotes; + size_t nProjectedSize = peerman.GetRequestedObjectCount(pnode->GetId()) + nProjectedVotes; if (nProjectedSize > MAX_INV_SZ) continue; // to early to ask the same node if (mapAskedRecently[nHashGovobj].count(pnode->addr)) continue; diff --git a/src/governance/governance.h b/src/governance/governance.h index 9e38f411fa..e8b0a075dd 100644 --- a/src/governance/governance.h +++ b/src/governance/governance.h @@ -357,8 +357,8 @@ public: void InitOnLoad(); - int RequestGovernanceObjectVotes(CNode& peer, CConnman& connman) const; - int RequestGovernanceObjectVotes(const std::vector& vNodesCopy, CConnman& connman) const; + int RequestGovernanceObjectVotes(CNode& peer, CConnman& connman, const PeerManager& peerman) const; + int RequestGovernanceObjectVotes(const std::vector& vNodesCopy, CConnman& connman, const PeerManager& peerman) const; /* * Trigger Management (formerly CGovernanceTriggerManager) diff --git a/src/init.cpp b/src/init.cpp index 2b9f2bb31f..144d258b94 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2220,7 +2220,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 10a: schedule Dash-specific tasks node.scheduler->scheduleEvery(std::bind(&CNetFulfilledRequestManager::DoMaintenance, std::ref(*node.netfulfilledman)), std::chrono::minutes{1}); - node.scheduler->scheduleEvery(std::bind(&CMasternodeSync::DoMaintenance, std::ref(*node.mn_sync)), std::chrono::seconds{1}); + node.scheduler->scheduleEvery(std::bind(&CMasternodeSync::DoMaintenance, std::ref(*node.mn_sync), std::cref(*node.peerman)), std::chrono::seconds{1}); node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), std::ref(*node.cj_ctx)), std::chrono::minutes{1}); node.scheduler->scheduleEvery(std::bind(&CDeterministicMNManager::DoMaintenance, std::ref(*node.dmnman)), std::chrono::seconds{10}); diff --git a/src/llmq/blockprocessor.cpp b/src/llmq/blockprocessor.cpp index 98c827ef6c..6030c9330e 100644 --- a/src/llmq/blockprocessor.cpp +++ b/src/llmq/blockprocessor.cpp @@ -60,7 +60,7 @@ PeerMsgRet CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_ CFinalCommitment qc; vRecv >> qc; - WITH_LOCK(cs_main, EraseObjectRequest(peer.GetId(), CInv(MSG_QUORUM_FINAL_COMMITMENT, ::SerializeHash(qc)))); + WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(peer.GetId(), CInv(MSG_QUORUM_FINAL_COMMITMENT, ::SerializeHash(qc)))); if (qc.IsNull()) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- null commitment from peer=%d\n", __func__, peer.GetId()); diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index 39130b5a07..cfd2938935 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -115,8 +115,7 @@ PeerMsgRet CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq CInv clsigInv(MSG_CLSIG, hash); if (from != -1) { - LOCK(cs_main); - EraseObjectRequest(from, clsigInv); + WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(from, clsigInv)); } { diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index e6f301cfa0..7b4b8c4ab2 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -72,8 +72,7 @@ void CDKGPendingMessages::PushPendingMessage(NodeId from, PeerManager* peerman, uint256 hash = hw.GetHash(); if (from != -1) { - LOCK(cs_main); - EraseObjectRequest(from, CInv(invType, hash)); + WITH_LOCK(::cs_main, Assert(m_peerman.load())->EraseObjectRequest(from, CInv(invType, hash))); } LOCK(cs_messages); diff --git a/src/llmq/instantsend.cpp b/src/llmq/instantsend.cpp index 037dd2f1f6..75f016a194 100644 --- a/src/llmq/instantsend.cpp +++ b/src/llmq/instantsend.cpp @@ -762,7 +762,7 @@ PeerMsgRet CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom { auto hash = ::SerializeHash(*islock); - WITH_LOCK(cs_main, EraseObjectRequest(pfrom.GetId(), CInv(MSG_ISDLOCK, hash))); + WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(pfrom.GetId(), CInv(MSG_ISDLOCK, hash))); if (!islock->TriviallyValid()) { return tl::unexpected{100}; @@ -1446,7 +1446,7 @@ void CInstantSendManager::RemoveConflictingLock(const uint256& islockHash, const } } -void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, bool is_masternode) +void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnman& connman, PeerManager& peerman, bool is_masternode) { std::vector nodesToAskFor; nodesToAskFor.reserve(4); @@ -1476,7 +1476,7 @@ void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnma txid.ToString(), pnode->GetId()); CInv inv(MSG_TX, txid); - RequestObject(pnode->GetId(), inv, GetTime(), is_masternode, /* fForce = */ true); + peerman.RequestObject(pnode->GetId(), inv, GetTime(), is_masternode, /* fForce = */ true); } } for (CNode* pnode : nodesToAskFor) { diff --git a/src/llmq/instantsend.h b/src/llmq/instantsend.h index 733d2afd7a..a823354f4e 100644 --- a/src/llmq/instantsend.h +++ b/src/llmq/instantsend.h @@ -315,7 +315,7 @@ private: EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock) EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); - static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, + static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, PeerManager& peerman, bool is_masternode); void ProcessPendingRetryLockTxs() EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); diff --git a/src/llmq/signing.cpp b/src/llmq/signing.cpp index 8200146d32..b866cfc1e3 100644 --- a/src/llmq/signing.cpp +++ b/src/llmq/signing.cpp @@ -604,10 +604,7 @@ static bool PreVerifyRecoveredSig(const CQuorumManager& quorum_manager, const CR PeerMsgRet CSigningManager::ProcessMessageRecoveredSig(const CNode& pfrom, const std::shared_ptr& recoveredSig) { - { - LOCK(cs_main); - EraseObjectRequest(pfrom.GetId(), CInv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash())); - } + WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(pfrom.GetId(), CInv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash()))); bool ban = false; if (!PreVerifyRecoveredSig(qman, *recoveredSig, ban)) { diff --git a/src/masternode/sync.cpp b/src/masternode/sync.cpp index 9e3f53a0c2..b4fc5440bf 100644 --- a/src/masternode/sync.cpp +++ b/src/masternode/sync.cpp @@ -115,7 +115,7 @@ void CMasternodeSync::ProcessMessage(const CNode& peer, std::string_view msg_typ LogPrint(BCLog::MNSYNC, "SYNCSTATUSCOUNT -- got inventory count: nItemID=%d nCount=%d peer=%d\n", nItemID, nCount, peer.GetId()); } -void CMasternodeSync::ProcessTick() +void CMasternodeSync::ProcessTick(const PeerManager& peerman) { assert(m_netfulfilledman.IsValid()); @@ -144,7 +144,7 @@ void CMasternodeSync::ProcessTick() // gradually request the rest of the votes after sync finished if(IsSynced()) { - m_govman.RequestGovernanceObjectVotes(snap.Nodes(), connman); + m_govman.RequestGovernanceObjectVotes(snap.Nodes(), connman, peerman); return; } @@ -264,7 +264,7 @@ void CMasternodeSync::ProcessTick() if(!m_netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) { continue; // to early for this node } - int nObjsLeftToAsk = m_govman.RequestGovernanceObjectVotes(*pnode, connman); + int nObjsLeftToAsk = m_govman.RequestGovernanceObjectVotes(*pnode, connman, peerman); // check for data if(nObjsLeftToAsk == 0) { static int64_t nTimeNoObjectsLeft = 0; @@ -368,9 +368,9 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexTip, const CBlock pindexNew->nHeight, pindexTip->nHeight, fInitialDownload, fReachedBestHeader); } -void CMasternodeSync::DoMaintenance() +void CMasternodeSync::DoMaintenance(const PeerManager& peerman) { if (ShutdownRequested()) return; - ProcessTick(); + ProcessTick(peerman); } diff --git a/src/masternode/sync.h b/src/masternode/sync.h index 2692cd1736..d61ef070ba 100644 --- a/src/masternode/sync.h +++ b/src/masternode/sync.h @@ -15,6 +15,7 @@ class CGovernanceManager; class CMasternodeSync; class CNetFulfilledRequestManager; class CNode; +class PeerManager; static constexpr int MASTERNODE_SYNC_BLOCKCHAIN = 1; static constexpr int MASTERNODE_SYNC_GOVERNANCE = 4; @@ -71,13 +72,13 @@ public: void SwitchToNextAsset(); void ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv) const; - void ProcessTick(); + void ProcessTick(const PeerManager& peerman); void AcceptedBlockHeader(const CBlockIndex *pindexNew); void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload); void UpdatedBlockTip(const CBlockIndex *pindexTip, const CBlockIndex *pindexNew, bool fInitialDownload); - void DoMaintenance(); + void DoMaintenance(const PeerManager& peerman); }; #endif // BITCOIN_MASTERNODE_SYNC_H diff --git a/src/net.h b/src/net.h index 77aa23fd40..71ff10861c 100644 --- a/src/net.h +++ b/src/net.h @@ -1654,10 +1654,6 @@ public: extern RecursiveMutex cs_main; -void EraseObjectRequest(NodeId nodeId, const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main); -void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool fForce=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); -size_t GetRequestedObjectCount(NodeId nodeId) EXCLUSIVE_LOCKS_REQUIRED(cs_main); - /** Protect desirable or disadvantaged inbound peers from eviction by ratio. * * This function protects half of the peers which have been connected the diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 3129c30b85..78dbe58a01 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -421,6 +421,10 @@ public: const std::chrono::microseconds time_received, const std::atomic& interruptMsgProc) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex); bool IsBanned(NodeId pnode) override EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_peer_mutex); + void EraseObjectRequest(NodeId nodeid, const CInv& inv) override EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + void RequestObject(NodeId nodeid, const CInv& inv, std::chrono::microseconds current_time, + bool is_masternode, bool fForce = false) override EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + size_t GetRequestedObjectCount(NodeId nodeid) const override EXCLUSIVE_LOCKS_REQUIRED(::cs_main); bool IsInvInFilter(NodeId nodeid, const uint256& hash) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); private: @@ -1350,27 +1354,20 @@ void PeerManagerImpl::PushNodeVersion(CNode& pnode, const Peer& peer) } } -void EraseObjectRequest(CNodeState* nodestate, const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +void PeerManagerImpl::EraseObjectRequest(NodeId nodeid, const CInv& inv) { AssertLockHeld(cs_main); + + CNodeState* state = State(nodeid); + if (state == nullptr) + return; + LogPrint(BCLog::NET, "%s -- inv=(%s)\n", __func__, inv.ToString()); g_already_asked_for.erase(inv.hash); g_erased_object_requests.insert(std::make_pair(inv.hash, GetTime())); - if (nodestate) { - nodestate->m_object_download.m_object_announced.erase(inv); - nodestate->m_object_download.m_object_in_flight.erase(inv); - } -} - -void EraseObjectRequest(NodeId nodeId, const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) -{ - AssertLockHeld(cs_main); - auto* state = State(nodeId); - if (!state) { - return; - } - EraseObjectRequest(state, inv); + state->m_object_download.m_object_announced.erase(inv); + state->m_object_download.m_object_in_flight.erase(inv); } std::chrono::microseconds GetObjectRequestTime(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) @@ -1443,9 +1440,15 @@ std::chrono::microseconds CalculateObjectGetDataTime(const CInv& inv, std::chron return process_time; } -void RequestObject(CNodeState* state, const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool fForce = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +void PeerManagerImpl::RequestObject(NodeId nodeid, const CInv& inv, std::chrono::microseconds current_time, + bool is_masternode, bool fForce) { AssertLockHeld(cs_main); + + CNodeState* state = State(nodeid); + if (state == nullptr) + return; + CNodeState::ObjectDownloadState& peer_download_state = state->m_object_download; if (peer_download_state.m_object_announced.size() >= MAX_PEER_OBJECT_ANNOUNCEMENTS || peer_download_state.m_object_process_time.size() >= MAX_PEER_OBJECT_ANNOUNCEMENTS || @@ -1471,23 +1474,14 @@ void RequestObject(CNodeState* state, const CInv& inv, std::chrono::microseconds LogPrint(BCLog::NET, "%s -- inv=(%s), current_time=%d, process_time=%d, delta=%d\n", __func__, inv.ToString(), current_time.count(), process_time.count(), (process_time - current_time).count()); } -void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool fForce) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +size_t PeerManagerImpl::GetRequestedObjectCount(NodeId nodeid) const { AssertLockHeld(cs_main); - auto* state = State(nodeId); - if (!state) { - return; - } - RequestObject(state, inv, current_time, is_masternode, fForce); -} -size_t GetRequestedObjectCount(NodeId nodeId) -{ - AssertLockHeld(cs_main); - auto* state = State(nodeId); - if (!state) { + CNodeState* state = State(nodeid); + if (state == nullptr) return 0; - } + return state->m_object_download.m_object_process_time.size(); } @@ -3795,7 +3789,7 @@ void PeerManagerImpl::ProcessMessage( } bool allowWhileInIBD = allowWhileInIBDObjs.count(inv.type); if (allowWhileInIBD || !m_chainman.ActiveChainstate().IsInitialBlockDownload()) { - RequestObject(State(pfrom.GetId()), inv, current_time, is_masternode); + RequestObject(pfrom.GetId(), inv, current_time, is_masternode); } } } @@ -4183,11 +4177,11 @@ void PeerManagerImpl::ProcessMessage( for (const uint256& parent_txid : unique_parents) { CInv _inv(MSG_TX, parent_txid); AddKnownInv(*peer, _inv.hash); - if (!AlreadyHave(_inv)) RequestObject(State(pfrom.GetId()), _inv, current_time, is_masternode); + if (!AlreadyHave(_inv)) RequestObject(pfrom.GetId(), _inv, current_time, is_masternode); // We don't know if the previous tx was a regular or a mixing one, try both CInv _inv2(MSG_DSTX, parent_txid); AddKnownInv(*peer, _inv2.hash); - if (!AlreadyHave(_inv2)) RequestObject(State(pfrom.GetId()), _inv2, current_time, is_masternode); + if (!AlreadyHave(_inv2)) RequestObject(pfrom.GetId(), _inv2, current_time, is_masternode); } if (m_orphanage.AddTx(ptx, pfrom.GetId())) { diff --git a/src/net_processing.h b/src/net_processing.h index 33b12b24ad..2b281df0c9 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -128,6 +128,11 @@ public: const std::chrono::microseconds time_received, const std::atomic& interruptMsgProc) = 0; virtual bool IsBanned(NodeId pnode) = 0; + + virtual void EraseObjectRequest(NodeId nodeid, const CInv& inv) = 0; + virtual void RequestObject(NodeId nodeid, const CInv& inv, std::chrono::microseconds current_time, + bool is_masternode, bool fForce = false) = 0; + virtual size_t GetRequestedObjectCount(NodeId nodeid) const = 0; }; #endif // BITCOIN_NET_PROCESSING_H diff --git a/src/spork.cpp b/src/spork.cpp index 6fd7a6388b..058d9b9b40 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -145,12 +145,8 @@ PeerMsgRet CSporkManager::ProcessSpork(const CNode& peer, PeerManager& peerman, uint256 hash = spork.GetHash(); - std::string strLogMsg; - { - LOCK(cs_main); - EraseObjectRequest(peer.GetId(), CInv(MSG_SPORK, hash)); - strLogMsg = strprintf("SPORK -- hash: %s id: %d value: %10d peer=%d", hash.ToString(), spork.nSporkID, spork.nValue, peer.GetId()); - } + WITH_LOCK(::cs_main, peerman.EraseObjectRequest(peer.GetId(), CInv(MSG_SPORK, hash))); + std::string strLogMsg{strprintf("SPORK -- hash: %s id: %d value: %10d peer=%d", hash.ToString(), spork.nSporkID, spork.nValue, peer.GetId())}; if (spork.nTimeSigned > GetAdjustedTime() + 2 * 60 * 60) { LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: too far into the future\n");