Skip to content

Commit

Permalink
Do not send dash-specific requests to masternodes before we are fully…
Browse files Browse the repository at this point in the history
… connected (#1882)

* Do not send dash-specific requests to masternodes before we are fully connected

Open all masternode connections via CConnman::ThreadOpenMasternodeConnections only. Queue requests and process them after some timeout.

* drop excessive `mnodeman.`

* switch from queues to maps of pending requests

* adjust few strings, add TODO for POOL_STATE_CONNECTING

* fix

* there can be only one pending dsa request per ps client
  • Loading branch information
UdjinM6 authored Feb 1, 2018
1 parent 5a5f618 commit 1b1a440
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 97 deletions.
94 changes: 79 additions & 15 deletions src/masternodeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,48 @@ std::pair<CService, std::set<uint256> > CMasternodeMan::PopScheduledMnbRequestCo
return std::make_pair(pairFront.first, setResult);
}

void CMasternodeMan::ProcessPendingMnbRequests(CConnman& connman)
{
std::pair<CService, std::set<uint256> > p = PopScheduledMnbRequestConnection();
if (!(p.first == CService() || p.second.empty())) {
if (connman.IsMasternodeOrDisconnectRequested(p.first)) return;
mapPendingMNB.insert(std::make_pair(p.first, std::make_pair(GetTime(), p.second)));
connman.AddPendingMasternode(p.first);
}

std::map<CService, std::pair<int64_t, std::set<uint256> > >::iterator itPendingMNB = mapPendingMNB.begin();
while (itPendingMNB != mapPendingMNB.end()) {
bool fDone = connman.ForNode(itPendingMNB->first, [&](CNode* pnode) {
// compile request vector
std::vector<CInv> vToFetch;
std::set<uint256>& setHashes = itPendingMNB->second.second;
std::set<uint256>::iterator it = setHashes.begin();
while(it != setHashes.end()) {
if(*it != uint256()) {
vToFetch.push_back(CInv(MSG_MASTERNODE_ANNOUNCE, *it));
LogPrint("masternode", "-- asking for mnb %s from addr=%s\n", it->ToString(), pnode->addr.ToString());
}
++it;
}

// ask for data
CNetMsgMaker msgMaker(pnode->GetSendVersion());
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
return true;
});

int64_t nTimeAdded = itPendingMNB->second.first;
if (fDone || (GetTime() - nTimeAdded > 15)) {
if (!fDone) {
LogPrint("masternode", "CMasternodeMan::%s -- failed to connect to %s\n", __func__, itPendingMNB->first.ToString());
}
mapPendingMNB.erase(itPendingMNB++);
} else {
++itPendingMNB;
}
}
LogPrint("masternode", "%s -- mapPendingMNB size: %d\n", __func__, mapPendingMNB.size());
}

void CMasternodeMan::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
{
Expand Down Expand Up @@ -1049,25 +1091,47 @@ bool CMasternodeMan::SendVerifyRequest(const CAddress& addr, const std::vector<C
return false;
}

connman.OpenMasternodeConnection(addr);
bool fSuccess = connman.ForNode(addr, CConnman::AllNodes, [&](CNode* pnode){
netfulfilledman.AddFulfilledRequest(addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request");
// use random nonce, store it and require node to reply with correct one later
CMasternodeVerification mnv(addr, GetRandInt(999999), nCachedBlockHeight - 1);
mWeAskedForVerification[addr] = mnv;
LogPrintf("CMasternodeMan::SendVerifyRequest -- verifying node using nonce %d addr=%s\n", mnv.nonce, addr.ToString());
CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange)
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MNVERIFY, mnv));
return true;
});
if (!fSuccess) {
LogPrintf("CMasternodeMan::SendVerifyRequest -- can't connect to node to verify it, addr=%s\n", addr.ToString());
return false;
}
if (connman.IsMasternodeOrDisconnectRequested(addr)) return false;

connman.AddPendingMasternode(addr);
// use random nonce, store it and require node to reply with correct one later
CMasternodeVerification mnv(addr, GetRandInt(999999), nCachedBlockHeight - 1);
LOCK(cs_mapPendingMNV);
mapPendingMNV.insert(std::make_pair(addr, std::make_pair(GetTime(), mnv)));
LogPrintf("CMasternodeMan::SendVerifyRequest -- verifying node using nonce %d addr=%s\n", mnv.nonce, addr.ToString());
return true;
}

void CMasternodeMan::ProcessPendingMnvRequests(CConnman& connman)
{
LOCK(cs_mapPendingMNV);

std::map<CService, std::pair<int64_t, CMasternodeVerification> >::iterator itPendingMNV = mapPendingMNV.begin();

while (itPendingMNV != mapPendingMNV.end()) {
bool fDone = connman.ForNode(itPendingMNV->first, [&](CNode* pnode) {
netfulfilledman.AddFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request");
// use random nonce, store it and require node to reply with correct one later
mWeAskedForVerification[pnode->addr] = itPendingMNV->second.second;
LogPrint("masternode", "-- verifying node using nonce %d addr=%s\n", itPendingMNV->second.second.nonce, pnode->addr.ToString());
CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange)
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MNVERIFY, itPendingMNV->second.second));
return true;
});

int64_t nTimeAdded = itPendingMNV->second.first;
if (fDone || (GetTime() - nTimeAdded > 15)) {
if (!fDone) {
LogPrint("masternode", "CMasternodeMan::%s -- failed to connect to %s\n", __func__, itPendingMNV->first.ToString());
}
mapPendingMNV.erase(itPendingMNV++);
} else {
++itPendingMNV;
}
}
LogPrint("masternode", "%s -- mapPendingMNV size: %d\n", __func__, mapPendingMNV.size());
}

void CMasternodeMan::SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, CConnman& connman)
{
// only masternodes can sign this, why would someone ask regular node?
Expand Down
5 changes: 5 additions & 0 deletions src/masternodeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class CMasternodeMan
std::map<uint256, std::pair< int64_t, std::set<CNetAddr> > > mMnbRecoveryRequests;
std::map<uint256, std::vector<CMasternodeBroadcast> > mMnbRecoveryGoodReplies;
std::list< std::pair<CService, uint256> > listScheduledMnbRequestConnections;
std::map<CService, std::pair<int64_t, std::set<uint256> > > mapPendingMNB;
std::map<CService, std::pair<int64_t, CMasternodeVerification> > mapPendingMNV;
CCriticalSection cs_mapPendingMNV;

/// Set when masternodes are added, cleared when CGovernanceManager is notified
bool fMasternodesAdded;
Expand Down Expand Up @@ -180,12 +183,14 @@ class CMasternodeMan

void ProcessMasternodeConnections(CConnman& connman);
std::pair<CService, std::set<uint256> > PopScheduledMnbRequestConnection();
void ProcessPendingMnbRequests(CConnman& connman);

void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);

void DoFullVerificationStep(CConnman& connman);
void CheckSameAddr();
bool SendVerifyRequest(const CAddress& addr, const std::vector<CMasternode*>& vSortedByAddr, CConnman& connman);
void ProcessPendingMnvRequests(CConnman& connman);
void SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, CConnman& connman);
void ProcessVerifyReply(CNode* pnode, CMasternodeVerification& mnv);
void ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerification& mnv);
Expand Down
60 changes: 30 additions & 30 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,7 @@ void CConnman::ThreadOpenAddedConnections()
}
}

void CConnman::ThreadMnbRequestConnections()
void CConnman::ThreadOpenMasternodeConnections()
{
// Connecting to specific addresses, no masternode connections available
if (IsArgSet("-connect") && mapMultiArgs.at("-connect").size() > 0)
Expand All @@ -1951,34 +1951,22 @@ void CConnman::ThreadMnbRequestConnections()
if (interruptNet)
return;

std::pair<CService, std::set<uint256> > p = mnodeman.PopScheduledMnbRequestConnection();
if(p.first == CService() || p.second.empty()) continue;

// compile request vector
std::vector<CInv> vToFetch;
std::set<uint256>::iterator it = p.second.begin();
while(it != p.second.end()) {
if(*it != uint256()) {
vToFetch.push_back(CInv(MSG_MASTERNODE_ANNOUNCE, *it));
LogPrint("masternode", "ThreadMnbRequestConnections -- asking for mnb %s from addr=%s\n", it->ToString(), p.first.ToString());
LOCK(cs_vPendingMasternodes);
std::vector<CService>::iterator it = vPendingMasternodes.begin();
while (it != vPendingMasternodes.end()) {
if (!IsMasternodeOrDisconnectRequested(*it)) {
OpenMasternodeConnection(CAddress(*it, NODE_NETWORK));
// should be in the list now if connection was opened
ForNode(*it, CConnman::AllNodes, [&](CNode* pnode) {
if (pnode->fDisconnect) {
return false;
}
grant.MoveTo(pnode->grantMasternodeOutbound);
return true;
});
}
++it;
it = vPendingMasternodes.erase(it);
}

CAddress addr(p.first, NODE_NETWORK);
OpenMasternodeConnection(addr);

ForNode(addr, CConnman::AllNodes, [&](CNode* pnode) {
if (pnode->fDisconnect) return false;

grant.MoveTo(pnode->grantMasternodeOutbound);

// ask for data
CNetMsgMaker msgMaker(pnode->GetSendVersion());
PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));

return true;
});
}
}

Expand Down Expand Up @@ -2369,7 +2357,7 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c
threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this)));

// Initiate masternode connections
threadMnbRequestConnections = std::thread(&TraceThread<std::function<void()> >, "mnbcon", std::function<void()>(std::bind(&CConnman::ThreadMnbRequestConnections, this)));
threadOpenMasternodeConnections = std::thread(&TraceThread<std::function<void()> >, "mncon", std::function<void()>(std::bind(&CConnman::ThreadOpenMasternodeConnections, this)));

// Process messages
threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
Expand Down Expand Up @@ -2431,8 +2419,8 @@ void CConnman::Stop()
{
if (threadMessageHandler.joinable())
threadMessageHandler.join();
if (threadMnbRequestConnections.joinable())
threadMnbRequestConnections.join();
if (threadOpenMasternodeConnections.joinable())
threadOpenMasternodeConnections.join();
if (threadOpenConnections.joinable())
threadOpenConnections.join();
if (threadOpenAddedConnections.joinable())
Expand Down Expand Up @@ -2548,6 +2536,18 @@ bool CConnman::RemoveAddedNode(const std::string& strNode)
return false;
}

bool CConnman::AddPendingMasternode(const CService& service)
{
LOCK(cs_vPendingMasternodes);
for(std::vector<CService>::const_iterator it = vPendingMasternodes.begin(); it != vPendingMasternodes.end(); ++it) {
if (service == *it)
return false;
}

vPendingMasternodes.push_back(service);
return true;
}

size_t CConnman::GetNodeCount(NumConnections flags)
{
LOCK(cs_vNodes);
Expand Down
7 changes: 5 additions & 2 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ class CConnman

bool AddNode(const std::string& node);
bool RemoveAddedNode(const std::string& node);
bool AddPendingMasternode(const CService& addr);
std::vector<AddedNodeInfo> GetAddedNodeInfo();

size_t GetNodeCount(NumConnections num);
Expand Down Expand Up @@ -409,7 +410,7 @@ class CConnman
void AcceptConnection(const ListenSocket& hListenSocket);
void ThreadSocketHandler();
void ThreadDNSAddressSeed();
void ThreadMnbRequestConnections();
void ThreadOpenMasternodeConnections();

uint64_t CalculateKeyedNetGroup(const CAddress& ad) const;

Expand Down Expand Up @@ -475,6 +476,8 @@ class CConnman
CCriticalSection cs_vOneShots;
std::vector<std::string> vAddedNodes;
CCriticalSection cs_vAddedNodes;
std::vector<CService> vPendingMasternodes;
CCriticalSection cs_vPendingMasternodes;
std::vector<CNode*> vNodes;
std::list<CNode*> vNodesDisconnected;
mutable CCriticalSection cs_vNodes;
Expand Down Expand Up @@ -512,7 +515,7 @@ class CConnman
std::thread threadSocketHandler;
std::thread threadOpenAddedConnections;
std::thread threadOpenConnections;
std::thread threadMnbRequestConnections;
std::thread threadOpenMasternodeConnections;
std::thread threadMessageHandler;
};
extern std::unique_ptr<CConnman> g_connman;
Expand Down
Loading

0 comments on commit 1b1a440

Please sign in to comment.