Multiple mnb recovery (#1297)
* ask for multiple mnb hashes for recovery * address comments, lock cs_vNodes and add/relese ref * add parentheses
This commit is contained in:
parent
e2eaf1d0d7
commit
572c554681
@ -161,16 +161,6 @@ void CMasternodeMan::AskForMN(CNode* pnode, const CTxIn &vin)
|
|||||||
pnode->PushMessage(NetMsgType::DSEG, vin);
|
pnode->PushMessage(NetMsgType::DSEG, vin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMasternodeMan::AskForMnb(CNode* pnode, const uint256 &hash)
|
|
||||||
{
|
|
||||||
if(!pnode || hash == uint256()) return;
|
|
||||||
|
|
||||||
LogPrint("masternode", "CMasternodeMan::AskForMnb -- asking for mnb %s from addr=%s\n", hash.ToString(), pnode->addr.ToString());
|
|
||||||
std::vector<CInv> vToFetch;
|
|
||||||
vToFetch.push_back(CInv(MSG_MASTERNODE_ANNOUNCE, hash));
|
|
||||||
pnode->PushMessage(NetMsgType::GETDATA, vToFetch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMasternodeMan::Check()
|
void CMasternodeMan::Check()
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
@ -198,7 +188,8 @@ void CMasternodeMan::CheckAndRemove()
|
|||||||
// Remove spent masternodes, prepare structures and make requests to reasure the state of inactive ones
|
// Remove spent masternodes, prepare structures and make requests to reasure the state of inactive ones
|
||||||
std::vector<CMasternode>::iterator it = vMasternodes.begin();
|
std::vector<CMasternode>::iterator it = vMasternodes.begin();
|
||||||
std::vector<std::pair<int, CMasternode> > vecMasternodeRanks;
|
std::vector<std::pair<int, CMasternode> > vecMasternodeRanks;
|
||||||
bool fAskedForMnbRecovery = false; // ask for one mn at a time
|
// ask for up to MNB_RECOVERY_MAX_ASK_ENTRIES masternode entries at a time
|
||||||
|
int nAskForMnbRecovery = MNB_RECOVERY_MAX_ASK_ENTRIES;
|
||||||
while(it != vMasternodes.end()) {
|
while(it != vMasternodes.end()) {
|
||||||
CMasternodeBroadcast mnb = CMasternodeBroadcast(*it);
|
CMasternodeBroadcast mnb = CMasternodeBroadcast(*it);
|
||||||
uint256 hash = mnb.GetHash();
|
uint256 hash = mnb.GetHash();
|
||||||
@ -216,7 +207,7 @@ void CMasternodeMan::CheckAndRemove()
|
|||||||
fMasternodesRemoved = true;
|
fMasternodesRemoved = true;
|
||||||
} else {
|
} else {
|
||||||
bool fAsk = pCurrentBlockIndex &&
|
bool fAsk = pCurrentBlockIndex &&
|
||||||
!fAskedForMnbRecovery &&
|
(nAskForMnbRecovery > 0) &&
|
||||||
masternodeSync.IsSynced() &&
|
masternodeSync.IsSynced() &&
|
||||||
it->IsNewStartRequired() &&
|
it->IsNewStartRequired() &&
|
||||||
!IsMnbRecoveryRequested(hash);
|
!IsMnbRecoveryRequested(hash);
|
||||||
@ -228,7 +219,8 @@ void CMasternodeMan::CheckAndRemove()
|
|||||||
int nRandomBlockHeight = GetRandInt(pCurrentBlockIndex->nHeight);
|
int nRandomBlockHeight = GetRandInt(pCurrentBlockIndex->nHeight);
|
||||||
vecMasternodeRanks = GetMasternodeRanks(nRandomBlockHeight);
|
vecMasternodeRanks = GetMasternodeRanks(nRandomBlockHeight);
|
||||||
}
|
}
|
||||||
// ask first MNB_RECOVERY_QUORUM_TOTAL mns we can connect to and we haven't asked recently
|
bool fAskedForMnbRecovery = false;
|
||||||
|
// ask first MNB_RECOVERY_QUORUM_TOTAL masternodes we can connect to and we haven't asked recently
|
||||||
for(int i = 0; setRequested.size() < MNB_RECOVERY_QUORUM_TOTAL && i < (int)vecMasternodeRanks.size(); i++) {
|
for(int i = 0; setRequested.size() < MNB_RECOVERY_QUORUM_TOTAL && i < (int)vecMasternodeRanks.size(); i++) {
|
||||||
// avoid banning
|
// avoid banning
|
||||||
if(mWeAskedForMasternodeListEntry.count(it->vin.prevout) && mWeAskedForMasternodeListEntry[it->vin.prevout].count(vecMasternodeRanks[i].second.addr)) continue;
|
if(mWeAskedForMasternodeListEntry.count(it->vin.prevout) && mWeAskedForMasternodeListEntry[it->vin.prevout].count(vecMasternodeRanks[i].second.addr)) continue;
|
||||||
@ -238,6 +230,10 @@ void CMasternodeMan::CheckAndRemove()
|
|||||||
listScheduledMnbRequestConnections.push_back(std::make_pair(addr, hash));
|
listScheduledMnbRequestConnections.push_back(std::make_pair(addr, hash));
|
||||||
fAskedForMnbRecovery = true;
|
fAskedForMnbRecovery = true;
|
||||||
}
|
}
|
||||||
|
if(fAskedForMnbRecovery) {
|
||||||
|
LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Recovery initiated, masternode=%s\n", it->vin.prevout.ToStringShort());
|
||||||
|
nAskForMnbRecovery--;
|
||||||
|
}
|
||||||
// wait for mnb recovery replies for MNB_RECOVERY_WAIT_SECONDS seconds
|
// wait for mnb recovery replies for MNB_RECOVERY_WAIT_SECONDS seconds
|
||||||
mMnbRecoveryRequests[hash] = std::make_pair(GetTime() + MNB_RECOVERY_WAIT_SECONDS, setRequested);
|
mMnbRecoveryRequests[hash] = std::make_pair(GetTime() + MNB_RECOVERY_WAIT_SECONDS, setRequested);
|
||||||
}
|
}
|
||||||
@ -773,13 +769,31 @@ void CMasternodeMan::ProcessMasternodeConnections()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<CService, uint256> CMasternodeMan::PopScheduledMnbRequestConnection()
|
std::pair<CService, std::set<uint256> > CMasternodeMan::PopScheduledMnbRequestConnection()
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
if(listScheduledMnbRequestConnections.empty()) return make_pair(CService(), uint256());
|
if(listScheduledMnbRequestConnections.empty()) {
|
||||||
std::pair<CService, uint256> p = listScheduledMnbRequestConnections.front();
|
return std::make_pair(CService(), std::set<uint256>());
|
||||||
listScheduledMnbRequestConnections.pop_front();
|
}
|
||||||
return p;
|
|
||||||
|
std::set<uint256> setResult;
|
||||||
|
|
||||||
|
listScheduledMnbRequestConnections.sort();
|
||||||
|
std::pair<CService, uint256> pairFront = listScheduledMnbRequestConnections.front();
|
||||||
|
|
||||||
|
// squash hashes from requests with the same CService as the first one into setResult
|
||||||
|
std::list< std::pair<CService, uint256> >::iterator it = listScheduledMnbRequestConnections.begin();
|
||||||
|
while(it != listScheduledMnbRequestConnections.end()) {
|
||||||
|
if(pairFront.first == it->first) {
|
||||||
|
setResult.insert(it->second);
|
||||||
|
it = listScheduledMnbRequestConnections.erase(it);
|
||||||
|
} else {
|
||||||
|
// since list is sorted now, we can be sure that there is no more hashes left
|
||||||
|
// to ask for from this addr
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_pair(pairFront.first, setResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ private:
|
|||||||
|
|
||||||
static const int MNB_RECOVERY_QUORUM_TOTAL = 10;
|
static const int MNB_RECOVERY_QUORUM_TOTAL = 10;
|
||||||
static const int MNB_RECOVERY_QUORUM_REQUIRED = 6;
|
static const int MNB_RECOVERY_QUORUM_REQUIRED = 6;
|
||||||
|
static const int MNB_RECOVERY_MAX_ASK_ENTRIES = 10;
|
||||||
static const int MNB_RECOVERY_WAIT_SECONDS = 60;
|
static const int MNB_RECOVERY_WAIT_SECONDS = 60;
|
||||||
static const int MNB_RECOVERY_RETRY_SECONDS = 3 * 60 * 60;
|
static const int MNB_RECOVERY_RETRY_SECONDS = 3 * 60 * 60;
|
||||||
|
|
||||||
@ -297,7 +298,7 @@ public:
|
|||||||
CMasternode* GetMasternodeByRank(int nRank, int nBlockHeight, int nMinProtocol=0, bool fOnlyActive=true);
|
CMasternode* GetMasternodeByRank(int nRank, int nBlockHeight, int nMinProtocol=0, bool fOnlyActive=true);
|
||||||
|
|
||||||
void ProcessMasternodeConnections();
|
void ProcessMasternodeConnections();
|
||||||
std::pair<CService, uint256> PopScheduledMnbRequestConnection();
|
std::pair<CService, std::set<uint256> > PopScheduledMnbRequestConnection();
|
||||||
|
|
||||||
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
||||||
|
|
||||||
|
36
src/net.cpp
36
src/net.cpp
@ -1700,23 +1700,41 @@ void ThreadMnbRequestConnections()
|
|||||||
if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
|
if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int nTick = 0;
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
MilliSleep(1000);
|
MilliSleep(1000);
|
||||||
nTick++;
|
|
||||||
|
|
||||||
CSemaphoreGrant grant(*semMasternodeOutbound);
|
CSemaphoreGrant grant(*semMasternodeOutbound);
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
std::pair<CService, uint256> p = mnodeman.PopScheduledMnbRequestConnection();
|
std::pair<CService, std::set<uint256> > p = mnodeman.PopScheduledMnbRequestConnection();
|
||||||
if(p.first == CService()) continue;
|
if(p.first == CService() || p.second.empty()) continue;
|
||||||
CNode* pnode = ConnectNode(CAddress(p.first), NULL, true);
|
|
||||||
if(pnode) {
|
CNode* pnode = NULL;
|
||||||
grant.MoveTo(pnode->grantMasternodeOutbound);
|
{
|
||||||
if(p.second != uint256())
|
LOCK(cs_vNodes);
|
||||||
mnodeman.AskForMnb(pnode, p.second);
|
pnode = ConnectNode(CAddress(p.first), NULL, true);
|
||||||
|
if(!pnode) continue;
|
||||||
|
pnode->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grant.MoveTo(pnode->grantMasternodeOutbound);
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ask for data
|
||||||
|
pnode->PushMessage(NetMsgType::GETDATA, vToFetch);
|
||||||
|
|
||||||
|
pnode->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user