Dash Core  0.12.2.1
P2P Digital Currency
masternodeman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "activemasternode.h"
6 #include "addrman.h"
7 #include "governance.h"
8 #include "masternode-payments.h"
9 #include "masternode-sync.h"
10 #include "masternodeman.h"
11 #include "messagesigner.h"
12 #include "netfulfilledman.h"
13 #include "privatesend-client.h"
14 #include "util.h"
15 
18 
19 const std::string CMasternodeMan::SERIALIZATION_VERSION_STRING = "CMasternodeMan-Version-7";
20 
22 {
23  bool operator()(const std::pair<int, CMasternode*>& t1,
24  const std::pair<int, CMasternode*>& t2) const
25  {
26  return (t1.first != t2.first) ? (t1.first < t2.first) : (t1.second->vin < t2.second->vin);
27  }
28 };
29 
31 {
32  bool operator()(const std::pair<arith_uint256, CMasternode*>& t1,
33  const std::pair<arith_uint256, CMasternode*>& t2) const
34  {
35  return (t1.first != t2.first) ? (t1.first < t2.first) : (t1.second->vin < t2.second->vin);
36  }
37 };
38 
40 
41 {
42  bool operator()(const CMasternode* t1,
43  const CMasternode* t2) const
44  {
45  return t1->addr < t2->addr;
46  }
47 };
48 
50 : cs(),
51  mapMasternodes(),
52  mAskedUsForMasternodeList(),
53  mWeAskedForMasternodeList(),
54  mWeAskedForMasternodeListEntry(),
55  mWeAskedForVerification(),
56  mMnbRecoveryRequests(),
57  mMnbRecoveryGoodReplies(),
58  listScheduledMnbRequestConnections(),
59  fMasternodesAdded(false),
60  fMasternodesRemoved(false),
61  vecDirtyGovernanceObjectHashes(),
62  nLastWatchdogVoteTime(0),
63  mapSeenMasternodeBroadcast(),
64  mapSeenMasternodePing(),
65  nDsqCount(0)
66 {}
67 
69 {
70  LOCK(cs);
71 
72  if (Has(mn.vin.prevout)) return false;
73 
74  LogPrint("masternode", "CMasternodeMan::Add -- Adding new Masternode: addr=%s, %i now\n", mn.addr.ToString(), size() + 1);
75  mapMasternodes[mn.vin.prevout] = mn;
76  fMasternodesAdded = true;
77  return true;
78 }
79 
80 void CMasternodeMan::AskForMN(CNode* pnode, const COutPoint& outpoint, CConnman& connman)
81 {
82  if(!pnode) return;
83 
84  LOCK(cs);
85 
86  std::map<COutPoint, std::map<CNetAddr, int64_t> >::iterator it1 = mWeAskedForMasternodeListEntry.find(outpoint);
87  if (it1 != mWeAskedForMasternodeListEntry.end()) {
88  std::map<CNetAddr, int64_t>::iterator it2 = it1->second.find(pnode->addr);
89  if (it2 != it1->second.end()) {
90  if (GetTime() < it2->second) {
91  // we've asked recently, should not repeat too often or we could get banned
92  return;
93  }
94  // we asked this node for this outpoint but it's ok to ask again already
95  LogPrintf("CMasternodeMan::AskForMN -- Asking same peer %s for missing masternode entry again: %s\n", pnode->addr.ToString(), outpoint.ToStringShort());
96  } else {
97  // we already asked for this outpoint but not this node
98  LogPrintf("CMasternodeMan::AskForMN -- Asking new peer %s for missing masternode entry: %s\n", pnode->addr.ToString(), outpoint.ToStringShort());
99  }
100  } else {
101  // we never asked any node for this outpoint
102  LogPrintf("CMasternodeMan::AskForMN -- Asking peer %s for missing masternode entry for the first time: %s\n", pnode->addr.ToString(), outpoint.ToStringShort());
103  }
105 
106  connman.PushMessage(pnode, NetMsgType::DSEG, CTxIn(outpoint));
107 }
108 
110 {
111  LOCK(cs);
112  CMasternode* pmn = Find(outpoint);
113  if (!pmn) {
114  return false;
115  }
116  nDsqCount++;
117  pmn->nLastDsq = nDsqCount;
118  pmn->fAllowMixingTx = true;
119 
120  return true;
121 }
122 
124 {
125  LOCK(cs);
126  CMasternode* pmn = Find(outpoint);
127  if (!pmn) {
128  return false;
129  }
130  pmn->fAllowMixingTx = false;
131 
132  return true;
133 }
134 
135 bool CMasternodeMan::PoSeBan(const COutPoint &outpoint)
136 {
137  LOCK(cs);
138  CMasternode* pmn = Find(outpoint);
139  if (!pmn) {
140  return false;
141  }
142  pmn->PoSeBan();
143 
144  return true;
145 }
146 
148 {
149  LOCK(cs);
150 
151  LogPrint("masternode", "CMasternodeMan::Check -- nLastWatchdogVoteTime=%d, IsWatchdogActive()=%d\n", nLastWatchdogVoteTime, IsWatchdogActive());
152 
153  for (auto& mnpair : mapMasternodes) {
154  mnpair.second.Check();
155  }
156 }
157 
159 {
161 
162  LogPrintf("CMasternodeMan::CheckAndRemove\n");
163 
164  {
165  // Need LOCK2 here to ensure consistent locking order because code below locks cs_main
166  // in CheckMnbAndUpdateMasternodeList()
167  LOCK2(cs_main, cs);
168 
169  Check();
170 
171  // Remove spent masternodes, prepare structures and make requests to reasure the state of inactive ones
172  rank_pair_vec_t vecMasternodeRanks;
173  // ask for up to MNB_RECOVERY_MAX_ASK_ENTRIES masternode entries at a time
174  int nAskForMnbRecovery = MNB_RECOVERY_MAX_ASK_ENTRIES;
175  std::map<COutPoint, CMasternode>::iterator it = mapMasternodes.begin();
176  while (it != mapMasternodes.end()) {
177  CMasternodeBroadcast mnb = CMasternodeBroadcast(it->second);
178  uint256 hash = mnb.GetHash();
179  // If collateral was spent ...
180  if (it->second.IsOutpointSpent()) {
181  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Removing Masternode: %s addr=%s %i now\n", it->second.GetStateString(), it->second.addr.ToString(), size() - 1);
182 
183  // erase all of the broadcasts we've seen from this txin, ...
184  mapSeenMasternodeBroadcast.erase(hash);
185  mWeAskedForMasternodeListEntry.erase(it->first);
186 
187  // and finally remove it from the list
188  it->second.FlagGovernanceItemsAsDirty();
189  mapMasternodes.erase(it++);
190  fMasternodesRemoved = true;
191  } else {
192  bool fAsk = (nAskForMnbRecovery > 0) &&
194  it->second.IsNewStartRequired() &&
195  !IsMnbRecoveryRequested(hash);
196  if(fAsk) {
197  // this mn is in a non-recoverable state and we haven't asked other nodes yet
198  std::set<CNetAddr> setRequested;
199  // calulate only once and only when it's needed
200  if(vecMasternodeRanks.empty()) {
201  int nRandomBlockHeight = GetRandInt(nCachedBlockHeight);
202  GetMasternodeRanks(vecMasternodeRanks, nRandomBlockHeight);
203  }
204  bool fAskedForMnbRecovery = false;
205  // ask first MNB_RECOVERY_QUORUM_TOTAL masternodes we can connect to and we haven't asked recently
206  for(int i = 0; setRequested.size() < MNB_RECOVERY_QUORUM_TOTAL && i < (int)vecMasternodeRanks.size(); i++) {
207  // avoid banning
208  if(mWeAskedForMasternodeListEntry.count(it->first) && mWeAskedForMasternodeListEntry[it->first].count(vecMasternodeRanks[i].second.addr)) continue;
209  // didn't ask recently, ok to ask now
210  CService addr = vecMasternodeRanks[i].second.addr;
211  setRequested.insert(addr);
212  listScheduledMnbRequestConnections.push_back(std::make_pair(addr, hash));
213  fAskedForMnbRecovery = true;
214  }
215  if(fAskedForMnbRecovery) {
216  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Recovery initiated, masternode=%s\n", it->first.ToStringShort());
217  nAskForMnbRecovery--;
218  }
219  // wait for mnb recovery replies for MNB_RECOVERY_WAIT_SECONDS seconds
220  mMnbRecoveryRequests[hash] = std::make_pair(GetTime() + MNB_RECOVERY_WAIT_SECONDS, setRequested);
221  }
222  ++it;
223  }
224  }
225 
226  // proces replies for MASTERNODE_NEW_START_REQUIRED masternodes
227  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- mMnbRecoveryGoodReplies size=%d\n", (int)mMnbRecoveryGoodReplies.size());
228  std::map<uint256, std::vector<CMasternodeBroadcast> >::iterator itMnbReplies = mMnbRecoveryGoodReplies.begin();
229  while(itMnbReplies != mMnbRecoveryGoodReplies.end()){
230  if(mMnbRecoveryRequests[itMnbReplies->first].first < GetTime()) {
231  // all nodes we asked should have replied now
232  if(itMnbReplies->second.size() >= MNB_RECOVERY_QUORUM_REQUIRED) {
233  // majority of nodes we asked agrees that this mn doesn't require new mnb, reprocess one of new mnbs
234  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- reprocessing mnb, masternode=%s\n", itMnbReplies->second[0].vin.prevout.ToStringShort());
235  // mapSeenMasternodeBroadcast.erase(itMnbReplies->first);
236  int nDos;
237  itMnbReplies->second[0].fRecovery = true;
238  CheckMnbAndUpdateMasternodeList(NULL, itMnbReplies->second[0], nDos, connman);
239  }
240  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- removing mnb recovery reply, masternode=%s, size=%d\n", itMnbReplies->second[0].vin.prevout.ToStringShort(), (int)itMnbReplies->second.size());
241  mMnbRecoveryGoodReplies.erase(itMnbReplies++);
242  } else {
243  ++itMnbReplies;
244  }
245  }
246  }
247  {
248  // no need for cm_main below
249  LOCK(cs);
250 
251  std::map<uint256, std::pair< int64_t, std::set<CNetAddr> > >::iterator itMnbRequest = mMnbRecoveryRequests.begin();
252  while(itMnbRequest != mMnbRecoveryRequests.end()){
253  // Allow this mnb to be re-verified again after MNB_RECOVERY_RETRY_SECONDS seconds
254  // if mn is still in MASTERNODE_NEW_START_REQUIRED state.
255  if(GetTime() - itMnbRequest->second.first > MNB_RECOVERY_RETRY_SECONDS) {
256  mMnbRecoveryRequests.erase(itMnbRequest++);
257  } else {
258  ++itMnbRequest;
259  }
260  }
261 
262  // check who's asked for the Masternode list
263  std::map<CNetAddr, int64_t>::iterator it1 = mAskedUsForMasternodeList.begin();
264  while(it1 != mAskedUsForMasternodeList.end()){
265  if((*it1).second < GetTime()) {
266  mAskedUsForMasternodeList.erase(it1++);
267  } else {
268  ++it1;
269  }
270  }
271 
272  // check who we asked for the Masternode list
273  it1 = mWeAskedForMasternodeList.begin();
274  while(it1 != mWeAskedForMasternodeList.end()){
275  if((*it1).second < GetTime()){
276  mWeAskedForMasternodeList.erase(it1++);
277  } else {
278  ++it1;
279  }
280  }
281 
282  // check which Masternodes we've asked for
283  std::map<COutPoint, std::map<CNetAddr, int64_t> >::iterator it2 = mWeAskedForMasternodeListEntry.begin();
284  while(it2 != mWeAskedForMasternodeListEntry.end()){
285  std::map<CNetAddr, int64_t>::iterator it3 = it2->second.begin();
286  while(it3 != it2->second.end()){
287  if(it3->second < GetTime()){
288  it2->second.erase(it3++);
289  } else {
290  ++it3;
291  }
292  }
293  if(it2->second.empty()) {
294  mWeAskedForMasternodeListEntry.erase(it2++);
295  } else {
296  ++it2;
297  }
298  }
299 
300  std::map<CNetAddr, CMasternodeVerification>::iterator it3 = mWeAskedForVerification.begin();
301  while(it3 != mWeAskedForVerification.end()){
302  if(it3->second.nBlockHeight < nCachedBlockHeight - MAX_POSE_BLOCKS) {
303  mWeAskedForVerification.erase(it3++);
304  } else {
305  ++it3;
306  }
307  }
308 
309  // NOTE: do not expire mapSeenMasternodeBroadcast entries here, clean them on mnb updates!
310 
311  // remove expired mapSeenMasternodePing
312  std::map<uint256, CMasternodePing>::iterator it4 = mapSeenMasternodePing.begin();
313  while(it4 != mapSeenMasternodePing.end()){
314  if((*it4).second.IsExpired()) {
315  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Removing expired Masternode ping: hash=%s\n", (*it4).second.GetHash().ToString());
316  mapSeenMasternodePing.erase(it4++);
317  } else {
318  ++it4;
319  }
320  }
321 
322  // remove expired mapSeenMasternodeVerification
323  std::map<uint256, CMasternodeVerification>::iterator itv2 = mapSeenMasternodeVerification.begin();
324  while(itv2 != mapSeenMasternodeVerification.end()){
325  if((*itv2).second.nBlockHeight < nCachedBlockHeight - MAX_POSE_BLOCKS){
326  LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Removing expired Masternode verification: hash=%s\n", (*itv2).first.ToString());
327  mapSeenMasternodeVerification.erase(itv2++);
328  } else {
329  ++itv2;
330  }
331  }
332 
333  LogPrintf("CMasternodeMan::CheckAndRemove -- %s\n", ToString());
334  }
335 
336  if(fMasternodesRemoved) {
337  NotifyMasternodeUpdates(connman);
338  }
339 }
340 
342 {
343  LOCK(cs);
344  mapMasternodes.clear();
349  mapSeenMasternodePing.clear();
350  nDsqCount = 0;
352 }
353 
354 int CMasternodeMan::CountMasternodes(int nProtocolVersion)
355 {
356  LOCK(cs);
357  int nCount = 0;
358  nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
359 
360  for (auto& mnpair : mapMasternodes) {
361  if(mnpair.second.nProtocolVersion < nProtocolVersion) continue;
362  nCount++;
363  }
364 
365  return nCount;
366 }
367 
368 int CMasternodeMan::CountEnabled(int nProtocolVersion)
369 {
370  LOCK(cs);
371  int nCount = 0;
372  nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
373 
374  for (auto& mnpair : mapMasternodes) {
375  if(mnpair.second.nProtocolVersion < nProtocolVersion || !mnpair.second.IsEnabled()) continue;
376  nCount++;
377  }
378 
379  return nCount;
380 }
381 
382 /* Only IPv4 masternodes are allowed in 12.1, saving this for later
383 int CMasternodeMan::CountByIP(int nNetworkType)
384 {
385  LOCK(cs);
386  int nNodeCount = 0;
387 
388  for (auto& mnpair : mapMasternodes)
389  if ((nNetworkType == NET_IPV4 && mnpair.second.addr.IsIPv4()) ||
390  (nNetworkType == NET_TOR && mnpair.second.addr.IsTor()) ||
391  (nNetworkType == NET_IPV6 && mnpair.second.addr.IsIPv6())) {
392  nNodeCount++;
393  }
394 
395  return nNodeCount;
396 }
397 */
398 
400 {
401  LOCK(cs);
402 
403  if(Params().NetworkIDString() == CBaseChainParams::MAIN) {
404  if(!(pnode->addr.IsRFC1918() || pnode->addr.IsLocal())) {
405  std::map<CNetAddr, int64_t>::iterator it = mWeAskedForMasternodeList.find(pnode->addr);
406  if(it != mWeAskedForMasternodeList.end() && GetTime() < (*it).second) {
407  LogPrintf("CMasternodeMan::DsegUpdate -- we already asked %s for the list; skipping...\n", pnode->addr.ToString());
408  return;
409  }
410  }
411  }
412 
413  connman.PushMessage(pnode, NetMsgType::DSEG, CTxIn());
414  int64_t askAgain = GetTime() + DSEG_UPDATE_SECONDS;
415  mWeAskedForMasternodeList[pnode->addr] = askAgain;
416 
417  LogPrint("masternode", "CMasternodeMan::DsegUpdate -- asked %s for the list\n", pnode->addr.ToString());
418 }
419 
421 {
422  LOCK(cs);
423  auto it = mapMasternodes.find(outpoint);
424  return it == mapMasternodes.end() ? NULL : &(it->second);
425 }
426 
427 bool CMasternodeMan::Get(const COutPoint& outpoint, CMasternode& masternodeRet)
428 {
429  // Theses mutexes are recursive so double locking by the same thread is safe.
430  LOCK(cs);
431  auto it = mapMasternodes.find(outpoint);
432  if (it == mapMasternodes.end()) {
433  return false;
434  }
435 
436  masternodeRet = it->second;
437  return true;
438 }
439 
441 {
442  LOCK(cs);
443  auto it = mapMasternodes.find(outpoint);
444  if (it == mapMasternodes.end()) {
445  return false;
446  }
447  mnInfoRet = it->second.GetInfo();
448  return true;
449 }
450 
451 bool CMasternodeMan::GetMasternodeInfo(const CPubKey& pubKeyMasternode, masternode_info_t& mnInfoRet)
452 {
453  LOCK(cs);
454  for (auto& mnpair : mapMasternodes) {
455  if (mnpair.second.pubKeyMasternode == pubKeyMasternode) {
456  mnInfoRet = mnpair.second.GetInfo();
457  return true;
458  }
459  }
460  return false;
461 }
462 
464 {
465  LOCK(cs);
466  for (auto& mnpair : mapMasternodes) {
467  CScript scriptCollateralAddress = GetScriptForDestination(mnpair.second.pubKeyCollateralAddress.GetID());
468  if (scriptCollateralAddress == payee) {
469  mnInfoRet = mnpair.second.GetInfo();
470  return true;
471  }
472  }
473  return false;
474 }
475 
476 bool CMasternodeMan::Has(const COutPoint& outpoint)
477 {
478  LOCK(cs);
479  return mapMasternodes.find(outpoint) != mapMasternodes.end();
480 }
481 
482 //
483 // Deterministically select the oldest/best masternode to pay on the network
484 //
485 bool CMasternodeMan::GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet)
486 {
487  return GetNextMasternodeInQueueForPayment(nCachedBlockHeight, fFilterSigTime, nCountRet, mnInfoRet);
488 }
489 
490 bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet)
491 {
492  mnInfoRet = masternode_info_t();
493  nCountRet = 0;
494 
496  // without winner list we can't reliably find the next winner anyway
497  return false;
498  }
499 
500  // Need LOCK2 here to ensure consistent locking order because the GetBlockHash call below locks cs_main
501  LOCK2(cs_main,cs);
502 
503  std::vector<std::pair<int, CMasternode*> > vecMasternodeLastPaid;
504 
505  /*
506  Make a vector with all of the last paid times
507  */
508 
509  int nMnCount = CountMasternodes();
510 
511  for (auto& mnpair : mapMasternodes) {
512  if(!mnpair.second.IsValidForPayment()) continue;
513 
514  //check protocol version
515  if(mnpair.second.nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
516 
517  //it's in the list (up to 8 entries ahead of current block to allow propagation) -- so let's skip it
518  if(mnpayments.IsScheduled(mnpair.second, nBlockHeight)) continue;
519 
520  //it's too new, wait for a cycle
521  if(fFilterSigTime && mnpair.second.sigTime + (nMnCount*2.6*60) > GetAdjustedTime()) continue;
522 
523  //make sure it has at least as many confirmations as there are masternodes
524  if(GetUTXOConfirmations(mnpair.first) < nMnCount) continue;
525 
526  vecMasternodeLastPaid.push_back(std::make_pair(mnpair.second.GetLastPaidBlock(), &mnpair.second));
527  }
528 
529  nCountRet = (int)vecMasternodeLastPaid.size();
530 
531  //when the network is in the process of upgrading, don't penalize nodes that recently restarted
532  if(fFilterSigTime && nCountRet < nMnCount/3)
533  return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCountRet, mnInfoRet);
534 
535  // Sort them low to high
536  sort(vecMasternodeLastPaid.begin(), vecMasternodeLastPaid.end(), CompareLastPaidBlock());
537 
538  uint256 blockHash;
539  if(!GetBlockHash(blockHash, nBlockHeight - 101)) {
540  LogPrintf("CMasternode::GetNextMasternodeInQueueForPayment -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", nBlockHeight - 101);
541  return false;
542  }
543  // Look at 1/10 of the oldest nodes (by last payment), calculate their scores and pay the best one
544  // -- This doesn't look at who is being paid in the +8-10 blocks, allowing for double payments very rarely
545  // -- 1/100 payments should be a double payment on mainnet - (1/(3000/10))*2
546  // -- (chance per block * chances before IsScheduled will fire)
547  int nTenthNetwork = nMnCount/10;
548  int nCountTenth = 0;
549  arith_uint256 nHighest = 0;
550  CMasternode *pBestMasternode = NULL;
551  BOOST_FOREACH (PAIRTYPE(int, CMasternode*)& s, vecMasternodeLastPaid){
552  arith_uint256 nScore = s.second->CalculateScore(blockHash);
553  if(nScore > nHighest){
554  nHighest = nScore;
555  pBestMasternode = s.second;
556  }
557  nCountTenth++;
558  if(nCountTenth >= nTenthNetwork) break;
559  }
560  if (pBestMasternode) {
561  mnInfoRet = pBestMasternode->GetInfo();
562  }
563  return mnInfoRet.fInfoValid;
564 }
565 
566 masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector<COutPoint> &vecToExclude, int nProtocolVersion)
567 {
568  LOCK(cs);
569 
570  nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
571 
572  int nCountEnabled = CountEnabled(nProtocolVersion);
573  int nCountNotExcluded = nCountEnabled - vecToExclude.size();
574 
575  LogPrintf("CMasternodeMan::FindRandomNotInVec -- %d enabled masternodes, %d masternodes to choose from\n", nCountEnabled, nCountNotExcluded);
576  if(nCountNotExcluded < 1) return masternode_info_t();
577 
578  // fill a vector of pointers
579  std::vector<CMasternode*> vpMasternodesShuffled;
580  for (auto& mnpair : mapMasternodes) {
581  vpMasternodesShuffled.push_back(&mnpair.second);
582  }
583 
584  InsecureRand insecureRand;
585  // shuffle pointers
586  std::random_shuffle(vpMasternodesShuffled.begin(), vpMasternodesShuffled.end(), insecureRand);
587  bool fExclude;
588 
589  // loop through
590  BOOST_FOREACH(CMasternode* pmn, vpMasternodesShuffled) {
591  if(pmn->nProtocolVersion < nProtocolVersion || !pmn->IsEnabled()) continue;
592  fExclude = false;
593  BOOST_FOREACH(const COutPoint &outpointToExclude, vecToExclude) {
594  if(pmn->vin.prevout == outpointToExclude) {
595  fExclude = true;
596  break;
597  }
598  }
599  if(fExclude) continue;
600  // found the one not in vecToExclude
601  LogPrint("masternode", "CMasternodeMan::FindRandomNotInVec -- found, masternode=%s\n", pmn->vin.prevout.ToStringShort());
602  return pmn->GetInfo();
603  }
604 
605  LogPrint("masternode", "CMasternodeMan::FindRandomNotInVec -- failed\n");
606  return masternode_info_t();
607 }
608 
609 bool CMasternodeMan::GetMasternodeScores(const uint256& nBlockHash, CMasternodeMan::score_pair_vec_t& vecMasternodeScoresRet, int nMinProtocol)
610 {
611  vecMasternodeScoresRet.clear();
612 
614  return false;
615 
617 
618  if (mapMasternodes.empty())
619  return false;
620 
621  // calculate scores
622  for (auto& mnpair : mapMasternodes) {
623  if (mnpair.second.nProtocolVersion >= nMinProtocol) {
624  vecMasternodeScoresRet.push_back(std::make_pair(mnpair.second.CalculateScore(nBlockHash), &mnpair.second));
625  }
626  }
627 
628  sort(vecMasternodeScoresRet.rbegin(), vecMasternodeScoresRet.rend(), CompareScoreMN());
629  return !vecMasternodeScoresRet.empty();
630 }
631 
632 bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet, int nBlockHeight, int nMinProtocol)
633 {
634  nRankRet = -1;
635 
637  return false;
638 
639  // make sure we know about this block
640  uint256 nBlockHash = uint256();
641  if (!GetBlockHash(nBlockHash, nBlockHeight)) {
642  LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
643  return false;
644  }
645 
646  LOCK(cs);
647 
648  score_pair_vec_t vecMasternodeScores;
649  if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol))
650  return false;
651 
652  int nRank = 0;
653  for (auto& scorePair : vecMasternodeScores) {
654  nRank++;
655  if(scorePair.second->vin.prevout == outpoint) {
656  nRankRet = nRank;
657  return true;
658  }
659  }
660 
661  return false;
662 }
663 
664 bool CMasternodeMan::GetMasternodeRanks(CMasternodeMan::rank_pair_vec_t& vecMasternodeRanksRet, int nBlockHeight, int nMinProtocol)
665 {
666  vecMasternodeRanksRet.clear();
667 
669  return false;
670 
671  // make sure we know about this block
672  uint256 nBlockHash = uint256();
673  if (!GetBlockHash(nBlockHash, nBlockHeight)) {
674  LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
675  return false;
676  }
677 
678  LOCK(cs);
679 
680  score_pair_vec_t vecMasternodeScores;
681  if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol))
682  return false;
683 
684  int nRank = 0;
685  for (auto& scorePair : vecMasternodeScores) {
686  nRank++;
687  vecMasternodeRanksRet.push_back(std::make_pair(nRank, *scorePair.second));
688  }
689 
690  return true;
691 }
692 
693 bool CMasternodeMan::GetMasternodeByRank(int nRankIn, masternode_info_t& mnInfoRet, int nBlockHeight, int nMinProtocol)
694 {
695  mnInfoRet = masternode_info_t();
696 
698  return false;
699 
700  // make sure we know about this block
701  uint256 nBlockHash = uint256();
702  if (!GetBlockHash(nBlockHash, nBlockHeight)) {
703  LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
704  return false;
705  }
706 
707  LOCK(cs);
708 
709  score_pair_vec_t vecMasternodeScores;
710  if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol))
711  return false;
712 
713  if (vecMasternodeScores.size() < nRankIn)
714  return false;
715 
716  int nRank = 0;
717  for (auto& scorePair : vecMasternodeScores) {
718  nRank++;
719  if(nRank == nRankIn) {
720  mnInfoRet = *scorePair.second;
721  return true;
722  }
723  }
724 
725  return false;
726 }
727 
729 {
730  //we don't care about this for regtest
731  if(Params().NetworkIDString() == CBaseChainParams::REGTEST) return;
732 
733  connman.ForEachNode(CConnman::AllNodes, [](CNode* pnode) {
734  if(pnode->fMasternode) {
735  if(privateSendClient.infoMixingMasternode.fInfoValid && pnode->addr == privateSendClient.infoMixingMasternode.addr)
736  return;
737  LogPrintf("Closing Masternode connection: peer=%d, addr=%s\n", pnode->id, pnode->addr.ToString());
738  pnode->fDisconnect = true;
739  }
740  });
741 }
742 
743 std::pair<CService, std::set<uint256> > CMasternodeMan::PopScheduledMnbRequestConnection()
744 {
745  LOCK(cs);
747  return std::make_pair(CService(), std::set<uint256>());
748  }
749 
750  std::set<uint256> setResult;
751 
753  std::pair<CService, uint256> pairFront = listScheduledMnbRequestConnections.front();
754 
755  // squash hashes from requests with the same CService as the first one into setResult
756  std::list< std::pair<CService, uint256> >::iterator it = listScheduledMnbRequestConnections.begin();
757  while(it != listScheduledMnbRequestConnections.end()) {
758  if(pairFront.first == it->first) {
759  setResult.insert(it->second);
760  it = listScheduledMnbRequestConnections.erase(it);
761  } else {
762  // since list is sorted now, we can be sure that there is no more hashes left
763  // to ask for from this addr
764  break;
765  }
766  }
767  return std::make_pair(pairFront.first, setResult);
768 }
769 
770 
771 void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman)
772 {
773  if(fLiteMode) return; // disable all Dash specific functionality
774  if(!masternodeSync.IsBlockchainSynced()) return;
775 
776  if (strCommand == NetMsgType::MNANNOUNCE) { //Masternode Broadcast
777 
779  vRecv >> mnb;
780 
781  pfrom->setAskFor.erase(mnb.GetHash());
782 
783  LogPrint("masternode", "MNANNOUNCE -- Masternode announce, masternode=%s\n", mnb.vin.prevout.ToStringShort());
784 
785  int nDos = 0;
786 
787  if (CheckMnbAndUpdateMasternodeList(pfrom, mnb, nDos, connman)) {
788  // use announced Masternode as a peer
789  connman.AddNewAddress(CAddress(mnb.addr, NODE_NETWORK), pfrom->addr, 2*60*60);
790  } else if(nDos > 0) {
791  Misbehaving(pfrom->GetId(), nDos);
792  }
793 
794  if(fMasternodesAdded) {
795  NotifyMasternodeUpdates(connman);
796  }
797  } else if (strCommand == NetMsgType::MNPING) { //Masternode Ping
798 
799  CMasternodePing mnp;
800  vRecv >> mnp;
801 
802  uint256 nHash = mnp.GetHash();
803 
804  pfrom->setAskFor.erase(nHash);
805 
806  LogPrint("masternode", "MNPING -- Masternode ping, masternode=%s\n", mnp.vin.prevout.ToStringShort());
807 
808  // Need LOCK2 here to ensure consistent locking order because the CheckAndUpdate call below locks cs_main
809  LOCK2(cs_main, cs);
810 
811  if(mapSeenMasternodePing.count(nHash)) return; //seen
812  mapSeenMasternodePing.insert(std::make_pair(nHash, mnp));
813 
814  LogPrint("masternode", "MNPING -- Masternode ping, masternode=%s new\n", mnp.vin.prevout.ToStringShort());
815 
816  // see if we have this Masternode
817  CMasternode* pmn = Find(mnp.vin.prevout);
818 
819  // if masternode uses sentinel ping instead of watchdog
820  // we shoud update nTimeLastWatchdogVote here if sentinel
821  // ping flag is actual
822  if(pmn && mnp.fSentinelIsCurrent)
823  UpdateWatchdogVoteTime(mnp.vin.prevout, mnp.sigTime);
824 
825  // too late, new MNANNOUNCE is required
826  if(pmn && pmn->IsNewStartRequired()) return;
827 
828  int nDos = 0;
829  if(mnp.CheckAndUpdate(pmn, false, nDos, connman)) return;
830 
831  if(nDos > 0) {
832  // if anything significant failed, mark that node
833  Misbehaving(pfrom->GetId(), nDos);
834  } else if(pmn != NULL) {
835  // nothing significant failed, mn is a known one too
836  return;
837  }
838 
839  // something significant is broken or mn is unknown,
840  // we might have to ask for a masternode entry once
841  AskForMN(pfrom, mnp.vin.prevout, connman);
842 
843  } else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry
844  // Ignore such requests until we are fully synced.
845  // We could start processing this after masternode list is synced
846  // but this is a heavy one so it's better to finish sync first.
847  if (!masternodeSync.IsSynced()) return;
848 
849  CTxIn vin;
850  vRecv >> vin;
851 
852  LogPrint("masternode", "DSEG -- Masternode list, masternode=%s\n", vin.prevout.ToStringShort());
853 
854  LOCK(cs);
855 
856  if(vin == CTxIn()) { //only should ask for this once
857  //local network
858  bool isLocal = (pfrom->addr.IsRFC1918() || pfrom->addr.IsLocal());
859 
860  if(!isLocal && Params().NetworkIDString() == CBaseChainParams::MAIN) {
861  std::map<CNetAddr, int64_t>::iterator it = mAskedUsForMasternodeList.find(pfrom->addr);
862  if (it != mAskedUsForMasternodeList.end() && it->second > GetTime()) {
863  Misbehaving(pfrom->GetId(), 34);
864  LogPrintf("DSEG -- peer already asked me for the list, peer=%d\n", pfrom->id);
865  return;
866  }
867  int64_t askAgain = GetTime() + DSEG_UPDATE_SECONDS;
868  mAskedUsForMasternodeList[pfrom->addr] = askAgain;
869  }
870  } //else, asking for a specific node which is ok
871 
872  int nInvCount = 0;
873 
874  for (auto& mnpair : mapMasternodes) {
875  if (vin != CTxIn() && vin != mnpair.second.vin) continue; // asked for specific vin but we are not there yet
876  if (mnpair.second.addr.IsRFC1918() || mnpair.second.addr.IsLocal()) continue; // do not send local network masternode
877  if (mnpair.second.IsUpdateRequired()) continue; // do not send outdated masternodes
878 
879  LogPrint("masternode", "DSEG -- Sending Masternode entry: masternode=%s addr=%s\n", mnpair.first.ToStringShort(), mnpair.second.addr.ToString());
880  CMasternodeBroadcast mnb = CMasternodeBroadcast(mnpair.second);
881  uint256 hash = mnb.GetHash();
883  pfrom->PushInventory(CInv(MSG_MASTERNODE_PING, mnpair.second.lastPing.GetHash()));
884  nInvCount++;
885 
886  if (!mapSeenMasternodeBroadcast.count(hash)) {
887  mapSeenMasternodeBroadcast.insert(std::make_pair(hash, std::make_pair(GetTime(), mnb)));
888  }
889 
890  if (vin.prevout == mnpair.first) {
891  LogPrintf("DSEG -- Sent 1 Masternode inv to peer %d\n", pfrom->id);
892  return;
893  }
894  }
895 
896  if(vin == CTxIn()) {
898  LogPrintf("DSEG -- Sent %d Masternode invs to peer %d\n", nInvCount, pfrom->id);
899  return;
900  }
901  // smth weird happen - someone asked us for vin we have no idea about?
902  LogPrint("masternode", "DSEG -- No invs sent to peer %d\n", pfrom->id);
903 
904  } else if (strCommand == NetMsgType::MNVERIFY) { // Masternode Verify
905 
906  // Need LOCK2 here to ensure consistent locking order because the all functions below call GetBlockHash which locks cs_main
907  LOCK2(cs_main, cs);
908 
910  vRecv >> mnv;
911 
912  if(mnv.vchSig1.empty()) {
913  // CASE 1: someone asked me to verify myself /IP we are using/
914  SendVerifyReply(pfrom, mnv, connman);
915  } else if (mnv.vchSig2.empty()) {
916  // CASE 2: we _probably_ got verification we requested from some masternode
917  ProcessVerifyReply(pfrom, mnv);
918  } else {
919  // CASE 3: we _probably_ got verification broadcast signed by some masternode which verified another one
920  ProcessVerifyBroadcast(pfrom, mnv);
921  }
922  }
923 }
924 
925 // Verification of masternodes via unique direct requests.
926 
928 {
929  if(activeMasternode.outpoint == COutPoint()) return;
930  if(!masternodeSync.IsSynced()) return;
931 
932  rank_pair_vec_t vecMasternodeRanks;
934 
935  // Need LOCK2 here to ensure consistent locking order because the SendVerifyRequest call below locks cs_main
936  // through GetHeight() signal in ConnectNode
937  LOCK2(cs_main, cs);
938 
939  int nCount = 0;
940 
941  int nMyRank = -1;
942  int nRanksTotal = (int)vecMasternodeRanks.size();
943 
944  // send verify requests only if we are in top MAX_POSE_RANK
945  std::vector<std::pair<int, CMasternode> >::iterator it = vecMasternodeRanks.begin();
946  while(it != vecMasternodeRanks.end()) {
947  if(it->first > MAX_POSE_RANK) {
948  LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Must be in top %d to send verify request\n",
949  (int)MAX_POSE_RANK);
950  return;
951  }
952  if(it->second.vin.prevout == activeMasternode.outpoint) {
953  nMyRank = it->first;
954  LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Found self at rank %d/%d, verifying up to %d masternodes\n",
955  nMyRank, nRanksTotal, (int)MAX_POSE_CONNECTIONS);
956  break;
957  }
958  ++it;
959  }
960 
961  // edge case: list is too short and this masternode is not enabled
962  if(nMyRank == -1) return;
963 
964  // send verify requests to up to MAX_POSE_CONNECTIONS masternodes
965  // starting from MAX_POSE_RANK + nMyRank and using MAX_POSE_CONNECTIONS as a step
966  int nOffset = MAX_POSE_RANK + nMyRank - 1;
967  if(nOffset >= (int)vecMasternodeRanks.size()) return;
968 
969  std::vector<CMasternode*> vSortedByAddr;
970  for (auto& mnpair : mapMasternodes) {
971  vSortedByAddr.push_back(&mnpair.second);
972  }
973 
974  sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr());
975 
976  it = vecMasternodeRanks.begin() + nOffset;
977  while(it != vecMasternodeRanks.end()) {
978  if(it->second.IsPoSeVerified() || it->second.IsPoSeBanned()) {
979  LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Already %s%s%s masternode %s address %s, skipping...\n",
980  it->second.IsPoSeVerified() ? "verified" : "",
981  it->second.IsPoSeVerified() && it->second.IsPoSeBanned() ? " and " : "",
982  it->second.IsPoSeBanned() ? "banned" : "",
983  it->second.vin.prevout.ToStringShort(), it->second.addr.ToString());
984  nOffset += MAX_POSE_CONNECTIONS;
985  if(nOffset >= (int)vecMasternodeRanks.size()) break;
986  it += MAX_POSE_CONNECTIONS;
987  continue;
988  }
989  LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Verifying masternode %s rank %d/%d address %s\n",
990  it->second.vin.prevout.ToStringShort(), it->first, nRanksTotal, it->second.addr.ToString());
991  if(SendVerifyRequest(CAddress(it->second.addr, NODE_NETWORK), vSortedByAddr, connman)) {
992  nCount++;
993  if(nCount >= MAX_POSE_CONNECTIONS) break;
994  }
995  nOffset += MAX_POSE_CONNECTIONS;
996  if(nOffset >= (int)vecMasternodeRanks.size()) break;
997  it += MAX_POSE_CONNECTIONS;
998  }
999 
1000  LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Sent verification requests to %d masternodes\n", nCount);
1001 }
1002 
1003 // This function tries to find masternodes with the same addr,
1004 // find a verified one and ban all the other. If there are many nodes
1005 // with the same addr but none of them is verified yet, then none of them are banned.
1006 // It could take many times to run this before most of the duplicate nodes are banned.
1007 
1009 {
1010  if(!masternodeSync.IsSynced() || mapMasternodes.empty()) return;
1011 
1012  std::vector<CMasternode*> vBan;
1013  std::vector<CMasternode*> vSortedByAddr;
1014 
1015  {
1016  LOCK(cs);
1017 
1018  CMasternode* pprevMasternode = NULL;
1019  CMasternode* pverifiedMasternode = NULL;
1020 
1021  for (auto& mnpair : mapMasternodes) {
1022  vSortedByAddr.push_back(&mnpair.second);
1023  }
1024 
1025  sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr());
1026 
1027  BOOST_FOREACH(CMasternode* pmn, vSortedByAddr) {
1028  // check only (pre)enabled masternodes
1029  if(!pmn->IsEnabled() && !pmn->IsPreEnabled()) continue;
1030  // initial step
1031  if(!pprevMasternode) {
1032  pprevMasternode = pmn;
1033  pverifiedMasternode = pmn->IsPoSeVerified() ? pmn : NULL;
1034  continue;
1035  }
1036  // second+ step
1037  if(pmn->addr == pprevMasternode->addr) {
1038  if(pverifiedMasternode) {
1039  // another masternode with the same ip is verified, ban this one
1040  vBan.push_back(pmn);
1041  } else if(pmn->IsPoSeVerified()) {
1042  // this masternode with the same ip is verified, ban previous one
1043  vBan.push_back(pprevMasternode);
1044  // and keep a reference to be able to ban following masternodes with the same ip
1045  pverifiedMasternode = pmn;
1046  }
1047  } else {
1048  pverifiedMasternode = pmn->IsPoSeVerified() ? pmn : NULL;
1049  }
1050  pprevMasternode = pmn;
1051  }
1052  }
1053 
1054  // ban duplicates
1055  BOOST_FOREACH(CMasternode* pmn, vBan) {
1056  LogPrintf("CMasternodeMan::CheckSameAddr -- increasing PoSe ban score for masternode %s\n", pmn->vin.prevout.ToStringShort());
1057  pmn->IncreasePoSeBanScore();
1058  }
1059 }
1060 
1061 bool CMasternodeMan::SendVerifyRequest(const CAddress& addr, const std::vector<CMasternode*>& vSortedByAddr, CConnman& connman)
1062 {
1063  if(netfulfilledman.HasFulfilledRequest(addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request")) {
1064  // we already asked for verification, not a good idea to do this too often, skip it
1065  LogPrint("masternode", "CMasternodeMan::SendVerifyRequest -- too many requests, skipping... addr=%s\n", addr.ToString());
1066  return false;
1067  }
1068 
1069  CNode* pnode = connman.ConnectNode(addr, NULL, true);
1070  if(pnode == NULL) {
1071  LogPrintf("CMasternodeMan::SendVerifyRequest -- can't connect to node to verify it, addr=%s\n", addr.ToString());
1072  return false;
1073  }
1074 
1076  // use random nonce, store it and require node to reply with correct one later
1077  CMasternodeVerification mnv(addr, GetRandInt(999999), nCachedBlockHeight - 1);
1078  mWeAskedForVerification[addr] = mnv;
1079  LogPrintf("CMasternodeMan::SendVerifyRequest -- verifying node using nonce %d addr=%s\n", mnv.nonce, addr.ToString());
1080  connman.PushMessage(pnode, NetMsgType::MNVERIFY, mnv);
1081 
1082  return true;
1083 }
1084 
1086 {
1087  // only masternodes can sign this, why would someone ask regular node?
1088  if(!fMasterNode) {
1089  // do not ban, malicious node might be using my IP
1090  // and trying to confuse the node which tries to verify it
1091  return;
1092  }
1093 
1095  // peer should not ask us that often
1096  LogPrintf("MasternodeMan::SendVerifyReply -- ERROR: peer already asked me recently, peer=%d\n", pnode->id);
1097  Misbehaving(pnode->id, 20);
1098  return;
1099  }
1100 
1101  uint256 blockHash;
1102  if(!GetBlockHash(blockHash, mnv.nBlockHeight)) {
1103  LogPrintf("MasternodeMan::SendVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id);
1104  return;
1105  }
1106 
1107  std::string strMessage = strprintf("%s%d%s", activeMasternode.service.ToString(false), mnv.nonce, blockHash.ToString());
1108 
1110  LogPrintf("MasternodeMan::SendVerifyReply -- SignMessage() failed\n");
1111  return;
1112  }
1113 
1114  std::string strError;
1115 
1116  if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig1, strMessage, strError)) {
1117  LogPrintf("MasternodeMan::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError);
1118  return;
1119  }
1120 
1121  connman.PushMessage(pnode, NetMsgType::MNVERIFY, mnv);
1123 }
1124 
1126 {
1127  std::string strError;
1128 
1129  // did we even ask for it? if that's the case we should have matching fulfilled request
1130  if(!netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request")) {
1131  LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: we didn't ask for verification of %s, peer=%d\n", pnode->addr.ToString(), pnode->id);
1132  Misbehaving(pnode->id, 20);
1133  return;
1134  }
1135 
1136  // Received nonce for a known address must match the one we sent
1137  if(mWeAskedForVerification[pnode->addr].nonce != mnv.nonce) {
1138  LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nounce: requested=%d, received=%d, peer=%d\n",
1139  mWeAskedForVerification[pnode->addr].nonce, mnv.nonce, pnode->id);
1140  Misbehaving(pnode->id, 20);
1141  return;
1142  }
1143 
1144  // Received nBlockHeight for a known address must match the one we sent
1145  if(mWeAskedForVerification[pnode->addr].nBlockHeight != mnv.nBlockHeight) {
1146  LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nBlockHeight: requested=%d, received=%d, peer=%d\n",
1147  mWeAskedForVerification[pnode->addr].nBlockHeight, mnv.nBlockHeight, pnode->id);
1148  Misbehaving(pnode->id, 20);
1149  return;
1150  }
1151 
1152  uint256 blockHash;
1153  if(!GetBlockHash(blockHash, mnv.nBlockHeight)) {
1154  // this shouldn't happen...
1155  LogPrintf("MasternodeMan::ProcessVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id);
1156  return;
1157  }
1158 
1159  // we already verified this address, why node is spamming?
1161  LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: already verified %s recently\n", pnode->addr.ToString());
1162  Misbehaving(pnode->id, 20);
1163  return;
1164  }
1165 
1166  {
1167  LOCK(cs);
1168 
1169  CMasternode* prealMasternode = NULL;
1170  std::vector<CMasternode*> vpMasternodesToBan;
1171  std::string strMessage1 = strprintf("%s%d%s", pnode->addr.ToString(false), mnv.nonce, blockHash.ToString());
1172  for (auto& mnpair : mapMasternodes) {
1173  if(CAddress(mnpair.second.addr, NODE_NETWORK) == pnode->addr) {
1174  if(CMessageSigner::VerifyMessage(mnpair.second.pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) {
1175  // found it!
1176  prealMasternode = &mnpair.second;
1177  if(!mnpair.second.IsPoSeVerified()) {
1178  mnpair.second.DecreasePoSeBanScore();
1179  }
1181 
1182  // we can only broadcast it if we are an activated masternode
1183  if(activeMasternode.outpoint == COutPoint()) continue;
1184  // update ...
1185  mnv.addr = mnpair.second.addr;
1186  mnv.vin1 = mnpair.second.vin;
1188  std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(),
1190  // ... and sign it
1192  LogPrintf("MasternodeMan::ProcessVerifyReply -- SignMessage() failed\n");
1193  return;
1194  }
1195 
1196  std::string strError;
1197 
1198  if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) {
1199  LogPrintf("MasternodeMan::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError);
1200  return;
1201  }
1202 
1203  mWeAskedForVerification[pnode->addr] = mnv;
1204  mnv.Relay();
1205 
1206  } else {
1207  vpMasternodesToBan.push_back(&mnpair.second);
1208  }
1209  }
1210  }
1211  // no real masternode found?...
1212  if(!prealMasternode) {
1213  // this should never be the case normally,
1214  // only if someone is trying to game the system in some way or smth like that
1215  LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: no real masternode found for addr %s\n", pnode->addr.ToString());
1216  Misbehaving(pnode->id, 20);
1217  return;
1218  }
1219  LogPrintf("CMasternodeMan::ProcessVerifyReply -- verified real masternode %s for addr %s\n",
1220  prealMasternode->vin.prevout.ToStringShort(), pnode->addr.ToString());
1221  // increase ban score for everyone else
1222  BOOST_FOREACH(CMasternode* pmn, vpMasternodesToBan) {
1223  pmn->IncreasePoSeBanScore();
1224  LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n",
1225  prealMasternode->vin.prevout.ToStringShort(), pnode->addr.ToString(), pmn->nPoSeBanScore);
1226  }
1227  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- PoSe score increased for %d fake masternodes, addr %s\n",
1228  (int)vpMasternodesToBan.size(), pnode->addr.ToString());
1229  }
1230 }
1231 
1233 {
1234  std::string strError;
1235 
1237  // we already have one
1238  return;
1239  }
1241 
1242  // we don't care about history
1244  LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Outdated: current block %d, verification block %d, peer=%d\n",
1245  nCachedBlockHeight, mnv.nBlockHeight, pnode->id);
1246  return;
1247  }
1248 
1249  if(mnv.vin1.prevout == mnv.vin2.prevout) {
1250  LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- ERROR: same vins %s, peer=%d\n",
1251  mnv.vin1.prevout.ToStringShort(), pnode->id);
1252  // that was NOT a good idea to cheat and verify itself,
1253  // ban the node we received such message from
1254  Misbehaving(pnode->id, 100);
1255  return;
1256  }
1257 
1258  uint256 blockHash;
1259  if(!GetBlockHash(blockHash, mnv.nBlockHeight)) {
1260  // this shouldn't happen...
1261  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id);
1262  return;
1263  }
1264 
1265  int nRank;
1266 
1268  LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n",
1269  mnv.vin2.prevout.ToStringShort());
1270  return;
1271  }
1272 
1273  if(nRank > MAX_POSE_RANK) {
1274  LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Masternode %s is not in top %d, current rank %d, peer=%d\n",
1275  mnv.vin2.prevout.ToStringShort(), (int)MAX_POSE_RANK, nRank, pnode->id);
1276  return;
1277  }
1278 
1279  {
1280  LOCK(cs);
1281 
1282  std::string strMessage1 = strprintf("%s%d%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString());
1283  std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(),
1285 
1286  CMasternode* pmn1 = Find(mnv.vin1.prevout);
1287  if(!pmn1) {
1288  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- can't find masternode1 %s\n", mnv.vin1.prevout.ToStringShort());
1289  return;
1290  }
1291 
1292  CMasternode* pmn2 = Find(mnv.vin2.prevout);
1293  if(!pmn2) {
1294  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- can't find masternode2 %s\n", mnv.vin2.prevout.ToStringShort());
1295  return;
1296  }
1297 
1298  if(pmn1->addr != mnv.addr) {
1299  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- addr %s do not match %s\n", mnv.addr.ToString(), pnode->addr.ToString());
1300  return;
1301  }
1302 
1303  if(CMessageSigner::VerifyMessage(pmn1->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) {
1304  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode1 failed, error: %s\n", strError);
1305  return;
1306  }
1307 
1308  if(CMessageSigner::VerifyMessage(pmn2->pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) {
1309  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode2 failed, error: %s\n", strError);
1310  return;
1311  }
1312 
1313  if(!pmn1->IsPoSeVerified()) {
1314  pmn1->DecreasePoSeBanScore();
1315  }
1316  mnv.Relay();
1317 
1318  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- verified masternode %s for addr %s\n",
1319  pmn1->vin.prevout.ToStringShort(), pnode->addr.ToString());
1320 
1321  // increase ban score for everyone else with the same addr
1322  int nCount = 0;
1323  for (auto& mnpair : mapMasternodes) {
1324  if(mnpair.second.addr != mnv.addr || mnpair.first == mnv.vin1.prevout) continue;
1325  mnpair.second.IncreasePoSeBanScore();
1326  nCount++;
1327  LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n",
1328  mnpair.first.ToStringShort(), mnpair.second.addr.ToString(), mnpair.second.nPoSeBanScore);
1329  }
1330  LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- PoSe score incresed for %d fake masternodes, addr %s\n",
1331  nCount, pnode->addr.ToString());
1332  }
1333 }
1334 
1335 std::string CMasternodeMan::ToString() const
1336 {
1337  std::ostringstream info;
1338 
1339  info << "Masternodes: " << (int)mapMasternodes.size() <<
1340  ", peers who asked us for Masternode list: " << (int)mAskedUsForMasternodeList.size() <<
1341  ", peers we asked for Masternode list: " << (int)mWeAskedForMasternodeList.size() <<
1342  ", entries in Masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size() <<
1343  ", nDsqCount: " << (int)nDsqCount;
1344 
1345  return info.str();
1346 }
1347 
1349 {
1350  LOCK2(cs_main, cs);
1351  mapSeenMasternodePing.insert(std::make_pair(mnb.lastPing.GetHash(), mnb.lastPing));
1352  mapSeenMasternodeBroadcast.insert(std::make_pair(mnb.GetHash(), std::make_pair(GetTime(), mnb)));
1353 
1354  LogPrintf("CMasternodeMan::UpdateMasternodeList -- masternode=%s addr=%s\n", mnb.vin.prevout.ToStringShort(), mnb.addr.ToString());
1355 
1356  CMasternode* pmn = Find(mnb.vin.prevout);
1357  if(pmn == NULL) {
1358  if(Add(mnb)) {
1359  masternodeSync.BumpAssetLastTime("CMasternodeMan::UpdateMasternodeList - new");
1360  }
1361  } else {
1363  if(pmn->UpdateFromNewBroadcast(mnb, connman)) {
1364  masternodeSync.BumpAssetLastTime("CMasternodeMan::UpdateMasternodeList - seen");
1365  mapSeenMasternodeBroadcast.erase(mnbOld.GetHash());
1366  }
1367  }
1368 }
1369 
1371 {
1372  // Need to lock cs_main here to ensure consistent locking order because the SimpleCheck call below locks cs_main
1373  LOCK(cs_main);
1374 
1375  {
1376  LOCK(cs);
1377  nDos = 0;
1378  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s\n", mnb.vin.prevout.ToStringShort());
1379 
1380  uint256 hash = mnb.GetHash();
1381  if(mapSeenMasternodeBroadcast.count(hash) && !mnb.fRecovery) { //seen
1382  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s seen\n", mnb.vin.prevout.ToStringShort());
1383  // less then 2 pings left before this MN goes into non-recoverable state, bump sync timeout
1385  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s seen update\n", mnb.vin.prevout.ToStringShort());
1386  mapSeenMasternodeBroadcast[hash].first = GetTime();
1387  masternodeSync.BumpAssetLastTime("CMasternodeMan::CheckMnbAndUpdateMasternodeList - seen");
1388  }
1389  // did we ask this node for it?
1390  if(pfrom && IsMnbRecoveryRequested(hash) && GetTime() < mMnbRecoveryRequests[hash].first) {
1391  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- mnb=%s seen request\n", hash.ToString());
1392  if(mMnbRecoveryRequests[hash].second.count(pfrom->addr)) {
1393  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- mnb=%s seen request, addr=%s\n", hash.ToString(), pfrom->addr.ToString());
1394  // do not allow node to send same mnb multiple times in recovery mode
1395  mMnbRecoveryRequests[hash].second.erase(pfrom->addr);
1396  // does it have newer lastPing?
1397  if(mnb.lastPing.sigTime > mapSeenMasternodeBroadcast[hash].second.lastPing.sigTime) {
1398  // simulate Check
1399  CMasternode mnTemp = CMasternode(mnb);
1400  mnTemp.Check();
1401  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- mnb=%s seen request, addr=%s, better lastPing: %d min ago, projected mn state: %s\n", hash.ToString(), pfrom->addr.ToString(), (GetAdjustedTime() - mnb.lastPing.sigTime)/60, mnTemp.GetStateString());
1402  if(mnTemp.IsValidStateForAutoStart(mnTemp.nActiveState)) {
1403  // this node thinks it's a good one
1404  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s seen good\n", mnb.vin.prevout.ToStringShort());
1405  mMnbRecoveryGoodReplies[hash].push_back(mnb);
1406  }
1407  }
1408  }
1409  }
1410  return true;
1411  }
1412  mapSeenMasternodeBroadcast.insert(std::make_pair(hash, std::make_pair(GetTime(), mnb)));
1413 
1414  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s new\n", mnb.vin.prevout.ToStringShort());
1415 
1416  if(!mnb.SimpleCheck(nDos)) {
1417  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- SimpleCheck() failed, masternode=%s\n", mnb.vin.prevout.ToStringShort());
1418  return false;
1419  }
1420 
1421  // search Masternode list
1422  CMasternode* pmn = Find(mnb.vin.prevout);
1423  if(pmn) {
1425  if(!mnb.Update(pmn, nDos, connman)) {
1426  LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Update() failed, masternode=%s\n", mnb.vin.prevout.ToStringShort());
1427  return false;
1428  }
1429  if(hash != mnbOld.GetHash()) {
1430  mapSeenMasternodeBroadcast.erase(mnbOld.GetHash());
1431  }
1432  return true;
1433  }
1434  }
1435 
1436  if(mnb.CheckOutpoint(nDos)) {
1437  Add(mnb);
1438  masternodeSync.BumpAssetLastTime("CMasternodeMan::CheckMnbAndUpdateMasternodeList - new");
1439  // if it matches our Masternode privkey...
1442  if(mnb.nProtocolVersion == PROTOCOL_VERSION) {
1443  // ... and PROTOCOL_VERSION, then we've been remotely activated ...
1444  LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Got NEW Masternode entry: masternode=%s sigTime=%lld addr=%s\n",
1445  mnb.vin.prevout.ToStringShort(), mnb.sigTime, mnb.addr.ToString());
1446  activeMasternode.ManageState(connman);
1447  } else {
1448  // ... otherwise we need to reactivate our node, do not add it to the list and do not relay
1449  // but also do not ban the node we get this message from
1450  LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- wrong PROTOCOL_VERSION, re-activate your MN: message nProtocolVersion=%d PROTOCOL_VERSION=%d\n", mnb.nProtocolVersion, PROTOCOL_VERSION);
1451  return false;
1452  }
1453  }
1454  mnb.Relay(connman);
1455  } else {
1456  LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Rejected Masternode entry: %s addr=%s\n", mnb.vin.prevout.ToStringShort(), mnb.addr.ToString());
1457  return false;
1458  }
1459 
1460  return true;
1461 }
1462 
1464 {
1465  LOCK(cs);
1466 
1467  if(fLiteMode || !masternodeSync.IsWinnersListSynced() || mapMasternodes.empty()) return;
1468 
1469  static bool IsFirstRun = true;
1470  // Do full scan on first run or if we are not a masternode
1471  // (MNs should update this info on every block, so limited scan should be enough for them)
1472  int nMaxBlocksToScanBack = (IsFirstRun || !fMasterNode) ? mnpayments.GetStorageLimit() : LAST_PAID_SCAN_BLOCKS;
1473 
1474  // LogPrint("mnpayments", "CMasternodeMan::UpdateLastPaid -- nHeight=%d, nMaxBlocksToScanBack=%d, IsFirstRun=%s\n",
1475  // nCachedBlockHeight, nMaxBlocksToScanBack, IsFirstRun ? "true" : "false");
1476 
1477  for (auto& mnpair: mapMasternodes) {
1478  mnpair.second.UpdateLastPaid(pindex, nMaxBlocksToScanBack);
1479  }
1480 
1481  IsFirstRun = false;
1482 }
1483 
1484 void CMasternodeMan::UpdateWatchdogVoteTime(const COutPoint& outpoint, uint64_t nVoteTime)
1485 {
1486  LOCK(cs);
1487  CMasternode* pmn = Find(outpoint);
1488  if(!pmn) {
1489  return;
1490  }
1491  pmn->UpdateWatchdogVoteTime(nVoteTime);
1493 }
1494 
1496 {
1497  LOCK(cs);
1498  // Check if any masternodes have voted recently, otherwise return false
1500 }
1501 
1502 bool CMasternodeMan::AddGovernanceVote(const COutPoint& outpoint, uint256 nGovernanceObjectHash)
1503 {
1504  LOCK(cs);
1505  CMasternode* pmn = Find(outpoint);
1506  if(!pmn) {
1507  return false;
1508  }
1509  pmn->AddGovernanceVote(nGovernanceObjectHash);
1510  return true;
1511 }
1512 
1514 {
1515  LOCK(cs);
1516  for(auto& mnpair : mapMasternodes) {
1517  mnpair.second.RemoveGovernanceObject(nGovernanceObjectHash);
1518  }
1519 }
1520 
1521 void CMasternodeMan::CheckMasternode(const CPubKey& pubKeyMasternode, bool fForce)
1522 {
1523  LOCK(cs);
1524  for (auto& mnpair : mapMasternodes) {
1525  if (mnpair.second.pubKeyMasternode == pubKeyMasternode) {
1526  mnpair.second.Check(fForce);
1527  return;
1528  }
1529  }
1530 }
1531 
1532 bool CMasternodeMan::IsMasternodePingedWithin(const COutPoint& outpoint, int nSeconds, int64_t nTimeToCheckAt)
1533 {
1534  LOCK(cs);
1535  CMasternode* pmn = Find(outpoint);
1536  return pmn ? pmn->IsPingedWithin(nSeconds, nTimeToCheckAt) : false;
1537 }
1538 
1540 {
1541  LOCK(cs);
1542  CMasternode* pmn = Find(outpoint);
1543  if(!pmn) {
1544  return;
1545  }
1546  pmn->lastPing = mnp;
1547  // if masternode uses sentinel ping instead of watchdog
1548  // we shoud update nTimeLastWatchdogVote here if sentinel
1549  // ping flag is actual
1550  if(mnp.fSentinelIsCurrent) {
1552  }
1553  mapSeenMasternodePing.insert(std::make_pair(mnp.GetHash(), mnp));
1554 
1555  CMasternodeBroadcast mnb(*pmn);
1556  uint256 hash = mnb.GetHash();
1557  if(mapSeenMasternodeBroadcast.count(hash)) {
1558  mapSeenMasternodeBroadcast[hash].second.lastPing = mnp;
1559  }
1560 }
1561 
1563 {
1564  nCachedBlockHeight = pindex->nHeight;
1565  LogPrint("masternode", "CMasternodeMan::UpdatedBlockTip -- nCachedBlockHeight=%d\n", nCachedBlockHeight);
1566 
1567  CheckSameAddr();
1568 
1569  if(fMasterNode) {
1570  // normal wallet does not need to update this every block, doing update on rpc call should be enough
1571  UpdateLastPaid(pindex);
1572  }
1573 }
1574 
1576 {
1577  // Avoid double locking
1578  bool fMasternodesAddedLocal = false;
1579  bool fMasternodesRemovedLocal = false;
1580  {
1581  LOCK(cs);
1582  fMasternodesAddedLocal = fMasternodesAdded;
1583  fMasternodesRemovedLocal = fMasternodesRemoved;
1584  }
1585 
1586  if(fMasternodesAddedLocal) {
1589  }
1590  if(fMasternodesRemovedLocal) {
1592  }
1593 
1594  LOCK(cs);
1595  fMasternodesAdded = false;
1596  fMasternodesRemoved = false;
1597 }
CMasternode * Find(const COutPoint &outpoint)
Find an entry.
bool CheckOutpoint(int &nDos)
Definition: masternode.cpp:543
masternode_info_t FindRandomNotInVec(const std::vector< COutPoint > &vecToExclude, int nProtocolVersion=-1)
Find a random entry.
bool GetBlockHash(uint256 &hashRet, int nBlockHeight)
CNode * ConnectNode(CAddress addrConnect, const char *pszDest=NULL, bool fConnectToMasternode=false)
Definition: net.cpp:347
static const int MNB_RECOVERY_QUORUM_TOTAL
Definition: masternodeman.h:38
bool IsLocal() const
Definition: netaddress.cpp:166
const char * MNPING
Definition: protocol.cpp:53
int64_t nDsqCount
Definition: masternodeman.h:91
CMasternodeMan mnodeman
CMasternodeSync masternodeSync
std::set< uint256 > setAskFor
Definition: net.h:743
static const int LAST_PAID_SCAN_BLOCKS
Definition: masternodeman.h:31
static const int MIN_POSE_PROTO_VERSION
Definition: masternodeman.h:33
bool Update(CMasternode *pmn, int &nDos, CConnman &connman)
Definition: masternode.cpp:491
bool CheckMnbAndUpdateMasternodeList(CNode *pfrom, CMasternodeBroadcast mnb, int &nDos, CConnman &connman)
Perform complete check and only then update list and maps.
std::string NetworkIDString() const
Definition: chainparams.h:75
void UpdateWatchdogVoteTime(uint64_t nVoteTime=0)
Definition: masternode.cpp:848
uint256 GetHash() const
Definition: masternode.h:65
CActiveMasternode activeMasternode
int GetRandInt(int nMax)
Definition: random.cpp:109
bool IsMnbRecoveryRequested(const uint256 &hash)
void Relay(CConnman &connman)
Definition: masternode.cpp:665
bool operator()(const CMasternode *t1, const CMasternode *t2) const
void PoSeBan()
Definition: masternode.h:262
void AddFulfilledRequest(CAddress addr, std::string strRequest)
#define strprintf
Definition: tinyformat.h:1011
CMasternodePing lastPing
Definition: masternode.h:156
uint64_t GetHash(const uint256 &salt) const
Definition: uint256.cpp:126
void UpdatedBlockTip(const CBlockIndex *pindex)
void CheckMasternode(const CPubKey &pubKeyMasternode, bool fForce)
bool IsMasternodePingedWithin(const COutPoint &outpoint, int nSeconds, int64_t nTimeToCheckAt=-1)
bool Get(const COutPoint &outpoint, CMasternode &masternodeRet)
Versions of Find that are safe to use from outside the class.
void CheckAndRemove()
This is dummy overload to be used for dumping/loading mncache.dat.
std::map< uint256, std::vector< CMasternodeBroadcast > > mMnbRecoveryGoodReplies
Definition: masternodeman.h:64
CCriticalSection cs_main
Definition: validation.cpp:62
bool operator()(const std::pair< arith_uint256, CMasternode *> &t1, const std::pair< arith_uint256, CMasternode *> &t2) const
CAddress addr
Definition: net.h:688
Definition: net.h:108
NodeId id
Definition: net.h:718
bool GetMasternodeRanks(rank_pair_vec_t &vecMasternodeRanksRet, int nBlockHeight=-1, int nMinProtocol=0)
std::map< uint256, CMasternodePing > mapSeenMasternodePing
Definition: masternodeman.h:87
const char * SYNCSTATUSCOUNT
Definition: protocol.cpp:63
std::map< COutPoint, std::map< CNetAddr, int64_t > > mWeAskedForMasternodeListEntry
Definition: masternodeman.h:58
CPubKey pubKeyMasternode
Definition: masternode.h:117
bool IsEnabled()
Definition: masternode.h:222
std::map< uint256, std::pair< int64_t, CMasternodeBroadcast > > mapSeenMasternodeBroadcast
Definition: masternodeman.h:85
void AskForMN(CNode *pnode, const COutPoint &outpoint, CConnman &connman)
Ask (source) node for mnb.
std::string ToString(bool fUseGetnameinfo=true) const
Definition: netaddress.cpp:568
bool IsWinnersListSynced()
static const int MASTERNODE_NEW_START_REQUIRED_SECONDS
Definition: masternode.h:21
const char * MNVERIFY
Definition: protocol.cpp:67
bool Add(CMasternode &mn)
Add an entry.
std::vector< score_pair_t > score_pair_vec_t
Definition: masternodeman.h:22
void AddNewAddress(const CAddress &addr, const CAddress &addrFrom, int64_t nTimePenalty=0)
Definition: net.cpp:2390
bool HasFulfilledRequest(CAddress addr, std::string strRequest)
bool IsPreEnabled()
Definition: masternode.h:223
void SetMasternodeLastPing(const COutPoint &outpoint, const CMasternodePing &mnp)
void Check()
Check all Masternodes.
bool fMasternodesAdded
Set when masternodes are added, cleared when CGovernanceManager is notified.
Definition: masternodeman.h:68
const char * DSEG
Definition: protocol.cpp:62
static const int MASTERNODE_WATCHDOG_MAX_SECONDS
Definition: masternode.h:20
bool fMasterNode
Definition: util.cpp:108
std::vector< unsigned char > vchSig1
Definition: masternode.h:368
std::string GetStateString() const
Definition: masternode.cpp:309
std::map< CNetAddr, int64_t > mAskedUsForMasternodeList
Definition: masternodeman.h:54
void UpdateLastPaid(const CBlockIndex *pindex)
#define AssertLockHeld(cs)
Definition: sync.h:96
NodeId GetId() const
Definition: net.h:790
bool fLiteMode
Definition: util.cpp:109
#define LOCK2(cs1, cs2)
Definition: sync.h:169
void Misbehaving(NodeId pnode, int howmuch)
#define LogPrintf(...)
Definition: util.h:98
arith_uint256 CalculateScore(const uint256 &blockHash)
Definition: masternode.cpp:91
std::map< CNetAddr, CMasternodeVerification > mWeAskedForVerification
Definition: masternodeman.h:60
bool fAllowMixingTx
Definition: masternode.h:163
COutPoint prevout
Definition: transaction.h:61
Definition: net.h:661
CMasternodePayments mnpayments
bool DisallowMixing(const COutPoint &outpoint)
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
#define LOCK(cs)
Definition: sync.h:168
CCriticalSection cs
Definition: masternodeman.h:46
void DoFullVerificationStep(CConnman &connman)
bool operator()(const std::pair< int, CMasternode *> &t1, const std::pair< int, CMasternode *> &t2) const
bool GetMasternodeInfo(const COutPoint &outpoint, masternode_info_t &mnInfoRet)
static const int DSEG_UPDATE_SECONDS
Definition: masternodeman.h:29
bool GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int &nCountRet, masternode_info_t &mnInfoRet)
Find an entry in the masternode list that is next to be paid.
static const int MASTERNODE_SYNC_LIST
bool IsScheduled(CMasternode &mn, int nNotBlockHeight)
int CountMasternodes(int nProtocolVersion=-1)
std::list< std::pair< CService, uint256 > > listScheduledMnbRequestConnections
Definition: masternodeman.h:65
void PushInventory(const CInv &inv)
Definition: net.h:866
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
std::map< uint256, CMasternodeVerification > mapSeenMasternodeVerification
Definition: masternodeman.h:89
static const int MNB_RECOVERY_MAX_ASK_ENTRIES
Definition: masternodeman.h:40
bool IsPoSeVerified()
Definition: masternode.h:226
void Check(bool fForce=false)
Definition: masternode.cpp:139
std::map< COutPoint, CMasternode > mapMasternodes
Definition: masternodeman.h:52
std::vector< rank_pair_t > rank_pair_vec_t
Definition: masternodeman.h:24
static bool VerifyMessage(const CPubKey pubkey, const std::vector< unsigned char > &vchSig, const std::string strMessage, std::string &strErrorRet)
Verify the message signature, returns true if succcessful.
void SendVerifyReply(CNode *pnode, CMasternodeVerification &mnv, CConnman &connman)
std::string ToString() const
Definition: uint256.cpp:65
CScript GetScriptForDestination(const CTxDestination &dest)
Definition: standard.cpp:262
void ProcessMasternodeConnections(CConnman &connman)
bool AddGovernanceVote(const COutPoint &outpoint, uint256 nGovernanceObjectHash)
bool fMasternode
Definition: net.h:712
int size()
Return the number of (unique) Masternodes.
bool GetMasternodeByRank(int nRank, masternode_info_t &mnInfoRet, int nBlockHeight=-1, int nMinProtocol=0)
static const int MNB_RECOVERY_QUORUM_REQUIRED
Definition: masternodeman.h:39
static const int MNB_RECOVERY_RETRY_SECONDS
Definition: masternodeman.h:42
std::string ToString() const
static const int MASTERNODE_MIN_MNP_SECONDS
Definition: masternode.h:18
void UpdateCachesAndClean()
Definition: governance.cpp:425
void ProcessVerifyReply(CNode *pnode, CMasternodeVerification &mnv)
void ManageState(CConnman &connman)
Manage state of active Masternode.
std::vector< unsigned char > vchSig2
Definition: masternode.h:369
void AddGovernanceVote(uint256 nGovernanceObjectHash)
Definition: masternode.cpp:830
int64_t sigTime
Definition: masternode.h:37
bool IsRFC1918() const
Definition: netaddress.cpp:88
void CheckMasternodeOrphanObjects(CConnman &connman)
Definition: governance.cpp:996
bool GetMasternodeScores(const uint256 &nBlockHash, score_pair_vec_t &vecMasternodeScoresRet, int nMinProtocol=0)
void CheckMasternodeOrphanVotes(CConnman &connman)
Definition: governance.cpp:985
void Clear()
Clear Masternode vector.
static const int MAX_POSE_BLOCKS
Definition: masternodeman.h:36
static const int MASTERNODE_POSE_BAN_MAX_SCORE
Definition: masternode.h:23
int CountEnabled(int nProtocolVersion=-1)
uint256 GetHash() const
Definition: masternode.h:338
static const int MNB_RECOVERY_WAIT_SECONDS
Definition: masternodeman.h:41
const CChainParams & Params()
bool fSentinelIsCurrent
Definition: masternode.h:39
int GetUTXOConfirmations(const COutPoint &outpoint)
Definition: validation.cpp:461
bool AllowMixing(const COutPoint &outpoint)
static const int PROTOCOL_VERSION
Definition: version.h:13
void UpdateWatchdogVoteTime(const COutPoint &outpoint, uint64_t nVoteTime=0)
static const std::string SERIALIZATION_VERSION_STRING
Definition: masternodeman.h:27
int64_t GetAdjustedTime()
Definition: timedata.cpp:33
bool IsBlockchainSynced()
void IncreasePoSeBanScore()
Definition: masternode.h:260
std::map< CNetAddr, int64_t > mWeAskedForMasternodeList
Definition: masternodeman.h:56
void ProcessVerifyBroadcast(CNode *pnode, const CMasternodeVerification &mnv)
CNetFulfilledRequestManager netfulfilledman
static bool IsValidStateForAutoStart(int nActiveStateIn)
Definition: masternode.h:233
uint256 GetHash() const
Definition: masternode.h:392
Definition: protocol.h:314
bool SimpleCheck(int &nDos)
Definition: masternode.cpp:430
void NotifyMasternodeUpdates(CConnman &connman)
int64_t nLastWatchdogVoteTime
Definition: masternodeman.h:75
static const int MAX_POSE_CONNECTIONS
Definition: masternodeman.h:34
bool PoSeBan(const COutPoint &outpoint)
masternode_info_t GetInfo()
Definition: masternode.cpp:286
void RemoveGovernanceObject(uint256 nGovernanceObjectHash)
bool Has(const COutPoint &outpoint)
static const std::string MAIN
Definition: pubkey.h:37
bool GetMasternodeRank(const COutPoint &outpoint, int &nRankRet, int nBlockHeight=-1, int nMinProtocol=0)
static bool SignMessage(const std::string strMessage, std::vector< unsigned char > &vchSigRet, const CKey key)
Sign the message, returns true if successful.
int nPoSeBanScore
Definition: masternode.h:161
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:20
std::pair< CService, std::set< uint256 > > PopScheduledMnbRequestConnection()
CGovernanceManager governance
Definition: governance.cpp:17
void BumpAssetLastTime(std::string strFuncName)
void UpdateMasternodeList(CMasternodeBroadcast mnb, CConnman &connman)
Update masternode list and maps using provided CMasternodeBroadcast.
static constexpr const CAllNodes AllNodes
Definition: net.h:160
std::map< uint256, std::pair< int64_t, std::set< CNetAddr > > > mMnbRecoveryRequests
Definition: masternodeman.h:63
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:113
bool SendVerifyRequest(const CAddress &addr, const std::vector< CMasternode *> &vSortedByAddr, CConnman &connman)
void DsegUpdate(CNode *pnode, CConnman &connman)
Count Masternodes by network type - NET_IPV4, NET_IPV6, NET_TOR.
std::string ToStringShort() const
Definition: transaction.cpp:17
void ForEachNode(const Condition &cond, Callable &&func)
Definition: net.h:239
#define PAIRTYPE(t1, t2)
const char * MNANNOUNCE
Definition: protocol.cpp:52
void DecreasePoSeBanScore()
Definition: masternode.h:261
static const int MAX_POSE_RANK
Definition: masternodeman.h:35
bool IsMasternodeListSynced()
void PushMessage(CNode *pnode, const std::string &sCommand, Args &&... args)
Definition: net.h:199
bool fMasternodesRemoved
Set when masternodes are removed, cleared when CGovernanceManager is notified.
Definition: masternodeman.h:71
bool IsPingedWithin(int nSeconds, int64_t nTimeToCheckAt=-1)
Definition: masternode.h:212
static const std::string REGTEST