PRCYCoin  2.0.0.7rc1
P2P Digital Currency
masternodeman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2015 The Dash developers
2 // Copyright (c) 2015-2018 The PIVX developers
3 // Copyright (c) 2018-2020 The DAPS Project developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "masternodeman.h"
8 
9 #include "addrman.h"
10 #include "masternode-payments.h"
11 #include "masternode-sync.h"
12 #include "messagesigner.h"
13 #include "fs.h"
14 #include "masternode.h"
15 #include "netbase.h"
16 #include "swifttx.h"
17 #include "util.h"
18 
19 #define MN_WINNER_MINIMUM_AGE 8000 // Age in seconds. This should be > MASTERNODE_REMOVAL_SECONDS to avoid misconfigured new nodes in the list.
20 
25 
27  bool operator()(const std::pair<int64_t, CTxIn>& t1,
28  const std::pair<int64_t, CTxIn>& t2) const
29  {
30  return t1.first < t2.first;
31  }
32 };
33 
35  bool operator()(const std::pair<int64_t, CTxIn>& t1,
36  const std::pair<int64_t, CTxIn>& t2) const
37  {
38  return t1.first < t2.first;
39  }
40 };
41 
43  bool operator()(const std::pair<int64_t, CMasternode>& t1,
44  const std::pair<int64_t, CMasternode>& t2) const
45  {
46  return t1.first < t2.first;
47  }
48 };
49 
50 //
51 // CMasternodeDB
52 //
53 
55 {
56  pathMN = GetDataDir() / "mncache.dat";
57  strMagicMessage = "MasternodeCache";
58 }
59 
60 bool CMasternodeDB::Write(const CMasternodeMan& mnodemanToSave)
61 {
62  int64_t nStart = GetTimeMillis();
63 
64  // serialize, checksum data up to that point, then append checksum
65  CDataStream ssMasternodes(SER_DISK, CLIENT_VERSION);
66  ssMasternodes << strMagicMessage; // masternode cache file specific magic message
67  ssMasternodes << FLATDATA(Params().MessageStart()); // network specific magic number
68  ssMasternodes << mnodemanToSave;
69  uint256 hash = Hash(ssMasternodes.begin(), ssMasternodes.end());
70  ssMasternodes << hash;
71 
72  // open output file, and associate with CAutoFile
73  FILE* file = fsbridge::fopen(pathMN, "wb");
74  CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
75  if (fileout.IsNull())
76  return error("%s : Failed to open file %s", __func__, pathMN.string());
77 
78  // Write and commit header, data
79  try {
80  fileout << ssMasternodes;
81  } catch (const std::exception& e) {
82  return error("%s : Serialize or I/O error - %s", __func__, e.what());
83  }
84 
85  fileout.fclose();
86 
87  LogPrint(BCLog::MASTERNODE,"Written info to mncache.dat %dms\n", GetTimeMillis() - nStart);
88  LogPrint(BCLog::MASTERNODE," %s\n", mnodemanToSave.ToString());
89 
90  return true;
91 }
92 
94 {
95  int64_t nStart = GetTimeMillis();
96  // open input file, and associate with CAutoFile
97  FILE* file = fsbridge::fopen(pathMN, "rb");
98  CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
99  if (filein.IsNull()) {
100  error("%s : Failed to open file %s", __func__, pathMN.string());
101  return FileError;
102  }
103 
104  // use file size to size memory buffer
105  int fileSize = fs::file_size(pathMN);
106  int dataSize = fileSize - sizeof(uint256);
107  // Don't try to resize to a negative number if file is small
108  if (dataSize < 0)
109  dataSize = 0;
110  std::vector<unsigned char> vchData;
111  vchData.resize(dataSize);
112  uint256 hashIn;
113 
114  // read data and checksum from file
115  try {
116  filein.read((char*)&vchData[0], dataSize);
117  filein >> hashIn;
118  } catch (const std::exception& e) {
119  error("%s : Deserialize or I/O error - %s", __func__, e.what());
120  return HashReadError;
121  }
122  filein.fclose();
123 
124  CDataStream ssMasternodes(vchData, SER_DISK, CLIENT_VERSION);
125 
126  // verify stored checksum matches input data
127  uint256 hashTmp = Hash(ssMasternodes.begin(), ssMasternodes.end());
128  if (hashIn != hashTmp) {
129  error("%s : Checksum mismatch, data corrupted", __func__);
130  return IncorrectHash;
131  }
132 
133  unsigned char pchMsgTmp[4];
134  std::string strMagicMessageTmp;
135  try {
136  // de-serialize file header (masternode cache file specific magic message) and ..
137 
138  ssMasternodes >> strMagicMessageTmp;
139 
140  // ... verify the message matches predefined one
141  if (strMagicMessage != strMagicMessageTmp) {
142  error("%s : Invalid masternode cache magic message", __func__);
143  return IncorrectMagicMessage;
144  }
145 
146  // de-serialize file header (network specific magic number) and ..
147  ssMasternodes >> FLATDATA(pchMsgTmp);
148 
149  // ... verify the network matches ours
150  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) {
151  error("%s : Invalid network magic number", __func__);
152  return IncorrectMagicNumber;
153  }
154  // de-serialize data into CMasternodeMan object
155  ssMasternodes >> mnodemanToLoad;
156  } catch (const std::exception& e) {
157  mnodemanToLoad.Clear();
158  error("%s : Deserialize or I/O error - %s", __func__, e.what());
159  return IncorrectFormat;
160  }
161 
162  LogPrint(BCLog::MASTERNODE,"Loaded info from mncache.dat %dms\n", GetTimeMillis() - nStart);
163  LogPrint(BCLog::MASTERNODE," %s\n", mnodemanToLoad.ToString());
164  if (!fDryRun) {
165  LogPrint(BCLog::MASTERNODE,"Masternode manager - cleaning....\n");
166  mnodemanToLoad.CheckAndRemove(true);
167  LogPrint(BCLog::MASTERNODE,"Masternode manager - result:\n");
168  LogPrint(BCLog::MASTERNODE," %s\n", mnodemanToLoad.ToString());
169  }
170 
171  return Ok;
172 }
173 
175 {
176  int64_t nStart = GetTimeMillis();
177 
178  CMasternodeDB mndb;
179  CMasternodeMan tempMnodeman;
180 
181  LogPrint(BCLog::MASTERNODE,"Verifying mncache.dat format...\n");
182  CMasternodeDB::ReadResult readResult = mndb.Read(tempMnodeman, true);
183  // there was an error and it was not an error on file opening => do not proceed
184  if (readResult == CMasternodeDB::FileError)
185  LogPrint(BCLog::MASTERNODE,"Missing masternode cache file - mncache.dat, will try to recreate\n");
186  else if (readResult != CMasternodeDB::Ok) {
187  LogPrint(BCLog::MASTERNODE,"Error reading mncache.dat: ");
188  if (readResult == CMasternodeDB::IncorrectFormat)
189  LogPrint(BCLog::MASTERNODE,"magic is ok but data has invalid format, will try to recreate\n");
190  else {
191  LogPrint(BCLog::MASTERNODE,"file format is unknown or invalid, please fix it manually\n");
192  return;
193  }
194  }
195  LogPrint(BCLog::MASTERNODE,"Writting info to mncache.dat...\n");
196  mndb.Write(mnodeman);
197 
198  LogPrint(BCLog::MASTERNODE,"Masternode dump finished %dms\n", GetTimeMillis() - nStart);
199 }
200 
202 {
203  nDsqCount = 0;
204 }
205 
207 {
208  LOCK(cs);
209 
210  if (!mn.IsEnabled())
211  return false;
212 
213  CMasternode* pmn = Find(mn.vin);
214  if (pmn == NULL) {
215  LogPrint(BCLog::MASTERNODE, "CMasternodeMan: Adding new Masternode %s - %i now\n", mn.vin.prevout.hash.ToString(), size() + 1);
216  vMasternodes.push_back(mn);
217  return true;
218  }
219 
220  return false;
221 }
222 
224 {
225  std::map<COutPoint, int64_t>::iterator i = mWeAskedForMasternodeListEntry.find(vin.prevout);
226  if (i != mWeAskedForMasternodeListEntry.end()) {
227  int64_t t = (*i).second;
228  if (GetTime() < t) return; // we've asked recently
229  }
230 
231  // ask for the mnb info once from the node that sent mnp
232 
233  LogPrint(BCLog::MASTERNODE, "CMasternodeMan::AskForMN - Asking node for missing entry, vin: %s\n", vin.prevout.hash.ToString());
234  std::string stl(vin.masternodeStealthAddress.begin(), vin.masternodeStealthAddress.end());
235  LogPrint(BCLog::MASTERNODE, "CMasternodeMan::AskForMN - stealth masternode address = %s\n", stl);
236  pnode->PushMessage(NetMsgType::DSEG, vin);
237  int64_t askAgain = GetTime() + MASTERNODE_MIN_MNP_SECONDS;
238  mWeAskedForMasternodeListEntry[vin.prevout] = askAgain;
239 }
240 
242 {
243  LOCK(cs);
244 
245  for (CMasternode& mn : vMasternodes) {
246  mn.Check();
247  }
248 }
249 
250 void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval)
251 {
252  Check();
253 
254  LOCK(cs);
255 
256  //remove inactive and outdated
257  std::vector<CMasternode>::iterator it = vMasternodes.begin();
258  while (it != vMasternodes.end()) {
259  if ((*it).activeState == CMasternode::MASTERNODE_REMOVE ||
260  (*it).activeState == CMasternode::MASTERNODE_VIN_SPENT ||
261  (forceExpiredRemoval && (*it).activeState == CMasternode::MASTERNODE_EXPIRED) ||
262  (*it).protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) {
263  LogPrint(BCLog::MASTERNODE, "CMasternodeMan: Removing inactive Masternode %s - %i now,mapSeenMasternodeBroadcast.size=%d\n", (*it).vin.prevout.hash.ToString(), size() - 1, mapSeenMasternodeBroadcast.size());
264 
265  //erase all of the broadcasts we've seen from this vin
266  // -- if we missed a few pings and the node was removed, this will allow is to get it back without them
267  // sending a brand new mnb
268  std::map<uint256, CMasternodeBroadcast>::iterator it3 = mapSeenMasternodeBroadcast.begin();
269  while (it3 != mapSeenMasternodeBroadcast.end()) {
270  if ((*it3).second.vin == (*it).vin) {
271  masternodeSync.mapSeenSyncMNB.erase((*it3).first);
272  mapSeenMasternodeBroadcast.erase(it3++);
273  } else {
274  ++it3;
275  }
276  }
277 
278  // allow us to ask for this masternode again if we see another ping
279  std::map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin();
280  while (it2 != mWeAskedForMasternodeListEntry.end()) {
281  if ((*it2).first == (*it).vin.prevout) {
282  mWeAskedForMasternodeListEntry.erase(it2++);
283  } else {
284  ++it2;
285  }
286  }
287 
288  it = vMasternodes.erase(it);
289  } else {
290  ++it;
291  }
292  }
293 
294  // check who's asked for the Masternode list
295  std::map<CNetAddr, int64_t>::iterator it1 = mAskedUsForMasternodeList.begin();
296  while (it1 != mAskedUsForMasternodeList.end()) {
297  if ((*it1).second < GetTime()) {
298  mAskedUsForMasternodeList.erase(it1++);
299  } else {
300  ++it1;
301  }
302  }
303 
304  // check who we asked for the Masternode list
305  it1 = mWeAskedForMasternodeList.begin();
306  while (it1 != mWeAskedForMasternodeList.end()) {
307  if ((*it1).second < GetTime()) {
308  mWeAskedForMasternodeList.erase(it1++);
309  } else {
310  ++it1;
311  }
312  }
313 
314  // check which Masternodes we've asked for
315  std::map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin();
316  while (it2 != mWeAskedForMasternodeListEntry.end()) {
317  if ((*it2).second < GetTime()) {
318  mWeAskedForMasternodeListEntry.erase(it2++);
319  } else {
320  ++it2;
321  }
322  }
323 
324  // remove expired mapSeenMasternodeBroadcast
325  std::map<uint256, CMasternodeBroadcast>::iterator it3 = mapSeenMasternodeBroadcast.begin();
326  while (it3 != mapSeenMasternodeBroadcast.end()) {
327  if ((*it3).second.lastPing.sigTime < GetTime() - (MASTERNODE_REMOVAL_SECONDS * 2)) {
328  mapSeenMasternodeBroadcast.erase(it3++);
329  masternodeSync.mapSeenSyncMNB.erase((*it3).second.GetHash());
330  } else {
331  ++it3;
332  }
333  }
334 
335  // remove expired mapSeenMasternodePing
336  std::map<uint256, CMasternodePing>::iterator it4 = mapSeenMasternodePing.begin();
337  while (it4 != mapSeenMasternodePing.end()) {
338  if ((*it4).second.sigTime < GetTime() - (MASTERNODE_REMOVAL_SECONDS * 2)) {
339  mapSeenMasternodePing.erase(it4++);
340  } else {
341  ++it4;
342  }
343  }
344 }
345 
347 {
348  LOCK(cs);
349  vMasternodes.clear();
354  mapSeenMasternodePing.clear();
355  nDsqCount = 0;
356 }
357 
359 {
360  int nStable_size = 0;
361  int nMinProtocol = ActiveProtocol();
362  int64_t nMasternode_Min_Age = MN_WINNER_MINIMUM_AGE;
363  int64_t nMasternode_Age = 0;
364 
365  for (CMasternode& mn : vMasternodes) {
366  if (mn.protocolVersion < nMinProtocol) {
367  continue; // Skip obsolete versions
368  }
369  mn.Check ();
370  if (!mn.IsEnabled ())
371  continue; // Skip not-enabled masternodes
372 
373  nStable_size++;
374  }
375 
376  return nStable_size;
377 }
378 
379 int CMasternodeMan::CountEnabled(int protocolVersion)
380 {
381  int i = 0;
382  protocolVersion = protocolVersion == -1 ? masternodePayments.GetMinMasternodePaymentsProto() : protocolVersion;
383 
384  for (CMasternode& mn : vMasternodes) {
385  mn.Check();
386  if (mn.protocolVersion < protocolVersion || !mn.IsEnabled()) continue;
387  i++;
388  }
389 
390  return i;
391 }
392 
393 void CMasternodeMan::CountNetworks(int protocolVersion, int& ipv4, int& ipv6, int& onion)
394 {
395  protocolVersion = protocolVersion == -1 ? masternodePayments.GetMinMasternodePaymentsProto() : protocolVersion;
396 
397  for (CMasternode& mn : vMasternodes) {
398  mn.Check();
399  std::string strHost;
400  int port;
401  SplitHostPort(mn.addr.ToString(), port, strHost);
402  CNetAddr node;
403  LookupHost(strHost.c_str(), node, false);
404  int nNetwork = node.GetNetwork();
405  switch (nNetwork) {
406  case 1 :
407  ipv4++;
408  break;
409  case 2 :
410  ipv6++;
411  break;
412  case 3 :
413  onion++;
414  break;
415  }
416  }
417 }
418 
420 {
421  LOCK(cs);
422 
423  if (Params().NetworkID() == CBaseChainParams::MAIN) {
424  if (!(pnode->addr.IsRFC1918() || pnode->addr.IsLocal())) {
425  std::map<CNetAddr, int64_t>::iterator it = mWeAskedForMasternodeList.find(pnode->addr);
426  if (it != mWeAskedForMasternodeList.end()) {
427  if (GetTime() < (*it).second) {
428  LogPrint(BCLog::MASTERNODE, "dseg - we already asked peer %i for the list; skipping...\n", pnode->GetId());
429  return;
430  }
431  }
432  }
433  }
434 
436  int64_t askAgain = GetTime() + MASTERNODES_DSEG_SECONDS;
437  mWeAskedForMasternodeList[pnode->addr] = askAgain;
438 }
439 
441 {
442  LOCK(cs);
443  CScript payee2;
444 
445  for (CMasternode& mn : vMasternodes) {
446  payee2 = GetScriptForDestination(mn.pubKeyCollateralAddress);
447  if (payee2 == payee)
448  return &mn;
449  }
450  return NULL;
451 }
452 
454 {
455  LOCK(cs);
456 
457  for (CMasternode& mn : vMasternodes) {
458  if (mn.vin.prevout == vin.prevout)
459  return &mn;
460  }
461  return NULL;
462 }
463 
464 
465 CMasternode* CMasternodeMan::Find(const CPubKey& pubKeyMasternode)
466 {
467  LOCK(cs);
468 
469  for (CMasternode& mn : vMasternodes) {
470  if (mn.pubKeyMasternode == pubKeyMasternode)
471  return &mn;
472  }
473  return NULL;
474 }
475 
476 //
477 // Deterministically select the oldest/best masternode to pay on the network
478 //
479 CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCount)
480 {
481  LOCK(cs);
482 
483  CMasternode* pBestMasternode = NULL;
484  std::vector<std::pair<int64_t, CTxIn> > vecMasternodeLastPaid;
485 
486  /*
487  Make a vector with all of the last paid times
488  */
489 
490  int nMnCount = CountEnabled();
491  for (CMasternode& mn : vMasternodes) {
492  mn.Check();
493  if (!mn.IsEnabled()) continue;
494 
495  // //check protocol version
496  if (mn.protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) continue;
497 
498  //it's in the list (up to 8 entries ahead of current block to allow propagation) -- so let's skip it
499  if (masternodePayments.IsScheduled(mn, nBlockHeight)) continue;
500 
501  //it's too new, wait for a cycle
502  if (fFilterSigTime && mn.sigTime + (nMnCount * 2.6 * 60) > GetAdjustedTime()) continue;
503 
504  //make sure it has as many confirmations as there are masternodes
505  if (mn.GetMasternodeInputAge() < nMnCount) continue;
506 
507  vecMasternodeLastPaid.push_back(std::make_pair(mn.SecondsSincePayment(), mn.vin));
508  }
509 
510  nCount = (int)vecMasternodeLastPaid.size();
511 
512  //when the network is in the process of upgrading, don't penalize nodes that recently restarted
513  if (fFilterSigTime && nCount < nMnCount / 3) return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCount);
514 
515  // Sort them high to low
516  sort(vecMasternodeLastPaid.rbegin(), vecMasternodeLastPaid.rend(), CompareLastPaid());
517 
518  // Look at 1/10 of the oldest nodes (by last payment), calculate their scores and pay the best one
519  // -- This doesn't look at who is being paid in the +8-10 blocks, allowing for double payments very rarely
520  // -- 1/100 payments should be a double payment on mainnet - (1/(3000/10))*2
521  // -- (chance per block * chances before IsScheduled will fire)
522  int nTenthNetwork = CountEnabled() / 10;
523  int nCountTenth = 0;
524  uint256 nHigh;
525  for (PAIRTYPE(int64_t, CTxIn) & s : vecMasternodeLastPaid) {
526  CMasternode* pmn = Find(s.second);
527  if (!pmn) break;
528 
529  uint256 n = pmn->CalculateScore(1, nBlockHeight - 100);
530  if (n > nHigh) {
531  nHigh = n;
532  pBestMasternode = pmn;
533  }
534  nCountTenth++;
535  if (nCountTenth >= nTenthNetwork) break;
536  }
537  return pBestMasternode;
538 }
539 
540 CMasternode* CMasternodeMan::GetCurrentMasterNode(int mod, int64_t nBlockHeight, int minProtocol)
541 {
542  int64_t score = 0;
543  CMasternode* winner = NULL;
544 
545  // scan for winner
546  for (CMasternode& mn : vMasternodes) {
547  mn.Check();
548  if (mn.protocolVersion < minProtocol || !mn.IsEnabled()) continue;
549 
550  // calculate the score for each Masternode
551  uint256 n = mn.CalculateScore(mod, nBlockHeight);
552  int64_t n2 = n.GetCompact(false);
553 
554  // determine the winner
555  if (n2 > score) {
556  score = n2;
557  winner = &mn;
558  }
559  }
560 
561  return winner;
562 }
563 
564 int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int64_t nBlockHeight, int minProtocol, bool fOnlyActive)
565 {
566  std::vector<std::pair<int64_t, CTxIn> > vecMasternodeScores;
567  int64_t nMasternode_Min_Age = MN_WINNER_MINIMUM_AGE;
568  int64_t nMasternode_Age = 0;
569 
570  //make sure we know about this block
571  uint256 hash;
572  if (!GetBlockHash(hash, nBlockHeight)) return -1;
573 
574  // scan for winner
575  for (CMasternode& mn : vMasternodes) {
576  if (mn.protocolVersion < minProtocol) {
577  LogPrint(BCLog::MASTERNODE,"Skipping Masternode with obsolete version %d\n", mn.protocolVersion);
578  continue; // Skip obsolete versions
579  }
580 
581  if (fOnlyActive) {
582  mn.Check();
583  if (!mn.IsEnabled()) continue;
584  }
585  uint256 n = mn.CalculateScore(1, nBlockHeight);
586  int64_t n2 = n.GetCompact(false);
587 
588  vecMasternodeScores.push_back(std::make_pair(n2, mn.vin));
589  }
590 
591  sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreTxIn());
592 
593  int rank = 0;
594  for (PAIRTYPE(int64_t, CTxIn) & s : vecMasternodeScores) {
595  rank++;
596  if (s.second.prevout == vin.prevout) {
597  return rank;
598  }
599  }
600 
601  return -1;
602 }
603 
604 std::vector<std::pair<int, CMasternode> > CMasternodeMan::GetMasternodeRanks(int64_t nBlockHeight, int minProtocol)
605 {
606  std::vector<std::pair<int64_t, CMasternode> > vecMasternodeScores;
607  std::vector<std::pair<int, CMasternode> > vecMasternodeRanks;
608 
609  //make sure we know about this block
610  uint256 hash;
611  if (!GetBlockHash(hash, nBlockHeight)) return vecMasternodeRanks;
612 
613  // scan for winner
614  for (CMasternode& mn : vMasternodes) {
615  mn.Check();
616 
617  if (mn.protocolVersion < minProtocol) continue;
618 
619  if (!mn.IsEnabled()) {
620  vecMasternodeScores.push_back(std::make_pair(9999, mn));
621  continue;
622  }
623 
624  uint256 n = mn.CalculateScore(1, nBlockHeight);
625  int64_t n2 = n.GetCompact(false);
626 
627  vecMasternodeScores.push_back(std::make_pair(n2, mn));
628  }
629 
630  sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN());
631 
632  int rank = 0;
633  for (PAIRTYPE(int64_t, CMasternode) & s : vecMasternodeScores) {
634  rank++;
635  vecMasternodeRanks.push_back(std::make_pair(rank, s.second));
636  }
637 
638  return vecMasternodeRanks;
639 }
640 
641 CMasternode* CMasternodeMan::GetMasternodeByRank(int nRank, int64_t nBlockHeight, int minProtocol, bool fOnlyActive)
642 {
643  std::vector<std::pair<int64_t, CTxIn> > vecMasternodeScores;
644 
645  // scan for winner
646  for (CMasternode& mn : vMasternodes) {
647  if (mn.protocolVersion < minProtocol) continue;
648  if (fOnlyActive) {
649  mn.Check();
650  if (!mn.IsEnabled()) continue;
651  }
652 
653  uint256 n = mn.CalculateScore(1, nBlockHeight);
654  int64_t n2 = n.GetCompact(false);
655 
656  vecMasternodeScores.push_back(std::make_pair(n2, mn.vin));
657  }
658 
659  sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreTxIn());
660 
661  int rank = 0;
662  for (PAIRTYPE(int64_t, CTxIn) & s : vecMasternodeScores) {
663  rank++;
664  if (rank == nRank) {
665  return Find(s.second);
666  }
667  }
668 
669  return NULL;
670 }
671 
672 void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
673 {
674  if (fLiteMode) return; //disable all Masternode related functionality
675  if (!masternodeSync.IsBlockchainSynced()) return;
676 
678  if (strCommand == NetMsgType::MNBROADCAST) { //Masternode Broadcast
680  vRecv >> mnb;
681 
682  if (mapSeenMasternodeBroadcast.count(mnb.GetHash())) { //seen
683  masternodeSync.AddedMasternodeList(mnb.GetHash());
684  return;
685  }
686  mapSeenMasternodeBroadcast.insert(std::make_pair(mnb.GetHash(), mnb));
687 
688  int nDoS = 0;
689  if (!mnb.CheckAndUpdate(nDoS)) {
690  if (nDoS > 0) {
691  LOCK(cs_main);
692  Misbehaving(pfrom->GetId(), nDoS);
693  }
694  //failed
695  return;
696  }
697 
698  // make sure the vout that was signed is related to the transaction that spawned the Masternode
699  // - this is expensive, so it's only done once per Masternode
700  if (!mnb.IsInputAssociatedWithPubkey(mnb.vin, mnb.pubKeyCollateralAddress)) {
701  LogPrintf("CMasternodeMan::ProcessMessage() : mnb - Got mismatched pubkey and vin\n");
702  LOCK(cs_main);
703  Misbehaving(pfrom->GetId(), 33);
704  return;
705  }
706 
707  // make sure it's still unspent
708  // - this is checked later by .check() in many places and by ThreadCheckMasternodes()
709  if (mnb.CheckInputsAndAdd(nDoS)) {
710  // use this as a peer
711  addrman.Add(CAddress(mnb.addr, NODE_NETWORK), pfrom->addr, 2 * 60 * 60);
712  masternodeSync.AddedMasternodeList(mnb.GetHash());
713  } else {
714  LogPrint(BCLog::MASTERNODE,"mnb - Rejected Masternode entry %s\n", mnb.vin.prevout.hash.ToString());
715 
716  if (nDoS > 0) {
717  LOCK(cs_main);
718  Misbehaving(pfrom->GetId(), nDoS);
719  }
720  }
721  }
722 
723  else if (strCommand == NetMsgType::MNPING) { //Masternode Ping
724  CMasternodePing mnp;
725  vRecv >> mnp;
726 
727  LogPrint(BCLog::MNPING, "mnp - Masternode ping, vin: %s\n", mnp.vin.prevout.hash.ToString());
728 
729  if (mapSeenMasternodePing.count(mnp.GetHash())) return; //seen
730  mapSeenMasternodePing.insert(std::make_pair(mnp.GetHash(), mnp));
731 
732  int nDoS = 0;
733  if (mnp.CheckAndUpdate(nDoS)) return;
734 
735  if (nDoS > 0) {
736  // if anything significant failed, mark that node
737  LOCK(cs_main);
738  Misbehaving(pfrom->GetId(), nDoS);
739  } else {
740  // if nothing significant failed, search existing Masternode list
741  CMasternode* pmn = Find(mnp.vin);
742  // if it's known, don't ask for the mnb, just return
743  if (pmn != NULL) return;
744  }
745 
746  // something significant is broken or mn is unknown,
747  // we might have to ask for a masternode entry once
748  AskForMN(pfrom, mnp.vin);
749 
750  } else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry
751 
752  CTxIn vin;
753  vRecv >> vin;
754  if (vin == CTxIn()) { //only should ask for this once
755  //local network
756  bool isLocal = (pfrom->addr.IsRFC1918() || pfrom->addr.IsLocal());
757 
758  if (!isLocal && Params().NetworkID() == CBaseChainParams::MAIN) {
759  std::map<CNetAddr, int64_t>::iterator i = mAskedUsForMasternodeList.find(pfrom->addr);
760  if (i != mAskedUsForMasternodeList.end()) {
761  int64_t t = (*i).second;
762  if (GetTime() < t) {
763  LogPrintf("CMasternodeMan::ProcessMessage() : dseg - peer already asked me for the list\n");
764  LOCK(cs_main);
765  Misbehaving(pfrom->GetId(), 34);
766  return;
767  }
768  }
769  int64_t askAgain = GetTime() + MASTERNODES_DSEG_SECONDS;
770  mAskedUsForMasternodeList[pfrom->addr] = askAgain;
771  }
772  } //else, asking for a specific node which is ok
773 
774 
775  int nInvCount = 0;
776  for (CMasternode& mn : vMasternodes) {
777  if (mn.addr.IsRFC1918()) continue; //local network
778 
779  if (mn.IsEnabled()) {
780  LogPrint(BCLog::MASTERNODE, "dseg - Sending Masternode entry - %s \n", mn.vin.prevout.hash.ToString());
781  if (vin == CTxIn() || vin == mn.vin) {
783  uint256 hash = mnb.GetHash();
785  nInvCount++;
786 
787  if (!mapSeenMasternodeBroadcast.count(hash)) mapSeenMasternodeBroadcast.insert(std::make_pair(hash, mnb));
788 
789  if (vin == mn.vin) {
790  LogPrint(BCLog::MASTERNODE, "dseg - Sent 1 Masternode entry to peer %i\n", pfrom->GetId());
791  return;
792  }
793  }
794  }
795  }
796 
797  if (vin == CTxIn()) {
799  LogPrint(BCLog::MASTERNODE, "dseg - Sent %d Masternode entries to peer %i\n", nInvCount, pfrom->GetId());
800  }
801  }
802 }
803 
805 {
806  LOCK(cs);
807 
808  std::vector<CMasternode>::iterator it = vMasternodes.begin();
809  while (it != vMasternodes.end()) {
810  if ((*it).vin == vin) {
811  LogPrint(BCLog::MASTERNODE, "CMasternodeMan: Removing Masternode %s - %i now\n", (*it).vin.prevout.hash.ToString(), size() - 1);
812  vMasternodes.erase(it);
813  break;
814  }
815  ++it;
816  }
817 }
818 
820 {
821  LOCK(cs);
822  mapSeenMasternodePing.insert(std::make_pair(mnb.lastPing.GetHash(), mnb.lastPing));
823  mapSeenMasternodeBroadcast.insert(std::make_pair(mnb.GetHash(), mnb));
824 
825  LogPrint(BCLog::MASTERNODE,"CMasternodeMan::UpdateMasternodeList -- masternode=%s\n", mnb.vin.prevout.ToStringShort());
826 
827  CMasternode* pmn = Find(mnb.vin);
828  if (pmn == NULL) {
829  CMasternode mn(mnb);
830  if (Add(mn)) {
832  }
833  } else if (pmn->UpdateFromNewBroadcast(mnb)) {
835  }
836 }
837 
838 std::string CMasternodeMan::ToString() const
839 {
840  std::ostringstream info;
841 
842  info << "Masternodes: " << (int)vMasternodes.size() << ", peers who asked us for Masternode list: " << (int)mAskedUsForMasternodeList.size() << ", peers we asked for Masternode list: " << (int)mWeAskedForMasternodeList.size() << ", entries in Masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size();
843 
844  return info.str();
845 }
846 
848 {
849  if (fLiteMode) return; //disable all Masternode related functionality
850 
851  // Make this thread recognisable as the wallet flushing thread
852  util::ThreadRename("prcycoin-masternodeman");
853  LogPrintf("Masternodes thread started\n");
854 
855  unsigned int c = 0;
856 
857  while (true) {
858  MilliSleep(1000);
859 
860  // try to sync from all available nodes, one step at a time
862 
864  c++;
865 
866  // check if we should activate or ping every few minutes,
867  // start right after sync is considered to be done
869 
870  if (c % 60 == 0) {
874  }
875  }
876  }
877 }
CTxIn
An input of a transaction.
Definition: transaction.h:83
CompareScoreMN
Definition: masternodeman.cpp:42
CMasternodeDB::HashReadError
@ HashReadError
Definition: masternodeman.h:44
CMasternode::MASTERNODE_EXPIRED
@ MASTERNODE_EXPIRED
Definition: masternode.h:118
CMasternodeDB::FileError
@ FileError
Definition: masternodeman.h:43
CMasternodeMan::AskForMN
void AskForMN(CNode *pnode, CTxIn &vin)
Ask (source) node for mnb.
Definition: masternodeman.cpp:223
SplitHostPort
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
Definition: netbase.cpp:74
CMasternodeMan::CountEnabled
int CountEnabled(int protocolVersion=-1)
Definition: masternodeman.cpp:379
CAutoFile::read
CAutoFile & read(char *pch, size_t nSize)
Definition: streams.h:367
GetTime
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:19
CActiveMasternode
Definition: activemasternode.h:23
CMasternodeMan::UpdateMasternodeList
void UpdateMasternodeList(CMasternodeBroadcast mnb)
Update masternode list and maps using provided CMasternodeBroadcast.
Definition: masternodeman.cpp:819
activeMasternode
CActiveMasternode activeMasternode
Keep track of the active Masternode.
Definition: masternodeman.cpp:24
CMasternodePayments::GetMinMasternodePaymentsProto
int GetMinMasternodePaymentsProto()
Definition: masternode-payments.cpp:293
CMasternodeMan::GetMasternodeRank
int GetMasternodeRank(const CTxIn &vin, int64_t nBlockHeight, int minProtocol=0, bool fOnlyActive=true)
Definition: masternodeman.cpp:564
CNode::GetId
NodeId GetId() const
Definition: net.h:423
FLATDATA
#define FLATDATA(obj)
Definition: serialize.h:365
fs.h
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:13
CDataStream::begin
const_iterator begin() const
Definition: streams.h:116
CAddrMan::Add
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:505
COutPoint::hash
uint256 hash
Definition: transaction.h:39
GetScriptForDestination
CScript GetScriptForDestination(const CTxDestination &dest)
Definition: standard.cpp:285
CompareScoreTxIn
Definition: masternodeman.cpp:34
CNetAddr
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:30
CMasternodeMan::Find
CMasternode * Find(const CScript &payee)
Find an entry.
Definition: masternodeman.cpp:440
CMasternodeSync::IsBlockchainSynced
bool IsBlockchainSynced()
Definition: masternode-sync.cpp:32
CMasternodeMan::CheckAndRemove
void CheckAndRemove(bool forceExpiredRemoval=false)
Check all Masternodes and remove inactive.
Definition: masternodeman.cpp:250
CNode
Information about a peer.
Definition: net.h:306
CMasternode::UpdateFromNewBroadcast
bool UpdateFromNewBroadcast(CMasternodeBroadcast &mnb)
Definition: masternode.cpp:146
CMasternodeDB::Ok
@ Ok
Definition: masternodeman.h:42
CMasternodeSync::AddedMasternodeList
void AddedMasternodeList(uint256 hash)
Definition: masternode-sync.cpp:89
CNode::addr
CAddress addr
Definition: net.h:332
COutPoint::ToStringShort
std::string ToStringShort() const
Definition: transaction.cpp:26
masternode-sync.h
CNode::PushInventory
void PushInventory(const CInv &inv)
Definition: net.h:494
CMasternodeMan::size
int size()
Return the number of (unique) Masternodes.
Definition: masternodeman.h:148
CMasternodeMan::vMasternodes
std::vector< CMasternode > vMasternodes
Definition: masternodeman.h:66
CMasternodeMan::GetNextMasternodeInQueueForPayment
CMasternode * GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int &nCount)
Find an entry in the masternode list that is next to be paid.
Definition: masternodeman.cpp:479
CMasternodeMan::ToString
std::string ToString() const
Definition: masternodeman.cpp:838
NODE_NETWORK
@ NODE_NETWORK
Definition: protocol.h:302
CInv
inv message data
Definition: protocol.h:358
MSG_MASTERNODE_ANNOUNCE
@ MSG_MASTERNODE_ANNOUNCE
Definition: protocol.h:402
masternodeman.h
CMasternodeMan::stable_size
int stable_size()
Return the number of Masternodes older than (default) 8000 seconds.
Definition: masternodeman.cpp:358
uint256::GetCompact
uint32_t GetCompact(bool fNegative=false) const
Definition: uint256.cpp:34
CMasternode::vin
CTxIn vin
Definition: masternode.h:127
CMasternodeMan::GetMasternodeRanks
std::vector< std::pair< int, CMasternode > > GetMasternodeRanks(int64_t nBlockHeight, int minProtocol=0)
Definition: masternodeman.cpp:604
CMasternodeDB::IncorrectMagicNumber
@ IncorrectMagicNumber
Definition: masternodeman.h:47
CMasternodeMan::Remove
void Remove(CTxIn vin)
Definition: masternodeman.cpp:804
CNode::PushMessage
void PushMessage(const char *pszCommand)
Definition: net.h:518
CMasternodeMan::mWeAskedForMasternodeListEntry
std::map< COutPoint, int64_t > mWeAskedForMasternodeListEntry
Definition: masternodeman.h:72
CTxIn::masternodeStealthAddress
std::vector< unsigned char > masternodeStealthAddress
Definition: transaction.h:99
masternodeSync
CMasternodeSync masternodeSync
Definition: masternode-sync.cpp:19
ThreadCheckMasternodes
void ThreadCheckMasternodes()
Definition: masternodeman.cpp:847
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:303
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
ActiveProtocol
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
Definition: main.cpp:6844
CNetAddr::GetNetwork
enum Network GetNetwork() const
Definition: netaddress.cpp:229
CMasternodeMan::Clear
void Clear()
Clear Masternode vector.
Definition: masternodeman.cpp:346
mnodeman
CMasternodeMan mnodeman
Masternode manager.
Definition: masternodeman.cpp:22
NetMsgType::DSEG
const char * DSEG
Definition: protocol.cpp:32
CActiveMasternode::ManageStatus
void ManageStatus()
Manage status of main Masternode.
Definition: activemasternode.cpp:21
BCLog::MNPING
@ MNPING
Definition: logging.h:64
CMasternodePayments::CleanPaymentList
void CleanPaymentList()
Definition: masternode-payments.cpp:554
CMasternode::MASTERNODE_VIN_SPENT
@ MASTERNODE_VIN_SPENT
Definition: masternode.h:123
CMasternodeMan::GetMasternodeByRank
CMasternode * GetMasternodeByRank(int nRank, int64_t nBlockHeight, int minProtocol=0, bool fOnlyActive=true)
Definition: masternodeman.cpp:641
LookupHost
bool LookupHost(const char *pszName, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Definition: netbase.cpp:184
GetBlockHash
bool GetBlockHash(uint256 &hash, int nBlockHeight)
Definition: masternode.cpp:26
fLiteMode
bool fLiteMode
Definition: util.cpp:100
util::ThreadRename
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
Definition: threadnames.cpp:57
CDataStream::end
const_iterator end() const
Definition: streams.h:118
PAIRTYPE
#define PAIRTYPE(t1, t2)
This is needed because the foreach macro can't get over the comma in pair<t1, t2>
Definition: utilstrencodings.h:24
CChainParams::NetworkID
CBaseChainParams::Network NetworkID() const
Definition: chainparams.h:103
CBaseChainParams::MAIN
@ MAIN
Definition: chainparamsbase.h:19
CMasternodeDB::ReadResult
ReadResult
Definition: masternodeman.h:41
CMasternode::CalculateScore
uint256 CalculateScore(int mod=1, int64_t nBlockHeight=0)
Definition: masternode.cpp:171
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
masternodePayments
CMasternodePayments masternodePayments
Object for who's going to get paid on which blocks.
Definition: masternode-payments.cpp:19
MASTERNODE_MIN_MNP_SECONDS
#define MASTERNODE_MIN_MNP_SECONDS
Definition: masternode.h:19
CNetAddr::IsRFC1918
bool IsRFC1918() const
Definition: netaddress.cpp:90
SER_DISK
@ SER_DISK
Definition: serialize.h:160
CMasternodeDB::Write
bool Write(const CMasternodeMan &mnodemanToSave)
Definition: masternodeman.cpp:60
CMasternodeMan::mapSeenMasternodeBroadcast
std::map< uint256, CMasternodeBroadcast > mapSeenMasternodeBroadcast
Definition: masternodeman.h:76
CAutoFile::IsNull
bool IsNull() const
Return true if the wrapped FILE* is NULL, false otherwise.
Definition: streams.h:355
masternode-payments.h
CMasternodeDB::IncorrectFormat
@ IncorrectFormat
Definition: masternodeman.h:48
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
CMasternodeMan::Add
bool Add(CMasternode &mn)
Add an entry.
Definition: masternodeman.cpp:206
LogPrint
#define LogPrint(category,...)
Definition: logging.h:162
CMasternodeMan::GetCurrentMasterNode
CMasternode * GetCurrentMasterNode(int mod=1, int64_t nBlockHeight=0, int minProtocol=0)
Get the current winner for this block.
Definition: masternodeman.cpp:540
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:363
addrman
CAddrMan addrman
Definition: net.cpp:80
CMasternodeMan::Check
void Check()
Check all Masternodes.
Definition: masternodeman.cpp:241
CAutoFile::fclose
void fclose()
Definition: streams.h:328
MASTERNODES_DSEG_SECONDS
#define MASTERNODES_DSEG_SECONDS
Definition: masternodeman.h:20
CMasternodeMan::cs_process_message
RecursiveMutex cs_process_message
Definition: masternodeman.h:63
MASTERNODE_REMOVAL_SECONDS
#define MASTERNODE_REMOVAL_SECONDS
Definition: masternode.h:23
CMasternodeMan::ProcessMessage
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
Definition: masternodeman.cpp:672
CompareLastPaid::operator()
bool operator()(const std::pair< int64_t, CTxIn > &t1, const std::pair< int64_t, CTxIn > &t2) const
Definition: masternodeman.cpp:27
GetTimeMillis
int64_t GetTimeMillis()
Definition: utiltime.cpp:31
CMasternodeBroadcast::GetHash
uint256 GetHash()
Definition: masternode.h:322
messagesigner.h
CMasternodeMan::CountNetworks
void CountNetworks(int protocolVersion, int &ipv4, int &ipv6, int &onion)
Definition: masternodeman.cpp:393
CMasternode
Definition: masternode.h:107
CPubKey
An encapsulated public key.
Definition: pubkey.h:37
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:30
CompareScoreMN::operator()
bool operator()(const std::pair< int64_t, CMasternode > &t1, const std::pair< int64_t, CMasternode > &t2) const
Definition: masternodeman.cpp:43
CAddress
A CService with information about it as peer.
Definition: protocol.h:323
BCLog::MASTERNODE
@ MASTERNODE
Definition: logging.h:62
CMasternodeMan::cs
RecursiveMutex cs
Definition: masternodeman.h:60
CMasternodeMan::CMasternodeMan
CMasternodeMan()
Definition: masternodeman.cpp:201
CompareScoreTxIn::operator()
bool operator()(const std::pair< int64_t, CTxIn > &t1, const std::pair< int64_t, CTxIn > &t2) const
Definition: masternodeman.cpp:35
CMasternodeDB::IncorrectHash
@ IncorrectHash
Definition: masternodeman.h:45
CMasternodeMan::mapSeenMasternodePing
std::map< uint256, CMasternodePing > mapSeenMasternodePing
Definition: masternodeman.h:78
swifttx.h
LOCK
#define LOCK(cs)
Definition: sync.h:182
CMasternodeSync::mapSeenSyncMNB
std::map< uint256, int > mapSeenSyncMNB
Definition: masternode-sync.h:32
CMasternodeMan
Definition: masternodeman.h:56
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:86
CMasternodeMan::DsegUpdate
void DsegUpdate(CNode *pnode)
Definition: masternodeman.cpp:419
CMasternodeDB::pathMN
fs::path pathMN
Definition: masternodeman.h:37
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:349
masternode.h
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
CMasternodeDB::IncorrectMagicMessage
@ IncorrectMagicMessage
Definition: masternodeman.h:46
MilliSleep
void MilliSleep(int64_t n)
Definition: utiltime.cpp:45
MASTERNODE_PING_SECONDS
#define MASTERNODE_PING_SECONDS
Definition: masternode.h:21
NetMsgType::SYNCSTATUSCOUNT
const char * SYNCSTATUSCOUNT
The syncstatuscount message is used to track the layer 2 syncing process.
Definition: protocol.cpp:59
CMasternode::MASTERNODE_REMOVE
@ MASTERNODE_REMOVE
Definition: masternode.h:120
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:34
addrman.h
CMasternode::IsEnabled
bool IsEnabled()
Definition: masternode.h:242
netbase.h
DumpMasternodes
void DumpMasternodes()
Definition: masternodeman.cpp:174
CompareLastPaid
Definition: masternodeman.cpp:26
CMasternodeMan::mAskedUsForMasternodeList
std::map< CNetAddr, int64_t > mAskedUsForMasternodeList
Definition: masternodeman.h:68
CMasternodeMan::mWeAskedForMasternodeList
std::map< CNetAddr, int64_t > mWeAskedForMasternodeList
Definition: masternodeman.h:70
Hash
std::string Hash(std::string input)
Compute the 256-bit hash of a std::string.
Definition: hash.h:122
CleanTransactionLocksList
void CleanTransactionLocksList()
Definition: swifttx.cpp:424
MN_WINNER_MINIMUM_AGE
#define MN_WINNER_MINIMUM_AGE
Definition: masternodeman.cpp:19
CMasternodeBroadcast
Definition: masternode.h:292
CMasternodeMan::nDsqCount
int64_t nDsqCount
Definition: masternodeman.h:82
NetMsgType::MNPING
const char * MNPING
The mnping message is used to ensure a masternode is still active.
Definition: protocol.cpp:51
MASTERNODE_SYNC_LIST
#define MASTERNODE_SYNC_LIST
Definition: masternode-sync.h:11
CNetAddr::IsLocal
bool IsLocal() const
Definition: netaddress.cpp:168
util.h
CMasternodePayments::IsScheduled
bool IsScheduled(CMasternode &mn, int nNotBlockHeight)
Definition: masternode-payments.cpp:409
CMasternodeDB::CMasternodeDB
CMasternodeDB()
Definition: masternodeman.cpp:54
NetMsgType::MNBROADCAST
const char * MNBROADCAST
The mnbroadcast message is used to broadcast masternode startup data to connected peers.
Definition: protocol.cpp:50
CMasternodePing
Definition: masternode.h:39
CMasternodePing::GetHash
uint256 GetHash()
Definition: masternode.h:67
CMasternodeDB::Read
ReadResult Read(CMasternodeMan &mnodemanToLoad, bool fDryRun=false)
Definition: masternodeman.cpp:93
CMasternode::Check
void Check(bool forceCheck=false)
Definition: masternode.cpp:200
CMasternode::lastPing
CMasternodePing lastPing
Definition: masternode.h:145
error
bool error(const char *fmt, const Args &... args)
Definition: util.h:61
CMasternodeDB::strMagicMessage
std::string strMagicMessage
Definition: masternodeman.h:38
CMasternodeDB
Access to the MN database (mncache.dat)
Definition: masternodeman.h:34
CMasternodeSync::Process
void Process()
Definition: masternode-sync.cpp:229
Misbehaving
void Misbehaving(NodeId pnode, int howmuch) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Increase a node's misbehavior score.
Definition: main.cpp:2645
base_uint::ToString
std::string ToString() const
Definition: arith_uint256.cpp:199