diff --git a/src/llmq/quorums_dkgsession.cpp b/src/llmq/quorums_dkgsession.cpp index 8b04d01d0d391..d439485307965 100644 --- a/src/llmq/quorums_dkgsession.cpp +++ b/src/llmq/quorums_dkgsession.cpp @@ -1244,26 +1244,17 @@ void CDKGSession::MarkBadMember(size_t idx) member->bad = true; } -void CDKGSession::AddParticipatingNode(NodeId nodeId) -{ - LOCK(invCs); - g_connman->ForNode(nodeId, [&](CNode* pnode) { - if (!participatingNodes.emplace(pnode->addr).second) { - return true; - } - - for (const auto& inv : invSet) { - pnode->PushInventory(inv); - } - return true; - }); -} - void CDKGSession::RelayInvToParticipants(const CInv& inv) const { LOCK(invCs); g_connman->ForEachNode([&](CNode* pnode) { - if (participatingNodes.count(pnode->addr)) { + bool relay = false; + if (pnode->qwatch) { + relay = true; + } else if (!pnode->verifiedProRegTxHash.IsNull() && membersMap.count(pnode->verifiedProRegTxHash)) { + relay = true; + } + if (relay) { pnode->PushInventory(inv); } }); diff --git a/src/llmq/quorums_dkgsession.h b/src/llmq/quorums_dkgsession.h index b0e110abd1c4c..4f4adca45871f 100644 --- a/src/llmq/quorums_dkgsession.h +++ b/src/llmq/quorums_dkgsession.h @@ -277,7 +277,6 @@ class CDKGSession std::map justifications; std::map prematureCommitments; std::set invSet; - std::set participatingNodes; std::vector pendingContributionVerifications; @@ -336,7 +335,6 @@ class CDKGSession bool AreWeMember() const { return !myProTxHash.IsNull(); } void MarkBadMember(size_t idx); - void AddParticipatingNode(NodeId nodeId); void RelayInvToParticipants(const CInv& inv) const; public: diff --git a/src/llmq/quorums_dkgsessionhandler.cpp b/src/llmq/quorums_dkgsessionhandler.cpp index 6110a0414f113..01163ce472278 100644 --- a/src/llmq/quorums_dkgsessionhandler.cpp +++ b/src/llmq/quorums_dkgsessionhandler.cpp @@ -435,14 +435,6 @@ bool ProcessPendingMessageBatch(CDKGSession& session, CDKGPendingMessages& pendi } } - for (const auto& p : preverifiedMessages) { - NodeId nodeId = p.first; - if (badNodes.count(nodeId)) { - continue; - } - session.AddParticipatingNode(nodeId); - } - return true; } @@ -492,12 +484,6 @@ void CDKGSessionHandler::HandleDKGRound() } LogPrint("llmq", debugMsg); g_connman->AddMasternodeQuorumNodes(params.type, curQuorumHash, connections); - - auto participatingNodesTmp = g_connman->GetMasternodeQuorumAddresses(params.type, curQuorumHash); - LOCK(curSession->invCs); - for (auto& p : participatingNodesTmp) { - curSession->participatingNodes.emplace(p.first); - } } } diff --git a/src/llmq/quorums_dkgsessionmgr.cpp b/src/llmq/quorums_dkgsessionmgr.cpp index edb4556744ecb..173634e4e88cf 100644 --- a/src/llmq/quorums_dkgsessionmgr.cpp +++ b/src/llmq/quorums_dkgsessionmgr.cpp @@ -81,10 +81,6 @@ void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& strComm if (strCommand == NetMsgType::QWATCH) { pfrom->qwatch = true; - for (auto& p : dkgSessionHandlers) { - LOCK2(p.second.cs, p.second.curSession->invCs); - p.second.curSession->participatingNodes.emplace(pfrom->addr); - } return; } diff --git a/src/llmq/quorums_signing_shares.cpp b/src/llmq/quorums_signing_shares.cpp index 072d4ca32cdda..bb3fd2d863d44 100644 --- a/src/llmq/quorums_signing_shares.cpp +++ b/src/llmq/quorums_signing_shares.cpp @@ -644,13 +644,7 @@ void CSigSharesManager::ProcessPendingSigSharesFromNode(NodeId nodeId, cxxtimer::Timer t(true); for (auto& sigShare : sigShares) { - // he sent us some valid sig shares, so he must be part of this quorum and is thus interested in our sig shares as well - // if this is the first time we received a sig share from this node, we won't announce the currently locally known sig shares to him. - // only the upcoming sig shares will be announced to him. this means the first signing session for a fresh quorum will be a bit - // slower than for older ones. TODO: fix this (risk of DoS when announcing all at once?) auto quorumKey = std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash); - nodeState.interestedIn.emplace(quorumKey); - ProcessSigShare(nodeId, sigShare, connman, quorums.at(quorumKey)); } t.stop(); @@ -670,10 +664,6 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare std::set quorumNodes; if (sigShare.quorumMember == quorum->GetMemberIndex(activeMasternodeInfo.proTxHash)) { quorumNodes = connman.GetMasternodeQuorumNodes((Consensus::LLMQType) sigShare.llmqType, sigShare.quorumHash); - // make sure node states are created for these nodes (we might have not received any message from these yet) - for (auto otherNodeId : quorumNodes) { - nodeStates[otherNodeId].interestedIn.emplace(std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash)); - } } if (quorumSigningManager->HasRecoveredSigForId(llmqType, sigShare.id)) { @@ -702,12 +692,9 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare if (!quorumNodes.empty()) { // don't announce and wait for other nodes to request this share and directly send it to them // there is no way the other nodes know about this share as this is the one created on this node - // this will also indicate interest to the other nodes in sig shares for this quorum - for (auto& p : nodeStates) { - if (!quorumNodes.count(p.first) && !p.second.interestedIn.count(std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash))) { - continue; - } - auto& session = p.second.GetOrCreateSessionFromShare(sigShare); + for (auto otherNodeId : quorumNodes) { + auto& nodeState = nodeStates[otherNodeId]; + auto& session = nodeState.GetOrCreateSessionFromShare(sigShare); session.quorum = quorum; session.requested.Set(sigShare.quorumMember, true); session.knows.Set(sigShare.quorumMember, true); @@ -942,7 +929,7 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map, StaticSaltedHasher> quorumNodesPrepared; + std::unordered_map, std::unordered_set, StaticSaltedHasher> quorumNodesMap; this->sigSharesToAnnounce.ForEach([&](const SigShareKey& sigShareKey, bool) { auto& signHash = sigShareKey.first; @@ -952,30 +939,20 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_mapllmqType, sigShare->quorumHash); - if (quorumNodesPrepared.emplace(quorumKey).second) { - // make sure we announce to at least the nodes which we know through the inter-quorum-communication system + auto it = quorumNodesMap.find(quorumKey); + if (it == quorumNodesMap.end()) { auto nodeIds = g_connman->GetMasternodeQuorumNodes(quorumKey.first, quorumKey.second); - for (auto nodeId : nodeIds) { - auto& nodeState = nodeStates[nodeId]; - nodeState.interestedIn.emplace(quorumKey); - } + it = quorumNodesMap.emplace(std::piecewise_construct, std::forward_as_tuple(quorumKey), std::forward_as_tuple(nodeIds.begin(), nodeIds.end())).first; } - for (auto& p : nodeStates) { - auto nodeId = p.first; - auto& nodeState = p.second; + auto& quorumNodes = it->second; - if (nodeState.banned) { - continue; - } + for (auto& nodeId : quorumNodes) { + auto& nodeState = nodeStates[nodeId]; - if (!nodeState.interestedIn.count(quorumKey)) { - // node is not interested in this sig share - // we only consider nodes to be interested if they sent us valid sig share before - // the sig share that we sign by ourself circumvents the inv system and is directly sent to all quorum members - // which are known by the deterministic inter-quorum-communication system. This is also the sig share that - // will tell the other nodes that we are interested in future sig shares + if (nodeState.banned) { continue; } @@ -997,9 +974,6 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_mapsigSharesToAnnounce.Clear(); } diff --git a/src/llmq/quorums_signing_shares.h b/src/llmq/quorums_signing_shares.h index d17be73c82ada..58ca5554488ff 100644 --- a/src/llmq/quorums_signing_shares.h +++ b/src/llmq/quorums_signing_shares.h @@ -316,10 +316,6 @@ class CSigSharesNodeState SigShareMap pendingIncomingSigShares; SigShareMap requestedSigShares; - // elements are added whenever we receive a valid sig share from this node - // this triggers us to send inventory items to him as he seems to be interested in these - std::unordered_set, StaticSaltedHasher> interestedIn; - bool banned{false}; Session& GetOrCreateSessionFromShare(const CSigShare& sigShare); diff --git a/src/masternode-utils.cpp b/src/masternode-utils.cpp index 1b8a755deda9c..9d46050867112 100644 --- a/src/masternode-utils.cpp +++ b/src/masternode-utils.cpp @@ -73,7 +73,7 @@ void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman) #endif // ENABLE_WALLET connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) { - if (pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode->addr)) { + if (pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode)) { #ifdef ENABLE_WALLET bool fFound = false; for (const auto& dmn : vecDmns) { diff --git a/src/net.cpp b/src/net.cpp index c58fd1f6c4c10..99c96974d746f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2749,16 +2749,6 @@ std::set CConnman::GetMasternodeQuorums(Consensus::LLMQType llmqType) return result; } -std::map CConnman::GetMasternodeQuorumAddresses(Consensus::LLMQType llmqType, const uint256& quorumHash) const -{ - LOCK(cs_vPendingMasternodes); - auto it = masternodeQuorumNodes.find(std::make_pair(llmqType, quorumHash)); - if (it == masternodeQuorumNodes.end()) { - return {}; - } - return it->second; -} - std::set CConnman::GetMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash) const { LOCK2(cs_vNodes, cs_vPendingMasternodes); @@ -2766,12 +2756,18 @@ std::set CConnman::GetMasternodeQuorumNodes(Consensus::LLMQType llmqType if (it == masternodeQuorumNodes.end()) { return {}; } + std::set proRegTxHashes; + for (auto& p : it->second) { + proRegTxHashes.emplace(p.second); + } + std::set nodes; for (const auto pnode : vNodes) { if (pnode->fDisconnect) { continue; } - if (!pnode->qwatch && !it->second.count(pnode->addr)) { + if (!pnode->qwatch && !it->second.count(pnode->addr) && + (pnode->verifiedProRegTxHash.IsNull() || !proRegTxHashes.count(pnode->verifiedProRegTxHash))) { continue; } nodes.emplace(pnode->id); @@ -2785,12 +2781,17 @@ void CConnman::RemoveMasternodeQuorumNodes(Consensus::LLMQType llmqType, const u masternodeQuorumNodes.erase(std::make_pair(llmqType, quorumHash)); } -bool CConnman::IsMasternodeQuorumNode(const CService& addr) +bool CConnman::IsMasternodeQuorumNode(const CNode* pnode) { LOCK(cs_vPendingMasternodes); for (const auto& p : masternodeQuorumNodes) { - if (p.second.count(addr)) { - return true; + for (const auto& p2 : p.second) { + if (p2.first == (CService)pnode->addr) { + return true; + } + if (!pnode->verifiedProRegTxHash.IsNull() && p2.second == pnode->verifiedProRegTxHash) { + return true; + } } } return false; diff --git a/src/net.h b/src/net.h index 1d8f3f3f2db0a..d385829f5cbe0 100644 --- a/src/net.h +++ b/src/net.h @@ -361,11 +361,10 @@ class CConnman bool AddMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::map& addresses); bool HasMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash); std::set GetMasternodeQuorums(Consensus::LLMQType llmqType); - std::map GetMasternodeQuorumAddresses(Consensus::LLMQType llmqType, const uint256& quorumHash) const; // also returns QWATCH nodes std::set GetMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash) const; void RemoveMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash); - bool IsMasternodeQuorumNode(const CService& addr); + bool IsMasternodeQuorumNode(const CNode* pnode); size_t GetNodeCount(NumConnections num); void GetNodeStats(std::vector& vstats);