Skip to content

Commit 2e05bf2

Browse files
committed
Change the way changes are handled:
- do not keep track of a single time variable for whole structure change - save to masternode.dat and clear on checks: - who's asked for the masternode list and the last time - who we asked for the masternode list and the last time (will help to prevent dseg ban when restart wallet several times in short period of time) - which masternodes we've asked for - do not use timeout for CheckAndRemove (played with that - doesn't make sense actually)
1 parent 0d51e1c commit 2e05bf2

File tree

4 files changed

+137
-119
lines changed

4 files changed

+137
-119
lines changed

src/darksend.cpp

+10-16
Original file line numberDiff line numberDiff line change
@@ -2168,24 +2168,18 @@ void ThreadCheckDarkSendPool()
21682168
//LogPrintf("ThreadCheckDarkSendPool::check timeout\n");
21692169
darkSendPool.CheckTimeout();
21702170

2171-
if(c % 60 == 0){
2171+
if(c % 60 == 0)
2172+
{
2173+
LOCK(cs_main);
2174+
/*
2175+
cs_main is required for doing CMasternode.Check because something
2176+
is modifying the coins view without a mempool lock. It causes
2177+
segfaults from this code without the cs_main lock.
2178+
*/
2179+
mnodeman.CheckAndRemove();
21722180
darkSendPool.ProcessMasternodeConnections();
21732181
masternodePayments.CleanPaymentList();
21742182
CleanTransactionLocksList();
2175-
2176-
// nodes refuse to relay dseep if it was less then MASTERNODE_MIN_DSEEP_SECONDS ago
2177-
// MASTERNODE_PING_WAIT_SECONDS gives some additional time on top of it
2178-
// so we have a timeout for this check on start unless we need to
2179-
if(c > MASTERNODE_MIN_DSEEP_SECONDS + MASTERNODE_PING_WAIT_SECONDS || mnodeman.UpdateNeeded())
2180-
{
2181-
LOCK(cs_main);
2182-
/*
2183-
cs_main is required for doing CMasternode.Check because something
2184-
is modifying the coins view without a mempool lock. It causes
2185-
segfaults from this code without the cs_main lock.
2186-
*/
2187-
mnodeman.CheckAndRemove();
2188-
}
21892183
}
21902184

21912185
if(c % MASTERNODE_PING_SECONDS == 0) activeMasternode.ManageStatus();
@@ -2208,7 +2202,7 @@ void ThreadCheckDarkSendPool()
22082202
LogPrintf("Successfully synced, asking for Masternode list and payment list\n");
22092203

22102204
//request full mn list only if masternodes.dat was updated quite a long time ago
2211-
if(mnodeman.UpdateNeeded()) pnode->PushMessage("dseg", CTxIn());
2205+
mnodeman.DsegUpdate(pnode);
22122206

22132207
pnode->PushMessage("mnget"); //sync payees
22142208
pnode->PushMessage("getsporks"); //get current network sporks

src/masternode.h

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#define MASTERNODE_MIN_DSEEP_SECONDS (30*60)
3131
#define MASTERNODE_MIN_DSEE_SECONDS (5*60)
3232
#define MASTERNODE_PING_SECONDS (1*60)
33-
#define MASTERNODE_PING_WAIT_SECONDS (5*60)
3433
#define MASTERNODE_EXPIRATION_SECONDS (65*60)
3534
#define MASTERNODE_REMOVAL_SECONDS (70*60)
3635

src/masternodeman.cpp

+98-74
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414

1515
/** Masternode manager */
1616
CMasternodeMan mnodeman;
17-
// who's asked for the masternode list and the last time
18-
std::map<CNetAddr, int64_t> askedForMasternodeList;
19-
// which masternodes we've asked for
20-
std::map<COutPoint, int64_t> askedForMasternodeListEntry;
2117

2218
struct CompareValueOnly
2319
{
@@ -133,54 +129,6 @@ void DumpMasternodes()
133129

134130
CMasternodeMan::CMasternodeMan() {}
135131

136-
CMasternode *CMasternodeMan::Find(const CTxIn &vin)
137-
{
138-
LOCK(cs);
139-
140-
BOOST_FOREACH(CMasternode& mn, vMasternodes)
141-
{
142-
if(mn.vin == vin)
143-
return &mn;
144-
}
145-
return NULL;
146-
}
147-
148-
CMasternode *CMasternodeMan::FindRandom()
149-
{
150-
LOCK(cs);
151-
152-
if(size() == 0) return NULL;
153-
154-
return &vMasternodes[GetRandInt(vMasternodes.size())];
155-
}
156-
157-
158-
CMasternode *CMasternodeMan::FindNotInVec(const std::vector<CTxIn> &vVins)
159-
{
160-
LOCK(cs);
161-
162-
BOOST_FOREACH(CMasternode &mn, vMasternodes)
163-
{
164-
mn.Check();
165-
UpdateLastTimeChanged();
166-
if(!mn.IsEnabled()) continue;
167-
168-
bool found = false;
169-
BOOST_FOREACH(const CTxIn& vin, vVins)
170-
if(mn.vin == vin)
171-
{
172-
found = true;
173-
break;
174-
}
175-
176-
if(found) continue;
177-
178-
return &mn;
179-
}
180-
181-
return NULL;
182-
}
183-
184132
bool CMasternodeMan::Add(CMasternode &mn)
185133
{
186134
LOCK(cs);
@@ -193,7 +141,6 @@ bool CMasternodeMan::Add(CMasternode &mn)
193141
if (pmn == NULL)
194142
{
195143
vMasternodes.push_back(mn);
196-
UpdateLastTimeChanged();
197144
return true;
198145
}
199146

@@ -204,7 +151,6 @@ void CMasternodeMan::Check()
204151
{
205152
LOCK(cs);
206153

207-
UpdateLastTimeChanged();
208154
BOOST_FOREACH(CMasternode& mn, vMasternodes)
209155
mn.Check();
210156
}
@@ -214,7 +160,6 @@ void CMasternodeMan::CheckAndRemove()
214160
LOCK(cs);
215161

216162
Check();
217-
UpdateLastTimeChanged();
218163

219164
//remove inactive
220165
vector<CMasternode>::iterator it = vMasternodes.begin();
@@ -226,35 +171,119 @@ void CMasternodeMan::CheckAndRemove()
226171
++it;
227172
}
228173
}
174+
175+
// check who's asked for the masternode list
176+
map<CNetAddr, int64_t>::iterator it1 = mAskedUsForMasternodeList.begin();
177+
while(it1 != mAskedUsForMasternodeList.end()){
178+
if((*it1).second < GetTime())
179+
it1 = mAskedUsForMasternodeList.erase(it1);
180+
else ++it1;
181+
}
182+
183+
// check who we asked for the masternode list
184+
it1 = mWeAskedForMasternodeList.begin();
185+
while(it1 != mWeAskedForMasternodeList.end()){
186+
if((*it1).second < GetTime())
187+
it1 = mWeAskedForMasternodeList.erase(it1);
188+
else ++it1;
189+
}
190+
191+
// check which masternodes we've asked for
192+
map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin();
193+
while(it2 != mWeAskedForMasternodeListEntry.end()){
194+
if((*it2).second < GetTime())
195+
it2 = mWeAskedForMasternodeListEntry.erase(it2);
196+
else ++it2;
197+
}
198+
229199
}
230200

231-
int CMasternodeMan::CountMasternodesAboveProtocol(int protocolVersion)
201+
int CMasternodeMan::CountEnabled()
232202
{
233203
int i = 0;
234204

235205
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
236206
mn.Check();
237-
UpdateLastTimeChanged();
238-
if(mn.protocolVersion < protocolVersion || !mn.IsEnabled()) continue;
239-
i++;
207+
if(mn.IsEnabled()) i++;
240208
}
241209

242210
return i;
243211
}
244212

245-
int CMasternodeMan::CountEnabled()
213+
int CMasternodeMan::CountMasternodesAboveProtocol(int protocolVersion)
246214
{
247215
int i = 0;
248216

249217
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
250218
mn.Check();
251-
UpdateLastTimeChanged();
252-
if(mn.IsEnabled()) i++;
219+
if(mn.protocolVersion < protocolVersion || !mn.IsEnabled()) continue;
220+
i++;
253221
}
254222

255223
return i;
256224
}
257225

226+
void CMasternodeMan::DsegUpdate(CNode* pnode)
227+
{
228+
std::map<CNetAddr, int64_t>::iterator it = mWeAskedForMasternodeList.find(pnode->addr);
229+
if (it != mWeAskedForMasternodeList.end())
230+
{
231+
if (GetTime() < (*it).second) {
232+
LogPrintf("dseg - we already asked %s for the list; skipping...\n", pnode->addr.ToString());
233+
return;
234+
}
235+
}
236+
pnode->PushMessage("dseg", CTxIn());
237+
int64_t askAgain = GetTime() + MASTERNODES_DSEG_SECONDS;
238+
mWeAskedForMasternodeList[pnode->addr] = askAgain;
239+
}
240+
241+
CMasternode *CMasternodeMan::Find(const CTxIn &vin)
242+
{
243+
LOCK(cs);
244+
245+
BOOST_FOREACH(CMasternode& mn, vMasternodes)
246+
{
247+
if(mn.vin == vin)
248+
return &mn;
249+
}
250+
return NULL;
251+
}
252+
253+
CMasternode *CMasternodeMan::FindNotInVec(const std::vector<CTxIn> &vVins)
254+
{
255+
LOCK(cs);
256+
257+
BOOST_FOREACH(CMasternode &mn, vMasternodes)
258+
{
259+
mn.Check();
260+
if(!mn.IsEnabled()) continue;
261+
262+
bool found = false;
263+
BOOST_FOREACH(const CTxIn& vin, vVins)
264+
if(mn.vin == vin)
265+
{
266+
found = true;
267+
break;
268+
}
269+
270+
if(found) continue;
271+
272+
return &mn;
273+
}
274+
275+
return NULL;
276+
}
277+
278+
CMasternode *CMasternodeMan::FindRandom()
279+
{
280+
LOCK(cs);
281+
282+
if(size() == 0) return NULL;
283+
284+
return &vMasternodes[GetRandInt(vMasternodes.size())];
285+
}
286+
258287
CMasternode* CMasternodeMan::GetCurrentMasterNode(int mod, int64_t nBlockHeight, int minProtocol)
259288
{
260289
unsigned int score = 0;
@@ -263,7 +292,6 @@ CMasternode* CMasternodeMan::GetCurrentMasterNode(int mod, int64_t nBlockHeight,
263292
// scan for winner
264293
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
265294
mn.Check();
266-
UpdateLastTimeChanged();
267295
if(mn.protocolVersion < minProtocol || !mn.IsEnabled()) continue;
268296

269297
// calculate the score for each masternode
@@ -289,7 +317,6 @@ int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int64_t nBlockHeight, in
289317
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
290318

291319
mn.Check();
292-
UpdateLastTimeChanged();
293320

294321
if(mn.protocolVersion < minProtocol) continue;
295322
if(!mn.IsEnabled()) {
@@ -399,7 +426,6 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
399426
// after that they just need to match
400427
if(count == -1 && pmn->pubkey == pubkey && !pmn->UpdatedWithin(MASTERNODE_MIN_DSEE_SECONDS)){
401428
pmn->UpdateLastSeen();
402-
UpdateLastTimeChanged();
403429

404430
if(pmn->now < sigTime){ //take the newest entry
405431
LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str());
@@ -516,7 +542,6 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
516542

517543
if(!pmn->UpdatedWithin(MASTERNODE_MIN_DSEEP_SECONDS))
518544
{
519-
UpdateLastTimeChanged();
520545
if(stop) pmn->Disable();
521546
else
522547
{
@@ -532,8 +557,8 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
532557

533558
if(fDebug) LogPrintf("dseep - Couldn't find masternode entry %s\n", vin.ToString().c_str());
534559

535-
std::map<COutPoint, int64_t>::iterator i = askedForMasternodeListEntry.find(vin.prevout);
536-
if (i != askedForMasternodeListEntry.end())
560+
std::map<COutPoint, int64_t>::iterator i = mWeAskedForMasternodeListEntry.find(vin.prevout);
561+
if (i != mWeAskedForMasternodeListEntry.end())
537562
{
538563
int64_t t = (*i).second;
539564
if (GetTime() < t) return; // we've asked recently
@@ -544,7 +569,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
544569
LogPrintf("dseep - Asking source node for missing entry %s\n", vin.ToString().c_str());
545570
pfrom->PushMessage("dseg", vin);
546571
int64_t askAgain = GetTime()+(60*60*24);
547-
askedForMasternodeListEntry[vin.prevout] = askAgain;
572+
mWeAskedForMasternodeListEntry[vin.prevout] = askAgain;
548573

549574
} else if (strCommand == "dseg") { //Get masternode list or specific entry
550575

@@ -555,8 +580,8 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
555580
//local network
556581
if(!pfrom->addr.IsRFC1918() && Params().NetworkID() == CChainParams::MAIN)
557582
{
558-
std::map<CNetAddr, int64_t>::iterator i = askedForMasternodeList.find(pfrom->addr);
559-
if (i != askedForMasternodeList.end())
583+
std::map<CNetAddr, int64_t>::iterator i = mAskedUsForMasternodeList.find(pfrom->addr);
584+
if (i != mAskedUsForMasternodeList.end())
560585
{
561586
int64_t t = (*i).second;
562587
if (GetTime() < t) {
@@ -565,9 +590,8 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
565590
return;
566591
}
567592
}
568-
569-
int64_t askAgain = GetTime()+(60*60*3);
570-
askedForMasternodeList[pfrom->addr] = askAgain;
593+
int64_t askAgain = GetTime() + MASTERNODES_DSEG_SECONDS;
594+
mAskedUsForMasternodeList[pfrom->addr] = askAgain;
571595
}
572596
} //else, asking for a specific node which is ok
573597

0 commit comments

Comments
 (0)