13 #include "validation.h"
30 if (proTxHash1 < proTxHash2) {
31 h1 =
::SerializeHash(std::make_tuple(proTxHash1, proTxHash2, proTxHash1));
32 h2 =
::SerializeHash(std::make_tuple(proTxHash1, proTxHash2, proTxHash2));
34 h1 =
::SerializeHash(std::make_tuple(proTxHash2, proTxHash1, proTxHash1));
35 h2 =
::SerializeHash(std::make_tuple(proTxHash2, proTxHash1, proTxHash2));
44 unsigned int forMemberIndex)
46 assert(forMemberIndex < mnList.size());
49 if (mnList.size() == 2) {
50 return {mnList[1 - forMemberIndex]->proTxHash};
58 int gap_max = (int)mnList.size() - 1;
60 while ((gap_max >>= 1) || k <= 1) {
61 size_t idx = (forMemberIndex + gap) % mnList.size();
69 static std::set<uint256> GetQuorumConnections(
const std::vector<CDeterministicMNCPtr>& mns,
const uint256& forMember,
bool onlyOutbound)
71 std::set<uint256> result;
72 for (
auto& dmn : mns) {
73 if (dmn->proTxHash == forMember) {
80 if (!onlyOutbound || deterministicOutbound == dmn->proTxHash) {
81 result.emplace(dmn->proTxHash);
89 static uint256 qwatchConnectionSeed;
90 static std::atomic<bool> qwatchConnectionSeedGenerated{
false};
92 if (!qwatchConnectionSeedGenerated) {
93 LOCK(qwatchConnectionSeedCs);
94 if (!qwatchConnectionSeedGenerated) {
96 qwatchConnectionSeedGenerated =
true;
100 std::set<size_t> result;
101 uint256 rnd = qwatchConnectionSeed;
102 for (
size_t i = 0; i < connectionCount; i++) {
104 result.emplace(rnd.
GetUint64(0) % memberCount);
113 auto connman =
g_connman->GetTierTwoConnMan();
115 auto connmanQuorumsToDelete = connman->getQuorumNodes(llmqType);
118 int curDkgHeight = pindexNew->
nHeight - (pindexNew->
nHeight % params.dkgInterval);
120 connmanQuorumsToDelete.erase(curDkgBlock);
122 for (
auto& quorum : lastQuorums) {
123 if (!quorum->IsMember(myProTxHash)) {
129 connmanQuorumsToDelete.erase(quorum->pindexQuorum->GetBlockHash());
132 for (
auto& qh : connmanQuorumsToDelete) {
133 LogPrintf(
"CQuorumManager::%s -- removing masternodes quorum connections for quorum %s:\n", __func__, qh.ToString());
134 connman->removeQuorumNodes(llmqType, qh);
142 auto itMember = std::find_if(members.begin(), members.end(), [&](
const CDeterministicMNCPtr& dmn) { return dmn->proTxHash == myProTxHash; });
143 bool isMember = itMember != members.end();
149 std::set<uint256> connections;
150 std::set<uint256> relayMembers;
152 connections = GetQuorumConnections(members, myProTxHash,
true);
153 unsigned int memberIndex = itMember - members.begin();
157 for (
auto idx : cindexes) {
158 connections.emplace(members[idx]->
proTxHash);
160 relayMembers = connections;
162 if (!connections.empty()) {
163 auto connman =
g_connman->GetTierTwoConnMan();
166 std::string debugMsg =
strprintf(
"CLLMQUtils::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, pindexQuorum->
GetBlockHash().
ToString());
167 for (
auto& c : connections) {
168 auto dmn = mnList.GetValidMN(c);
170 debugMsg +=
strprintf(
" %s (not in valid MN set anymore)\n", c.ToString());
172 debugMsg +=
strprintf(
" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString());
177 connman->setQuorumNodes(llmqType, pindexQuorum->
GetBlockHash(), connections);
179 if (!relayMembers.empty()) {
180 auto connman =
g_connman->GetTierTwoConnMan();
181 connman->setMasternodeQuorumRelayMembers(llmqType, pindexQuorum->
GetBlockHash(), relayMembers);
190 std::set<uint256> probeConnections;
191 for (
auto& dmn : members) {
192 if (dmn->proTxHash == myProTxHash) {
198 if (curTime - lastOutbound > 50 * 60) {
199 probeConnections.emplace(dmn->proTxHash);
203 if (!probeConnections.empty()) {
206 std::string debugMsg =
strprintf(
"CLLMQUtils::%s -- adding masternodes probes for quorum %s:\n", __func__, pindexQuorum->
GetBlockHash().
ToString());
207 for (
auto& c : probeConnections) {
208 auto dmn = mnList.GetValidMN(c);
210 debugMsg +=
strprintf(
" %s (not in valid MN set anymore)\n", c.ToString());
212 debugMsg +=
strprintf(
" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString());
217 g_connman->GetTierTwoConnMan()->addPendingProbeConnections(probeConnections);
const CChainParams & Params()
Return the currently selected parameters.
The block chain is a tree shaped structure starting with the genesis block at the root,...
uint256 GetBlockHash() const
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
const Consensus::Params & GetConsensus() const
std::string ToString() const
uint64_t GetUint64(int pos) const
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
std::shared_ptr< const CDeterministicMN > CDeterministicMNCPtr
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
uint256 DeterministicOutboundConnection(const uint256 &proTxHash1, const uint256 &proTxHash2)
void EnsureLatestQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexNew, const uint256 &myProTxHash, std::vector< CQuorumCPtr > &lastQuorums)
void EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &myProTxHash)
void AddQuorumProbeConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &myProTxHash)
std::set< size_t > CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, size_t memberCount, size_t connectionCount)
std::set< uint256 > GetQuorumRelayMembers(const std::vector< CDeterministicMNCPtr > &mnList, unsigned int forMemberIndex)
uint256 GetRandHash() noexcept
std::map< LLMQType, LLMQParams > llmqs
int64_t GetAdjustedTime()