Skip to content

Commit 15d70e7

Browse files
committed
net_mn: connect MN probing connections functionality.
1 parent b5074b4 commit 15d70e7

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

src/tiertwo/net_masternodes.cpp

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ bool TierTwoConnMan::isMasternodeQuorumNode(const CNode* pnode)
6868
return false;
6969
}
7070

71+
void TierTwoConnMan::addPendingProbeConnections(const std::set<uint256>& proTxHashes)
72+
{
73+
LOCK(cs_vPendingMasternodes);
74+
masternodePendingProbes.insert(proTxHashes.begin(), proTxHashes.end());
75+
}
76+
7177
void TierTwoConnMan::start(CScheduler& scheduler)
7278
{
7379
// Must be started after connman
@@ -94,10 +100,10 @@ void TierTwoConnMan::interrupt()
94100
interruptNet();
95101
}
96102

97-
void TierTwoConnMan::openConnection(const CAddress& addrConnect)
103+
void TierTwoConnMan::openConnection(const CAddress& addrConnect, bool isProbe)
98104
{
99105
if (interruptNet) return;
100-
connman->OpenNetworkConnection(addrConnect, false, nullptr, nullptr, false, false, false, true);
106+
connman->OpenNetworkConnection(addrConnect, false, nullptr, nullptr, false, false, false, true, isProbe);
101107
}
102108

103109
class PeerData {
@@ -109,6 +115,13 @@ class PeerData {
109115
bool operator==(const CService& s) const { return service == s; }
110116
};
111117

118+
struct MnService {
119+
public:
120+
uint256 verif_proreg_tx_hash{UINT256_ZERO};
121+
bool is_inbound{false};
122+
bool operator==(const uint256& hash) const { return verif_proreg_tx_hash == hash; }
123+
};
124+
112125
void TierTwoConnMan::ThreadOpenMasternodeConnections()
113126
{
114127
const auto& chainParams = Params();
@@ -131,11 +144,11 @@ void TierTwoConnMan::ThreadOpenMasternodeConnections()
131144
// Gather all connected peers first, so we don't
132145
// try to connect to an already connected peer
133146
std::vector<PeerData> connectedNodes;
134-
std::set<uint256> connectedProRegTxHashes;
147+
std::vector<MnService> connectedProRegTxHashes;
135148
connman->ForEachNode([&](const CNode* pnode) {
136149
connectedNodes.emplace_back(PeerData{pnode->addr, pnode->fDisconnect, pnode->m_masternode_connection});
137150
if (!pnode->verifiedProRegTxHash.IsNull()) {
138-
connectedProRegTxHashes.emplace(pnode->verifiedProRegTxHash);
151+
connectedProRegTxHashes.emplace_back(MnService{pnode->verifiedProRegTxHash, pnode->fInbound});
139152
}
140153
});
141154

@@ -144,13 +157,14 @@ void TierTwoConnMan::ThreadOpenMasternodeConnections()
144157
// Current list
145158
auto mnList = deterministicMNManager->GetListAtChainTip();
146159
int64_t currentTime = GetAdjustedTime();
160+
bool isProbe = false;
147161
{
148162
LOCK(cs_vPendingMasternodes);
149163
std::vector<CDeterministicMNCPtr> pending;
150164
for (const auto& group: masternodeQuorumNodes) {
151165
for (const auto& proRegTxHash: group.second) {
152166
// Skip if already have this member connected
153-
if (connectedProRegTxHashes.count(proRegTxHash)) continue;
167+
if (std::count(connectedProRegTxHashes.begin(), connectedProRegTxHashes.end(), proRegTxHash) > 0) continue;
154168

155169
// Check if DMN exists in tip list
156170
const auto& dmn = mnList.GetValidMN(proRegTxHash);
@@ -171,13 +185,52 @@ void TierTwoConnMan::ThreadOpenMasternodeConnections()
171185
pending.emplace_back(dmn);
172186
}
173187
}
174-
// todo: add proving system.
175188
// Select a random node to connect
176189
if (!pending.empty()) {
177190
dmnToConnect = pending[GetRandInt((int)pending.size())];
178191
LogPrint(BCLog::NET_MN, "TierTwoConnMan::%s -- opening quorum connection to %s, service=%s\n",
179192
__func__, dmnToConnect->proTxHash.ToString(), dmnToConnect->pdmnState->addr.ToString());
180193
}
194+
195+
// If no node was selected, let's try to probe nodes connection
196+
if (!dmnToConnect) {
197+
for (auto it = masternodePendingProbes.begin(); it != masternodePendingProbes.end(); ) {
198+
auto dmn = mnList.GetMN(*it);
199+
if (!dmn) {
200+
it = masternodePendingProbes.erase(it);
201+
continue;
202+
}
203+
204+
// Discard already connected outbound MNs
205+
auto mnService = std::find(connectedProRegTxHashes.begin(), connectedProRegTxHashes.end(), dmn->proTxHash);
206+
bool connectedAndOutbound = mnService != std::end(connectedProRegTxHashes) && !mnService->is_inbound;
207+
if (connectedAndOutbound) {
208+
// we already have an outbound connection to this MN so there is no eed to probe it again
209+
g_mmetaman.GetMetaInfo(dmn->proTxHash)->SetLastOutboundSuccess(currentTime);
210+
it = masternodePendingProbes.erase(it);
211+
continue;
212+
}
213+
214+
++it;
215+
216+
int64_t lastAttempt = g_mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastOutboundAttempt();
217+
// back off trying connecting to an address if we already tried recently
218+
if (currentTime - lastAttempt < chainParams.LLMQConnectionRetryTimeout()) {
219+
continue;
220+
}
221+
pending.emplace_back(dmn);
222+
}
223+
224+
// Select a random node to connect
225+
if (!pending.empty()) {
226+
dmnToConnect = pending[GetRandInt((int)pending.size())];
227+
masternodePendingProbes.erase(dmnToConnect->proTxHash);
228+
isProbe = true;
229+
230+
LogPrint(BCLog::NET_MN, "CConnman::%s -- probing masternode %s, service=%s\n",
231+
__func__, dmnToConnect->proTxHash.ToString(), dmnToConnect->pdmnState->addr.ToString());
232+
}
233+
}
181234
}
182235

183236
// No DMN to connect
@@ -190,7 +243,7 @@ void TierTwoConnMan::ThreadOpenMasternodeConnections()
190243
triedConnect = true;
191244

192245
// Now connect
193-
openConnection(CAddress(dmnToConnect->pdmnState->addr, NODE_NETWORK));
246+
openConnection(CAddress(dmnToConnect->pdmnState->addr, NODE_NETWORK), isProbe);
194247
// should be in the list now if connection was opened
195248
bool connected = connman->ForNode(dmnToConnect->pdmnState->addr, CConnman::AllNodes, [&](CNode* pnode) {
196249
if (pnode->fDisconnect) {

src/tiertwo/net_masternodes.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class TierTwoConnMan
3939
// Returns true if the node has the same address as a MN.
4040
bool isMasternodeQuorumNode(const CNode* pnode);
4141

42+
// Adds the DMNs to the pending to probe list
43+
void addPendingProbeConnections(const std::set<uint256>& proTxHashes);
44+
4245
// Manages the MN connections
4346
void ThreadOpenMasternodeConnections();
4447
void start(CScheduler& scheduler);
@@ -53,11 +56,12 @@ class TierTwoConnMan
5356
std::vector<uint256> vPendingMasternodes GUARDED_BY(cs_vPendingMasternodes);
5457
typedef std::pair<Consensus::LLMQType, uint256> QuorumTypeAndHash;
5558
std::map<QuorumTypeAndHash, std::set<uint256>> masternodeQuorumNodes GUARDED_BY(cs_vPendingMasternodes);
59+
std::set<uint256> masternodePendingProbes GUARDED_BY(cs_vPendingMasternodes);
5660

5761
// parent connections manager
5862
CConnman* connman;
5963

60-
void openConnection(const CAddress& addrConnect);
64+
void openConnection(const CAddress& addrConnect, bool isProbe);
6165
void doMaintenance();
6266
};
6367

0 commit comments

Comments
 (0)