From 1c6c0d8b7ea7c65c7c04bfe53bc9180b0bc87682 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 21 Dec 2016 03:55:55 +0400 Subject: [PATCH] fix AskForMN (#1217) Should also store/check node we asked for mn list entry, not outpoint only. This should help to get mn list in sync when some nodes refuse to answer thus blocking such requests for the same outpoint for the next 3h and increasing mn list inconsistency. --- src/masternodeman.cpp | 40 ++++++++++++++++++++++++++++++---------- src/masternodeman.h | 2 +- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 5d8798bd4..4ad8fb893 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -136,17 +136,29 @@ void CMasternodeMan::AskForMN(CNode* pnode, const CTxIn &vin) { if(!pnode) return; - std::map::iterator it = mWeAskedForMasternodeListEntry.find(vin.prevout); - if (it != mWeAskedForMasternodeListEntry.end() && GetTime() < (*it).second) { - // we've asked recently, should not repeat too often or we could get banned - return; + LOCK(cs); + + std::map >::iterator it1 = mWeAskedForMasternodeListEntry.find(vin.prevout); + if (it1 != mWeAskedForMasternodeListEntry.end()) { + std::map::iterator it2 = it1->second.find(pnode->addr); + if (it2 != it1->second.end()) { + if (GetTime() < it2->second) { + // we've asked recently, should not repeat too often or we could get banned + return; + } + // we asked this node for this outpoint but it's ok to ask again already + LogPrintf("CMasternodeMan::AskForMN -- Asking same peer %s for missing masternode entry again: %s\n", pnode->addr.ToString(), vin.prevout.ToStringShort()); + } else { + // we already asked for this outpoint but not this node + LogPrintf("CMasternodeMan::AskForMN -- Asking new peer %s for missing masternode entry: %s\n", pnode->addr.ToString(), vin.prevout.ToStringShort()); + } + } else { + // we never asked any node for this outpoint + LogPrintf("CMasternodeMan::AskForMN -- Asking peer %s for missing masternode entry for the first time: %s\n", pnode->addr.ToString(), vin.prevout.ToStringShort()); } + mWeAskedForMasternodeListEntry[vin.prevout][pnode->addr] = GetTime() + DSEG_UPDATE_SECONDS; - // ask for the mnb info once from the node that sent mnp - - LogPrintf("CMasternodeMan::AskForMN -- Asking node for missing masternode entry: %s\n", vin.prevout.ToStringShort()); pnode->PushMessage(NetMsgType::DSEG, vin); - mWeAskedForMasternodeListEntry[vin.prevout] = GetTime() + DSEG_UPDATE_SECONDS;; } void CMasternodeMan::Check() @@ -214,9 +226,17 @@ void CMasternodeMan::CheckAndRemove() } // check which Masternodes we've asked for - std::map::iterator it2 = mWeAskedForMasternodeListEntry.begin(); + std::map >::iterator it2 = mWeAskedForMasternodeListEntry.begin(); while(it2 != mWeAskedForMasternodeListEntry.end()){ - if((*it2).second < GetTime()){ + std::map::iterator it3 = it2->second.begin(); + while(it3 != it2->second.end()){ + if(it3->second < GetTime()){ + it2->second.erase(it3++); + } else { + ++it3; + } + } + if(it2->second.empty()) { mWeAskedForMasternodeListEntry.erase(it2++); } else { ++it2; diff --git a/src/masternodeman.h b/src/masternodeman.h index 8e4fb92c0..57e0aa173 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -117,7 +117,7 @@ private: // who we asked for the Masternode list and the last time std::map mWeAskedForMasternodeList; // which Masternodes we've asked for - std::map mWeAskedForMasternodeListEntry; + std::map > mWeAskedForMasternodeListEntry; // who we asked for the masternode verification std::map mWeAskedForVerification;