From 364d6c37f7193650c2cf96c44687abcfc82cf3c9 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 16 Mar 2020 10:54:59 +0100 Subject: [PATCH 1/3] Move and unify logic for quorum connection establishment into CLLMQUtils --- src/llmq/quorums.cpp | 29 +++------------------ src/llmq/quorums_dkgsessionhandler.cpp | 28 +------------------- src/llmq/quorums_utils.cpp | 36 ++++++++++++++++++++++++++ src/llmq/quorums_utils.h | 2 ++ 4 files changed, 42 insertions(+), 53 deletions(-) diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index 8b2caff58eea..4bb0b7303ffe 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -187,37 +187,14 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const auto curDkgBlock = pindexNew->GetAncestor(curDkgHeight)->GetBlockHash(); connmanQuorumsToDelete.erase(curDkgBlock); + bool allowWatch = gArgs.GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS); for (auto& quorum : lastQuorums) { - if (!quorum->IsMember(myProTxHash) && !gArgs.GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS)) { + if (!quorum->IsMember(myProTxHash) && !allowWatch) { continue; } if (!g_connman->HasMasternodeQuorumNodes(llmqType, quorum->qc.quorumHash)) { - std::set connections; - if (quorum->IsMember(myProTxHash)) { - connections = CLLMQUtils::GetQuorumConnections(llmqType, quorum->pindexQuorum, myProTxHash); - } else { - auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(llmqType, quorum->pindexQuorum, quorum->members.size(), 1); - for (auto idx : cindexes) { - connections.emplace(quorum->members[idx]->proTxHash); - } - } - if (!connections.empty()) { - if (LogAcceptCategory(BCLog::LLMQ)) { - auto mnList = deterministicMNManager->GetListAtChainTip(); - std::string debugMsg = strprintf("CQuorumManager::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, quorum->qc.quorumHash.ToString()); - for (auto& c : connections) { - auto dmn = mnList.GetValidMN(c); - if (!dmn) { - debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); - } else { - debugMsg += strprintf(" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString(false)); - } - } - LogPrint(BCLog::LLMQ, debugMsg.c_str()); - } - g_connman->AddMasternodeQuorumNodes(llmqType, quorum->qc.quorumHash, connections); - } + CLLMQUtils::EnsureQuorumConnections(llmqType, quorum->pindexQuorum, myProTxHash, allowWatch); } connmanQuorumsToDelete.erase(quorum->qc.quorumHash); } diff --git a/src/llmq/quorums_dkgsessionhandler.cpp b/src/llmq/quorums_dkgsessionhandler.cpp index 332e53330cda..97778cb95f16 100644 --- a/src/llmq/quorums_dkgsessionhandler.cpp +++ b/src/llmq/quorums_dkgsessionhandler.cpp @@ -500,33 +500,7 @@ void CDKGSessionHandler::HandleDKGRound() return changed; }); - if (curSession->AreWeMember() || gArgs.GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS)) { - std::set connections; - if (curSession->AreWeMember()) { - connections = CLLMQUtils::GetQuorumConnections(params.type, pindexQuorum, curSession->myProTxHash); - } else { - auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(params.type, pindexQuorum, curSession->members.size(), 1); - for (auto idx : cindexes) { - connections.emplace(curSession->members[idx]->dmn->proTxHash); - } - } - if (!connections.empty()) { - if (LogAcceptCategory(BCLog::LLMQ_DKG)) { - std::string debugMsg = strprintf("CDKGSessionManager::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, curSession->pindexQuorum->GetBlockHash().ToString()); - auto mnList = deterministicMNManager->GetListAtChainTip(); - for (const auto& c : connections) { - auto dmn = mnList.GetValidMN(c); - if (!dmn) { - debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); - } else { - debugMsg += strprintf(" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString(false)); - } - } - LogPrint(BCLog::LLMQ_DKG, debugMsg.c_str()); - } - g_connman->AddMasternodeQuorumNodes(params.type, curQuorumHash, connections); - } - } + CLLMQUtils::EnsureQuorumConnections(params.type, pindexQuorum, curSession->myProTxHash, gArgs.GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS)); WaitForNextPhase(QuorumPhase_Initialized, QuorumPhase_Contribute, curQuorumHash, []{return false;}); diff --git a/src/llmq/quorums_utils.cpp b/src/llmq/quorums_utils.cpp index 417668b8bfa6..0f66118d9fba 100644 --- a/src/llmq/quorums_utils.cpp +++ b/src/llmq/quorums_utils.cpp @@ -95,6 +95,42 @@ std::set CLLMQUtils::CalcDeterministicWatchConnections(Consensus::LLMQTy return result; } +void CLLMQUtils::EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256& myProTxHash, bool allowWatch) +{ + auto members = GetAllQuorumMembers(llmqType, pindexQuorum); + bool isMember = std::find_if(members.begin(), members.end(), [&](const CDeterministicMNCPtr& dmn) { return dmn->proTxHash == myProTxHash; }) != members.end(); + + if (!isMember && !allowWatch) { + return; + } + + std::set connections; + if (isMember) { + connections = CLLMQUtils::GetQuorumConnections(llmqType, pindexQuorum, myProTxHash); + } else { + auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(llmqType, pindexQuorum, members.size(), 1); + for (auto idx : cindexes) { + connections.emplace(members[idx]->proTxHash); + } + } + if (!connections.empty()) { + if (LogAcceptCategory(BCLog::LLMQ)) { + auto mnList = deterministicMNManager->GetListAtChainTip(); + std::string debugMsg = strprintf("CLLMQUtils::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, pindexQuorum->GetBlockHash().ToString()); + for (auto& c : connections) { + auto dmn = mnList.GetValidMN(c); + if (!dmn) { + debugMsg += strprintf(" %s (not in valid MN set anymore)\n", c.ToString()); + } else { + debugMsg += strprintf(" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString(false)); + } + } + LogPrint(BCLog::LLMQ, debugMsg.c_str()); + } + g_connman->AddMasternodeQuorumNodes(llmqType, pindexQuorum->GetBlockHash(), connections); + } +} + bool CLLMQUtils::IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash) { auto& params = Params().GetConsensus().llmqs.at(llmqType); diff --git a/src/llmq/quorums_utils.h b/src/llmq/quorums_utils.h index 14ceafcfe1e7..4a047f0c0f30 100644 --- a/src/llmq/quorums_utils.h +++ b/src/llmq/quorums_utils.h @@ -34,6 +34,8 @@ class CLLMQUtils static std::set GetQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& forMember); static std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, size_t memberCount, size_t connectionCount); + static void EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& myProTxHash, bool allowWatch); + static bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash); template From 9ef1e7cb51a77835db016edae2e9be9d3e9d8ed3 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 19 Mar 2020 11:35:44 +0100 Subject: [PATCH 2/3] Only log new quorum connections when it's actually new --- src/llmq/quorums_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llmq/quorums_utils.cpp b/src/llmq/quorums_utils.cpp index 0f66118d9fba..db4b9e878077 100644 --- a/src/llmq/quorums_utils.cpp +++ b/src/llmq/quorums_utils.cpp @@ -114,7 +114,7 @@ void CLLMQUtils::EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBl } } if (!connections.empty()) { - if (LogAcceptCategory(BCLog::LLMQ)) { + if (!g_connman->HasMasternodeQuorumNodes(llmqType, pindexQuorum->GetBlockHash()) && LogAcceptCategory(BCLog::LLMQ)) { auto mnList = deterministicMNManager->GetListAtChainTip(); std::string debugMsg = strprintf("CLLMQUtils::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, pindexQuorum->GetBlockHash().ToString()); for (auto& c : connections) { From 7f1f1d12f537fc847c0779c4aa84b065f1022b12 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 16 Mar 2020 11:06:29 +0100 Subject: [PATCH 3/3] Make EnsureQuorumConnections re-set connections in every iteration Instead of only doing it the first time. This is a preparation for the new intra-quorum connection system (which connects all members to all other members) --- src/llmq/quorums.cpp | 5 ++--- src/llmq/quorums_utils.cpp | 2 +- src/net.cpp | 10 ++++------ src/net.h | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index 4bb0b7303ffe..cdc744f98c3f 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -193,9 +193,8 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const continue; } - if (!g_connman->HasMasternodeQuorumNodes(llmqType, quorum->qc.quorumHash)) { - CLLMQUtils::EnsureQuorumConnections(llmqType, quorum->pindexQuorum, myProTxHash, allowWatch); - } + CLLMQUtils::EnsureQuorumConnections(llmqType, quorum->pindexQuorum, myProTxHash, allowWatch); + connmanQuorumsToDelete.erase(quorum->qc.quorumHash); } diff --git a/src/llmq/quorums_utils.cpp b/src/llmq/quorums_utils.cpp index db4b9e878077..a2ca3ba3b7fc 100644 --- a/src/llmq/quorums_utils.cpp +++ b/src/llmq/quorums_utils.cpp @@ -127,7 +127,7 @@ void CLLMQUtils::EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBl } LogPrint(BCLog::LLMQ, debugMsg.c_str()); } - g_connman->AddMasternodeQuorumNodes(llmqType, pindexQuorum->GetBlockHash(), connections); + g_connman->SetMasternodeQuorumNodes(llmqType, pindexQuorum->GetBlockHash(), connections); } } diff --git a/src/net.cpp b/src/net.cpp index 0448b09d9e3b..7cee6848bab0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2797,15 +2797,13 @@ bool CConnman::AddPendingMasternode(const uint256& proTxHash) return true; } -bool CConnman::AddMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set& proTxHashes) +void CConnman::SetMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set& proTxHashes) { LOCK(cs_vPendingMasternodes); - auto it = masternodeQuorumNodes.find(std::make_pair(llmqType, quorumHash)); - if (it != masternodeQuorumNodes.end()) { - return false; + auto it = masternodeQuorumNodes.emplace(std::make_pair(llmqType, quorumHash), proTxHashes); + if (!it.second) { + it.first->second = proTxHashes; } - masternodeQuorumNodes.emplace(std::make_pair(llmqType, quorumHash), proTxHashes); - return true; } bool CConnman::HasMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash) diff --git a/src/net.h b/src/net.h index b7b35a7ffb5a..893a4bdf3eb2 100644 --- a/src/net.h +++ b/src/net.h @@ -408,7 +408,7 @@ class CConnman std::vector GetAddedNodeInfo(); bool AddPendingMasternode(const uint256& proTxHash); - bool AddMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set& proTxHashes); + void SetMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set& proTxHashes); bool HasMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash); std::set GetMasternodeQuorums(Consensus::LLMQType llmqType); // also returns QWATCH nodes