20 const std::set<uint256>& proTxHashes)
23 auto it = masternodeQuorumNodes.emplace(
QuorumTypeAndHash(llmqType, quorumHash), proTxHashes);
25 it.first->second = proTxHashes;
32 std::set<uint256> result;
33 for (
const auto& p : masternodeQuorumNodes) {
34 if (p.first.first != llmqType) {
37 result.emplace(p.first.second);
45 std::set<NodeId> result;
46 auto it = masternodeQuorumRelayMembers.find(std::make_pair(llmqType, quorumHash));
47 if (it == masternodeQuorumRelayMembers.end()) {
57 result.emplace(pnode->
GetId());
71 masternodeQuorumNodes.erase(std::make_pair(llmqType, quorumHash));
77 auto it = masternodeQuorumRelayMembers.emplace(std::make_pair(llmqType, quorumHash), proTxHashes);
79 it.first->second = proTxHashes;
89 CNetMsgMaker msgMaker(pnode->GetSendVersion());
90 connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QSENDRECSIGS, true));
91 pnode->m_masternode_iqr_connection = true;
103 auto dmn = mnList.GetMNByService(pnode->
addr);
104 if (dmn ==
nullptr) {
108 assumedProTxHash = dmn->proTxHash;
112 for (
const auto& quorumConn : masternodeQuorumNodes) {
117 }
else if (!assumedProTxHash.
IsNull()) {
118 if (quorumConn.second.count(assumedProTxHash)) {
132 for (
const auto& p : masternodeQuorumRelayMembers) {
133 if (p.second.count(protxHash) > 0) {
143 if (std::find(vPendingMasternodes.begin(), vPendingMasternodes.end(),
proTxHash) != vPendingMasternodes.end()) {
146 vPendingMasternodes.emplace_back(
proTxHash);
153 masternodePendingProbes.insert(proTxHashes.begin(), proTxHashes.end());
159 masternodeQuorumNodes.clear();
160 masternodeQuorumRelayMembers.clear();
161 vPendingMasternodes.clear();
162 masternodePendingProbes.clear();
217 const auto& chainParams =
Params();
218 bool triedConnect =
false;
222 int sleepTime = triedConnect ? 100 : (chainParams.IsRegTestNet() ? 200 : 1500);
227 triedConnect =
false;
235 std::vector<PeerData> connectedNodes;
236 std::vector<MnService> connectedMnServices;
249 bool isProbe =
false;
254 if (!vPendingMasternodes.empty()) {
255 auto dmn = mnList.GetValidMN(vPendingMasternodes.front());
256 vPendingMasternodes.erase(vPendingMasternodes.begin());
258 auto peerData = std::find(connectedNodes.begin(), connectedNodes.end(), dmn->pdmnState->addr);
259 if (peerData == std::end(connectedNodes)) {
262 __func__, dmn->proTxHash.ToString(), dmn->pdmnState->addr.ToString());
269 std::vector<CDeterministicMNCPtr> pending;
270 for (
const auto& group: masternodeQuorumNodes) {
271 for (
const auto& proRegTxHash: group.second) {
273 if (std::count(connectedMnServices.begin(), connectedMnServices.end(), proRegTxHash) > 0) {
283 const auto& dmn = mnList.GetValidMN(proRegTxHash);
285 auto peerData = std::find(connectedNodes.begin(), connectedNodes.end(), dmn->pdmnState->addr);
288 if (peerData != std::end(connectedNodes) &&
289 (peerData->f_disconnect || peerData->f_is_mn_conn)) {
296 if (currentTime - lastAttempt < chainParams.LLMQConnectionRetryTimeout()) {
299 pending.emplace_back(dmn);
303 if (!pending.empty()) {
304 dmnToConnect = pending[
GetRandInt((
int) pending.size())];
306 __func__, dmnToConnect->proTxHash.ToString(), dmnToConnect->pdmnState->addr.ToString());
312 std::vector<CDeterministicMNCPtr> pending;
313 for (
auto it = masternodePendingProbes.begin(); it != masternodePendingProbes.end(); ) {
314 auto dmn = mnList.GetMN(*it);
316 it = masternodePendingProbes.erase(it);
321 auto mnService = std::find(connectedMnServices.begin(), connectedMnServices.end(), dmn->proTxHash);
322 bool connectedAndOutbound = mnService != std::end(connectedMnServices) && !mnService->is_inbound;
323 if (connectedAndOutbound) {
326 it = masternodePendingProbes.erase(it);
334 if (currentTime - lastAttempt < chainParams.LLMQConnectionRetryTimeout()) {
337 pending.emplace_back(dmn);
341 if (!pending.empty()) {
342 dmnToConnect = pending[
GetRandInt((
int)pending.size())];
343 masternodePendingProbes.erase(dmnToConnect->proTxHash);
347 __func__, dmnToConnect->proTxHash.ToString(), dmnToConnect->pdmnState->addr.ToString());
365 if (pnode->fDisconnect) { LogPrintf(
"about to be disconnected\n");
372 __func__, dmnToConnect->proTxHash.ToString(), dmnToConnect->pdmnState->addr.ToString());
382 int nonMasternodeCount = 0;
385 nonMasternodeCount++;
403 LogPrintf(
"Closing Masternode connection: peer=%d, addr=%s\n", pnode->
GetId(), pnode->
addr.
ToString());
405 LogPrintf(
"Closing Masternode connection: peer=%d\n", pnode->
GetId());
416 ProcessMasternodeConnections(*
connman, *
this);
const CChainParams & Params()
Return the currently selected parameters.
A CService with information about it as peer.
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound=nullptr, const char *strDest=nullptr, bool fOneShot=false, bool fFeeler=false, bool fAddnode=false, bool masternode_connection=false, bool masternode_probe_connection=false)
size_t GetMaxOutboundNodeCount()
constexpr static const CAllNodes AllNodes
void ForEachNode(Callable &&func)
Information about a peer.
std::atomic< bool > m_masternode_connection
uint256 verifiedProRegTxHash
const int64_t nTimeConnected
std::atomic< bool > m_masternode_probe_connection
std::atomic< bool > m_masternode_iqr_connection
std::atomic_bool fDisconnect
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToStringIPPort() const
std::string ToString() const
bool sleep_for(std::chrono::milliseconds rel_time)
PeerData(const CService &s, bool disconnect, bool is_mn_conn)
bool operator==(const CService &s) const
bool hasQuorumNodes(Consensus::LLMQType llmqType, const uint256 &quorumHash)
std::thread threadOpenMasternodeConnections
void addPendingProbeConnections(const std::set< uint256 > &proTxHashes)
void ThreadOpenMasternodeConnections()
RecursiveMutex cs_vPendingMasternodes
bool isMasternodeQuorumRelayMember(const uint256 &protxHash)
void start(CScheduler &scheduler, const TierTwoConnMan::Options &options)
std::pair< Consensus::LLMQType, uint256 > QuorumTypeAndHash
void openConnection(const CAddress &addrConnect, bool isProbe)
void setMasternodeQuorumRelayMembers(Consensus::LLMQType llmqType, const uint256 &quorumHash, const std::set< uint256 > &proTxHashes)
TierTwoConnMan(CConnman *_connman)
bool isMasternodeQuorumNode(const CNode *pnode)
void setQuorumNodes(Consensus::LLMQType llmqType, const uint256 &quorumHash, const std::set< uint256 > &proTxHashes)
CThreadInterrupt interruptNet
std::set< uint256 > getQuorumNodes(Consensus::LLMQType llmqType)
bool addPendingMasternode(const uint256 &proTxHash)
void removeQuorumNodes(Consensus::LLMQType llmqType, const uint256 &quorumHash)
bool IsBlockchainSynced() const
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
std::shared_ptr< const CDeterministicMN > CDeterministicMNCPtr
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
int GetRandInt(int nMax) noexcept
uint256 verif_proreg_tx_hash
bool operator==(const uint256 &hash) const
bool m_has_specified_outgoing
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::atomic< bool > fMasterNode
void TraceThread(const std::string name, Callable func)
TierTwoSyncState g_tiertwo_sync_state
int64_t GetAdjustedTime()
const uint256 UINT256_ZERO
constant uint256 instances
int64_t GetSystemTimeInSeconds()
Returns the system time (not mockable)