From 003a1b7d72cbf753b7394c473d88a6be0df5a643 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 24 Feb 2015 13:39:29 +0300 Subject: [PATCH] track lastTimeChanged for mnodeman and ask for update only if UpdateNeeded --- src/darksend.cpp | 29 +++++++++++++++-------------- src/masternode.cpp | 2 +- src/masternodeman.cpp | 24 +++++++++++++++--------- src/masternodeman.h | 12 ++++++++++-- src/rpcdarksend.cpp | 1 - 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/darksend.cpp b/src/darksend.cpp index 1e0910da9..dbb6d7880 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -2172,19 +2172,20 @@ void ThreadCheckDarkSendPool() darkSendPool.ProcessMasternodeConnections(); masternodePayments.CleanPaymentList(); CleanTransactionLocksList(); - } - // nodes refuse to relay dseep if it was less then MASTERNODE_MIN_DSEEP_SECONDS ago - // MASTERNODE_PING_WAIT_SECONDS gives some additional time on top of it - if(c % (MASTERNODE_MIN_DSEEP_SECONDS + MASTERNODE_PING_WAIT_SECONDS) == 0) - { - LOCK(cs_main); - /* - cs_main is required for doing CMasternode.Check because something - is modifying the coins view without a mempool lock. It causes - segfaults from this code without the cs_main lock. - */ - mnodeman.CheckAndRemove(); + // nodes refuse to relay dseep if it was less then MASTERNODE_MIN_DSEEP_SECONDS ago + // MASTERNODE_PING_WAIT_SECONDS gives some additional time on top of it + // so we have a timeout for this check on start unless we need to + if(c > MASTERNODE_MIN_DSEEP_SECONDS + MASTERNODE_PING_WAIT_SECONDS || mnodeman.UpdateNeeded()) + { + LOCK(cs_main); + /* + cs_main is required for doing CMasternode.Check because something + is modifying the coins view without a mempool lock. It causes + segfaults from this code without the cs_main lock. + */ + mnodeman.CheckAndRemove(); + } } if(c % MASTERNODE_PING_SECONDS == 0) activeMasternode.ManageStatus(); @@ -2206,8 +2207,8 @@ void ThreadCheckDarkSendPool() LogPrintf("Successfully synced, asking for Masternode list and payment list\n"); - //request full mn list only if we didn't load them from masternodes.dat yet - if(mnodeman.size() == 0) pnode->PushMessage("dseg", CTxIn()); + //request full mn list only if masternodes.dat was updated quite a long time ago + if(mnodeman.UpdateNeeded()) pnode->PushMessage("dseg", CTxIn()); pnode->PushMessage("mnget"); //sync payees pnode->PushMessage("getsporks"); //get current network sporks diff --git a/src/masternode.cpp b/src/masternode.cpp index 436d30eae..07842abe5 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -387,7 +387,7 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight) } //if we can't find new MN to get paid, pick first active MN counting back from the end of vecLastPayments list - if(newWinner.nBlockHeight == 0 && mnodeman.size() > 0) + if(newWinner.nBlockHeight == 0 && mnodeman.CountEnabled() > 0) { BOOST_REVERSE_FOREACH(CTxIn& vinLP, vecLastPayments) { diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index f65729072..fcdfe0458 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -158,6 +158,7 @@ CMasternode *CMasternodeMan::FindNotInVec(const std::vector &vVins) BOOST_FOREACH(CMasternode &mn, vMasternodes) { mn.Check(); + UpdateLastTimeChanged(); if(!mn.IsEnabled()) continue; bool found = false; @@ -188,6 +189,7 @@ bool CMasternodeMan::Add(CMasternode &mn) if (!pmn) { vMasternodes.push_back(mn); + UpdateLastTimeChanged(); return true; } @@ -198,6 +200,7 @@ void CMasternodeMan::Check() { LOCK(cs); + UpdateLastTimeChanged(); BOOST_FOREACH(CMasternode& mn, vMasternodes) mn.Check(); } @@ -206,15 +209,11 @@ void CMasternodeMan::CheckAndRemove() { LOCK(cs); - vector::iterator it = vMasternodes.begin(); - //check them separately - while(it != vMasternodes.end()){ - (*it).Check(); - ++it; - } + Check(); + UpdateLastTimeChanged(); //remove inactive - it = vMasternodes.begin(); + vector::iterator it = vMasternodes.begin(); while(it != vMasternodes.end()){ if((*it).activeState == 4 || (*it).activeState == 3){ LogPrintf("Removing inactive masternode %s\n", (*it).addr.ToString().c_str()); @@ -230,6 +229,8 @@ int CMasternodeMan::CountMasternodesAboveProtocol(int protocolVersion) int i = 0; BOOST_FOREACH(CMasternode& mn, vMasternodes) { + mn.Check(); + UpdateLastTimeChanged(); if(mn.protocolVersion < protocolVersion || !mn.IsEnabled()) continue; i++; } @@ -242,8 +243,9 @@ int CMasternodeMan::CountEnabled() int i = 0; BOOST_FOREACH(CMasternode& mn, vMasternodes) { - if(!mn.IsEnabled()) continue; - i++; + mn.Check(); + UpdateLastTimeChanged(); + if(mn.IsEnabled()) i++; } return i; @@ -257,6 +259,7 @@ CMasternode* CMasternodeMan::GetCurrentMasterNode(int mod, int64_t nBlockHeight, // scan for winner BOOST_FOREACH(CMasternode& mn, vMasternodes) { mn.Check(); + UpdateLastTimeChanged(); if(mn.protocolVersion < minProtocol || !mn.IsEnabled()) continue; // calculate the score for each masternode @@ -282,6 +285,7 @@ int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int64_t nBlockHeight, in BOOST_FOREACH(CMasternode& mn, vMasternodes) { mn.Check(); + UpdateLastTimeChanged(); if(mn.protocolVersion < minProtocol) continue; if(!mn.IsEnabled()) { @@ -391,6 +395,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData // after that they just need to match if(count == -1 && mn->pubkey == pubkey && !mn->UpdatedWithin(MASTERNODE_MIN_DSEE_SECONDS)){ mn->UpdateLastSeen(); + UpdateLastTimeChanged(); if(mn->now < sigTime){ //take the newest entry LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str()); @@ -507,6 +512,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData if(!mn->UpdatedWithin(MASTERNODE_MIN_DSEEP_SECONDS)) { + UpdateLastTimeChanged(); if(stop) mn->Disable(); else { diff --git a/src/masternodeman.h b/src/masternodeman.h index 16ff17ccf..a7f85a84b 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -50,6 +50,9 @@ private: // map to hold all MNs std::vector vMasternodes; + // keep track of latest time whem vMasternodes was changed + int64_t lastTimeChanged; + public: IMPLEMENT_SERIALIZE @@ -61,6 +64,7 @@ public: LOCK(cs); unsigned char nVersion = 0; READWRITE(nVersion); + READWRITE(lastTimeChanged); READWRITE(vMasternodes); } ) @@ -87,7 +91,7 @@ public: void CheckAndRemove(); // Clear masternode vector - void Clear() { vMasternodes.clear(); } + void Clear() { vMasternodes.clear(); lastTimeChanged = 0; } // Return the number of (unique) masternodes int size() { return vMasternodes.size(); } @@ -101,10 +105,14 @@ public: int CountEnabled(); - std::vector GetFullMasternodeVector() { return vMasternodes; } + std::vector GetFullMasternodeVector() { Check(); return vMasternodes; } void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); + void UpdateLastTimeChanged() { lastTimeChanged = GetAdjustedTime(); } + + bool UpdateNeeded() { return lastTimeChanged < GetAdjustedTime() - MASTERNODE_REMOVAL_SECONDS; } + }; #endif diff --git a/src/rpcdarksend.cpp b/src/rpcdarksend.cpp index 31890a3fd..b4b1b668d 100644 --- a/src/rpcdarksend.cpp +++ b/src/rpcdarksend.cpp @@ -558,7 +558,6 @@ Value masternodelist(const Array& params, bool fHelp) Object obj; std::vector vMasternodes = mnodeman.GetFullMasternodeVector(); BOOST_FOREACH(CMasternode& mn, vMasternodes) { - mn.Check(); std::string strAddr = mn.addr.ToString().c_str(); if(strMode == "active"){