PRCYCoin  2.0.0.7rc1
P2P Digital Currency
masternode-payments.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 "masternode-payments.h"
8 #include "addrman.h"
9 #include "fs.h"
10 #include "masternode-budget.h"
11 #include "masternode-sync.h"
12 #include "masternodeman.h"
13 #include "messagesigner.h"
14 #include "sync.h"
15 #include "util.h"
16 #include "utilmoneystr.h"
17 
20 
24 
25 //
26 // CMasternodePaymentDB
27 //
28 
30 {
31  pathDB = GetDataDir() / "mnpayments.dat";
32  strMagicMessage = "MasternodePayments";
33 }
34 
36 {
37  int64_t nStart = GetTimeMillis();
38 
39  // serialize, checksum data up to that point, then append checksum
40  CDataStream ssObj(SER_DISK, CLIENT_VERSION);
41  ssObj << strMagicMessage; // masternode cache file specific magic message
42  ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
43  ssObj << objToSave;
44  uint256 hash = Hash(ssObj.begin(), ssObj.end());
45  ssObj << hash;
46 
47  // open output file, and associate with CAutoFile
48  FILE* file = fsbridge::fopen(pathDB, "wb");
49  CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
50  if (fileout.IsNull())
51  return error("%s : Failed to open file %s", __func__, pathDB.string());
52 
53  // Write and commit header, data
54  try {
55  fileout << ssObj;
56  } catch (const std::exception& e) {
57  return error("%s : Serialize or I/O error - %s", __func__, e.what());
58  }
59  fileout.fclose();
60 
61  LogPrint(BCLog::MASTERNODE, "Written info to mnpayments.dat %dms\n", GetTimeMillis() - nStart);
62 
63  return true;
64 }
65 
67 {
68  int64_t nStart = GetTimeMillis();
69  // open input file, and associate with CAutoFile
70  FILE* file = fsbridge::fopen(pathDB, "rb");
71  CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
72  if (filein.IsNull()) {
73  error("%s : Failed to open file %s", __func__, pathDB.string());
74  return FileError;
75  }
76 
77  // use file size to size memory buffer
78  int fileSize = fs::file_size(pathDB);
79  int dataSize = fileSize - sizeof(uint256);
80  // Don't try to resize to a negative number if file is small
81  if (dataSize < 0)
82  dataSize = 0;
83  std::vector<unsigned char> vchData;
84  vchData.resize(dataSize);
85  uint256 hashIn;
86 
87  // read data and checksum from file
88  try {
89  filein.read((char*)&vchData[0], dataSize);
90  filein >> hashIn;
91  } catch (const std::exception& e) {
92  error("%s : Deserialize or I/O error - %s", __func__, e.what());
93  return HashReadError;
94  }
95  filein.fclose();
96 
97  CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);
98 
99  // verify stored checksum matches input data
100  uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
101  if (hashIn != hashTmp) {
102  error("%s : Checksum mismatch, data corrupted", __func__);
103  return IncorrectHash;
104  }
105 
106  unsigned char pchMsgTmp[4];
107  std::string strMagicMessageTmp;
108  try {
109  // de-serialize file header (masternode cache file specific magic message) and ..
110  ssObj >> strMagicMessageTmp;
111 
112  // ... verify the message matches predefined one
113  if (strMagicMessage != strMagicMessageTmp) {
114  error("%s : Invalid masternode payement cache magic message", __func__);
115  return IncorrectMagicMessage;
116  }
117 
118 
119  // de-serialize file header (network specific magic number) and ..
120  ssObj >> FLATDATA(pchMsgTmp);
121 
122  // ... verify the network matches ours
123  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) {
124  error("%s : Invalid network magic number", __func__);
125  return IncorrectMagicNumber;
126  }
127 
128  // de-serialize data into CMasternodePayments object
129  ssObj >> objToLoad;
130  } catch (const std::exception& e) {
131  objToLoad.Clear();
132  error("%s : Deserialize or I/O error - %s", __func__, e.what());
133  return IncorrectFormat;
134  }
135 
136  LogPrint(BCLog::MASTERNODE, "Loaded info from mnpayments.dat %dms\n", GetTimeMillis() - nStart);
137  LogPrint(BCLog::MASTERNODE, " %s\n", objToLoad.ToString());
138  if (!fDryRun) {
139  LogPrint(BCLog::MASTERNODE, "Masternode payments manager - cleaning....\n");
140  objToLoad.CleanPaymentList();
141  LogPrint(BCLog::MASTERNODE, "Masternode payments manager - result:\n");
142  LogPrint(BCLog::MASTERNODE, " %s\n", objToLoad.ToString());
143  }
144 
145  return Ok;
146 }
147 
149 {
150  int64_t nStart = GetTimeMillis();
151 
152  CMasternodePaymentDB paymentdb;
153  CMasternodePayments tempPayments;
154 
155  LogPrint(BCLog::MASTERNODE, "Verifying mnpayments.dat format...\n");
156  CMasternodePaymentDB::ReadResult readResult = paymentdb.Read(tempPayments, true);
157  // there was an error and it was not an error on file opening => do not proceed
158  if (readResult == CMasternodePaymentDB::FileError)
159  LogPrint(BCLog::MASTERNODE, "Missing budgets file - mnpayments.dat, will try to recreate\n");
160  else if (readResult != CMasternodePaymentDB::Ok) {
161  LogPrint(BCLog::MASTERNODE, "Error reading mnpayments.dat: ");
162  if (readResult == CMasternodePaymentDB::IncorrectFormat)
163  LogPrint(BCLog::MASTERNODE, "magic is ok but data has invalid format, will try to recreate\n");
164  else {
165  LogPrint(BCLog::MASTERNODE, "file format is unknown or invalid, please fix it manually\n");
166  return;
167  }
168  }
169  LogPrint(BCLog::MASTERNODE, "Writting info to mnpayments.dat...\n");
170  paymentdb.Write(masternodePayments);
171 
172  LogPrint(BCLog::MASTERNODE, "Budget dump finished %dms\n", GetTimeMillis() - nStart);
173 }
174 
175 bool IsBlockValueValid(int nHeight, CAmount nExpectedValue, CAmount nMinted)
176 {
177  if (!masternodeSync.IsSynced()) {
178  //there is no budget data to use to check anything
179  //super blocks will always be on these blocks, max 100 per budgeting
180  if (nHeight % GetBudgetPaymentCycleBlocks() < 100) {
181  return true;
182  }
183  } else {
184  // we're synced and have data so check the budget schedule
185  if (budget.IsBudgetPaymentBlock(nHeight)) {
186  //the value of the block is evaluated in CheckBlock
187  return true;
188  }
189  }
190 
191  return nMinted <= nExpectedValue;
192 }
193 
194 bool IsBlockPayeeValid(const CBlock& block, int nBlockHeight)
195 {
196  if (!masternodeSync.IsSynced()) { //there is no budget data to use to check anything -- find the longest chain
197  LogPrint(BCLog::MASTERNODE, "Client not synced, skipping block payee checks\n");
198  return true;
199  }
200 
201  const CTransaction& txNew = (nBlockHeight > Params().LAST_POW_BLOCK() ? block.vtx[1] : block.vtx[0]);
202 
203  //check for masternode payee
204  if (masternodePayments.IsTransactionValid(txNew, nBlockHeight))
205  return true;
206  LogPrint(BCLog::MASTERNODE, "Invalid mn payment detected %s\n", txNew.ToString().c_str());
207 
208  LogPrint(BCLog::MASTERNODE, "Masternode payment enforcement is disabled, accepting block\n");
209 
210  return true;
211 }
212 
213 
214 bool FillBlockPayee(CMutableTransaction& txNew, CAmount nFees, bool fProofOfStake)
215 {
216  CBlockIndex* pindexPrev = chainActive.Tip();
217  if (!pindexPrev) return false;
218 
219  return masternodePayments.FillBlockPayee(txNew, nFees, fProofOfStake);
220 }
221 
222 std::string GetRequiredPaymentsString(int nBlockHeight)
223 {
224  return masternodePayments.GetRequiredPaymentsString(nBlockHeight);
225 }
226 
227 bool CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int64_t nFees, bool fProofOfStake)
228 {
229  CBlockIndex* pindexPrev = chainActive.Tip();
230  if (!pindexPrev) return false;
231 
232  bool hasPayment = true;
233  std::vector<unsigned char> payeeAddr;
234  CScript payee;
235  CKey mnPaymentPrivTx;
236  mnPaymentPrivTx.MakeNewKey(true);
237  CPubKey mnPaymentPubTx = mnPaymentPrivTx.GetPubKey();
238 
239  masternodePayments.GetBlockPayee(pindexPrev->nHeight + 1, payeeAddr);
240  //no masternode detected
241  CMasternode* winningNode = mnodeman.GetCurrentMasterNode(1);
242  if (winningNode) {
243  //generate payee based on masternodeStealthAddress
244  payeeAddr = winningNode->vin.masternodeStealthAddress;
245  std::string mnsa(payeeAddr.begin(), payeeAddr.end());
246 
247  //Parse stealth address
248  CPubKey pubViewKey, pubSpendKey, des;
249  bool hasPaymentID;
250  uint64_t paymentID;
251  if (!CWallet::DecodeStealthAddress(mnsa, pubViewKey, pubSpendKey, hasPaymentID, paymentID)) {
252  throw std::runtime_error("Stealth address mal-formatted");
253  }
254  if (CWallet::ComputeStealthDestination(mnPaymentPrivTx, pubViewKey, pubSpendKey, des))
255  payee = GetScriptForDestination(des);
256  } else {
257  hasPayment = false;
258  }
259 
260  CAmount posBlockReward = GetBlockValue(pindexPrev->nHeight);
261  CAmount masternodePayment = GetMasternodePayment(pindexPrev->nHeight, posBlockReward);
262  if (hasPayment) {
263  if (fProofOfStake) {
269  unsigned int i = txNew.vout.size();
273  txNew.vout.resize(i + 1);
274  txNew.vout[i].scriptPubKey = payee;
275  txNew.vout[i].nValue = masternodePayment;
276  txNew.vout[i].masternodeStealthAddress = payeeAddr;
277  std::copy(mnPaymentPrivTx.begin(), mnPaymentPrivTx.end(), std::back_inserter(txNew.vout[i].txPriv));
278  std::copy(mnPaymentPubTx.begin(), mnPaymentPubTx.end(), std::back_inserter(txNew.vout[i].txPub));
279  //subtract mn payment from the stake reward
280  txNew.vout[i - 1].nValue -= masternodePayment;
281  } else {
282  txNew.vout.resize(2);
283  txNew.vout[1].scriptPubKey = payee;
284  txNew.vout[1].nValue = masternodePayment;
285  txNew.vout[0].nValue = posBlockReward - masternodePayment;
286  }
287 
288  LogPrintf("Masternode payment of %s to %s\n", FormatMoney(masternodePayment).c_str(), payee.ToString().c_str());
289  }
290  return true;
291 }
292 
294 {
295  return ActiveProtocol();
296 }
297 
298 void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
299 {
300  if (!masternodeSync.IsBlockchainSynced()) return;
301 
302  if (fLiteMode) return; //disable all Masternode related functionality
303 
304 
305  if (strCommand == NetMsgType::GETMNWINNERS) { //Masternode Payments Request Sync
306  if (fLiteMode) return; //disable all Masternode related functionality
307 
308  int nCountNeeded;
309  vRecv >> nCountNeeded;
310 
311  if (Params().NetworkID() == CBaseChainParams::MAIN) {
313  LogPrintf("CMasternodePayments::ProcessMessageMasternodePayments() : mnget - peer already asked me for the list\n");
314  LOCK(cs_main);
315  Misbehaving(pfrom->GetId(), 20);
316  return;
317  }
318  }
319 
321  masternodePayments.Sync(pfrom, nCountNeeded);
322  LogPrint(BCLog::MASTERNODE, "mnget - Sent Masternode winners to peer %i\n", pfrom->GetId());
323  } else if (strCommand == NetMsgType::MNWINNER) { //Masternode Payments Declare Winner
324  //this is required in litemodef
326  vRecv >> winner;
327 
328  if (pfrom->nVersion < ActiveProtocol()) return;
329 
330  int nHeight;
331  {
332  TRY_LOCK(cs_main, locked);
333  if (!locked || chainActive.Tip() == NULL) return;
334  nHeight = chainActive.Tip()->nHeight;
335  }
336 
337  if (masternodePayments.mapMasternodePayeeVotes.count(winner.GetHash())) {
338  LogPrint(BCLog::MASTERNODE, "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString().c_str(), nHeight);
339  masternodeSync.AddedMasternodeWinner(winner.GetHash());
340  return;
341  }
342 
343  int nFirstBlock = nHeight - (mnodeman.CountEnabled() * 1.25);
344  if (winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > nHeight + 20) {
345  LogPrint(BCLog::MASTERNODE, "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, nHeight);
346  return;
347  }
348 
349  std::string strError = "";
350  if (!winner.IsValid(pfrom, strError)) {
351  return;
352  }
353 
354  if (!masternodePayments.CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)) {
355  return;
356  }
357 
358  if (!winner.SignatureValid()) {
359  if (masternodeSync.IsSynced()) {
360  LogPrintf("CMasternodePayments::ProcessMessageMasternodePayments() : mnw - invalid signature\n");
361  LOCK(cs_main);
362  Misbehaving(pfrom->GetId(), 20);
363  }
364  // it could just be a non-synced masternode
365  mnodeman.AskForMN(pfrom, winner.vinMasternode);
366  return;
367  }
368 
370  winner.Relay();
371  masternodeSync.AddedMasternodeWinner(winner.GetHash());
372  }
373  }
374 }
375 
376 bool CMasternodePaymentWinner::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
377 {
378  std::string strError = "";
379  std::string strMasterNodeSignMessage;
380 
381  std::string payeeString(payee.begin(), payee.end());
383  std::string strMessage = HEX_STR(ser);
384 
385  if (!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
386  LogPrint(BCLog::MASTERNODE,"%s - SignMessage Error.%s\n", __func__);
387  return false;
388  }
389 
390  if (!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
391  LogPrint(BCLog::MASTERNODE,"%s - VerifyMessage Error: %s\n", __func__, strError);
392  return false;
393  }
394 
395  return true;
396 }
397 
398 bool CMasternodePayments::GetBlockPayee(int nBlockHeight, std::vector<unsigned char>& payee)
399 {
400  if (mapMasternodeBlocks.count(nBlockHeight)) {
401  return mapMasternodeBlocks[nBlockHeight].GetPayee(payee);
402  }
403 
404  return false;
405 }
406 
407 // Is this masternode scheduled to get paid soon?
408 // -- Only look ahead up to 8 blocks to allow for propagation of the latest 2 winners
409 bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
410 {
412 
413  int nHeight;
414  {
415  TRY_LOCK(cs_main, locked);
416  if (!locked || chainActive.Tip() == NULL) return false;
417  nHeight = chainActive.Tip()->nHeight;
418  }
419 
420  std::vector<unsigned char> mnpayee;
421  mnpayee = mn.vin.masternodeStealthAddress;
422 
423  std::vector<unsigned char> payee;
424  for (int64_t h = nHeight; h <= nHeight + 8; h++) {
425  if (h == nNotBlockHeight) continue;
426  if (mapMasternodeBlocks.count(h)) {
427  if (mapMasternodeBlocks[h].GetPayee(payee)) {
428  if (mnpayee == payee) {
429  return true;
430  }
431  }
432  }
433  }
434 
435  return false;
436 }
437 
439 {
440  uint256 blockHash;
441  if (!GetBlockHash(blockHash, winnerIn.nBlockHeight - 100)) {
442  return false;
443  }
444 
445  {
447 
448  if (mapMasternodePayeeVotes.count(winnerIn.GetHash())) {
449  return false;
450  }
451 
452  mapMasternodePayeeVotes[winnerIn.GetHash()] = winnerIn;
453 
454  if (!mapMasternodeBlocks.count(winnerIn.nBlockHeight)) {
455  CMasternodeBlockPayees blockPayees(winnerIn.nBlockHeight);
456  mapMasternodeBlocks[winnerIn.nBlockHeight] = blockPayees;
457  }
458  }
459 
461 
462  return true;
463 }
464 
466 {
468 
469  int nMaxSignatures = 0;
470  int nMasternode_Drift_Count = 0;
471 
472  std::string strPayeesPossible = "";
473  nMasternode_Drift_Count = mnodeman.size() + Params().MasternodeCountDrift();
474  CBlockIndex* pindexPrev = chainActive.Tip();
475  CAmount requiredMasternodePayment = GetMasternodePayment(nBlockHeight, GetBlockValue(pindexPrev->nHeight));
476 
477  //require at least 6 signatures
478  for (CMasternodePayee& payee : vecPayments)
479  if (payee.nVotes >= nMaxSignatures && payee.nVotes >= MNPAYMENTS_SIGNATURES_REQUIRED)
480  nMaxSignatures = payee.nVotes;
481 
482  // if we don't have at least 6 signatures on a payee, approve whichever is the longest chain
483  if (nMaxSignatures < MNPAYMENTS_SIGNATURES_REQUIRED) return true;
484 
485  for (CMasternodePayee& payee : vecPayments) {
486  bool found = false;
487  for (CTxOut out : txNew.vout) {
488  if (payee.masternodeStealthAddress == out.masternodeStealthAddress) {
489  if (out.nValue >= requiredMasternodePayment)
490  found = true;
491  else
492  LogPrint(BCLog::MASTERNODE, "Masternode payment is out of drift range. Paid=%s Min=%s\n", FormatMoney(out.nValue).c_str(), FormatMoney(requiredMasternodePayment).c_str());
493  }
494  }
495 
496  if (payee.nVotes >= MNPAYMENTS_SIGNATURES_REQUIRED) {
497  if (found) return true;
498 
499  std::string address2(payee.masternodeStealthAddress.begin(), payee.masternodeStealthAddress.end());
500 
501  if (strPayeesPossible == "") {
502  strPayeesPossible += address2;
503  } else {
504  strPayeesPossible += "," + address2;
505  }
506  }
507  }
508  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::IsTransactionValid - Missing required payment of %s to %s\n", FormatMoney(requiredMasternodePayment).c_str(), strPayeesPossible.c_str());
509  return false;
510 }
511 
513 {
515 
516  std::string ret = "Unknown";
517 
518  for (CMasternodePayee& payee : vecPayments) {
519  //CTxDestination address1;
520  std::string paymentAddress(payee.masternodeStealthAddress.begin(), payee.masternodeStealthAddress.end());
521 
522  if (ret != "Unknown") {
523  ret += ", " + paymentAddress + ":" + std::to_string(payee.nVotes);
524  } else {
525  ret = paymentAddress + ":" + std::to_string(payee.nVotes);
526  }
527  }
528 
529  return ret;
530 }
531 
533 {
535 
536  if (mapMasternodeBlocks.count(nBlockHeight)) {
537  return mapMasternodeBlocks[nBlockHeight].GetRequiredPaymentsString();
538  }
539 
540  return "Unknown";
541 }
542 
543 bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight)
544 {
546 
547  if (mapMasternodeBlocks.count(nBlockHeight)) {
548  return mapMasternodeBlocks[nBlockHeight].IsTransactionValid(txNew);
549  }
550 
551  return true;
552 }
553 
555 {
557 
558  int nHeight;
559  {
560  TRY_LOCK(cs_main, locked);
561  if (!locked || chainActive.Tip() == NULL) return;
562  nHeight = chainActive.Tip()->nHeight;
563  }
564 
565  //keep up to five cycles for historical sake
566  int nLimit = std::max(int(mnodeman.size() * 1.25), 1000);
567 
568  std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
569  while (it != mapMasternodePayeeVotes.end()) {
570  CMasternodePaymentWinner winner = (*it).second;
571 
572  if (nHeight - winner.nBlockHeight > nLimit) {
573  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::CleanPaymentList - Removing old Masternode payment - block %d\n", winner.nBlockHeight);
574  masternodeSync.mapSeenSyncMNW.erase((*it).first);
575  mapMasternodePayeeVotes.erase(it++);
576  mapMasternodeBlocks.erase(winner.nBlockHeight);
577  } else {
578  ++it;
579  }
580  }
581 }
582 
583 bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError)
584 {
586 
587  if (!pmn) {
588  strError = strprintf("Unknown Masternode %s", vinMasternode.prevout.hash.ToString());
589  LogPrint(BCLog::MASTERNODE, "CMasternodePaymentWinner::IsValid - %s\n", strError);
591  return false;
592  }
593 
594  if (pmn->protocolVersion < ActiveProtocol()) {
595  strError = strprintf("Masternode protocol too old %d - req %d", pmn->protocolVersion, ActiveProtocol());
596  LogPrint(BCLog::MASTERNODE, "CMasternodePaymentWinner::IsValid - %s\n", strError);
597  return false;
598  }
599 
601 
602  if (n > MNPAYMENTS_SIGNATURES_TOTAL) {
603  //It's common to have masternodes mistakenly think they are in the top 10
604  // We don't want to print all of these messages, or punish them unless they're way off
605  if (n > MNPAYMENTS_SIGNATURES_TOTAL * 2) {
606  strError = strprintf("Masternode not in the top %d (%d)", MNPAYMENTS_SIGNATURES_TOTAL * 2, n);
607  LogPrint(BCLog::MASTERNODE, "CMasternodePaymentWinner::IsValid - %s\n", strError);
608  }
609  return false;
610  }
611 
612  return true;
613 }
614 
615 bool CMasternodePayments::ProcessBlock(int nBlockHeight)
616 {
617  if (!fMasterNode) return false;
618 
619  //reference node - hybrid mode
620 
621  int n = mnodeman.GetMasternodeRank(activeMasternode.vin, nBlockHeight - 100, ActiveProtocol());
622 
623  if (n == -1) {
624  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::ProcessBlock - Unknown Masternode\n");
625  return false;
626  }
627 
628  if (n > MNPAYMENTS_SIGNATURES_TOTAL) {
629  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::ProcessBlock - Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, n);
630  return false;
631  }
632 
633  if (nBlockHeight <= nLastBlockHeight) return false;
634 
636 
637  if (budget.IsBudgetPaymentBlock(nBlockHeight)) {
638  //is budget payment block -- handled by the budgeting software
639  } else {
640  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::ProcessBlock() Start nHeight %d - vin %s. \n", nBlockHeight, activeMasternode.vin.prevout.hash.ToString());
641 
642  // pay to the oldest MN that still had no payment but its input is old enough and it was active long enough
643  int nCount = 0;
644  CMasternode* pmn = mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount);
645 
646  if (pmn != NULL) {
647  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::ProcessBlock() Found by FindOldestNotInVec \n");
648  newWinner.nBlockHeight = nBlockHeight;
649 
651  newWinner.AddPayee(pmn->vin.masternodeStealthAddress);
652 
653  CTxDestination address1;
654  ExtractDestination(payee, address1);
655  CBitcoinAddress address2(address1);
656  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::ProcessBlock() Winner payee %s nHeight %d. \n", address2.ToString().c_str(), newWinner.nBlockHeight);
657  } else {
658  LogPrint(BCLog::MASTERNODE, "CMasternodePayments::ProcessBlock() Failed to find masternode to pay\n");
659  }
660  }
661 
662  std::string errorMessage;
663  CPubKey pubKeyMasternode;
664  CKey keyMasternode;
665 
666  if (!CMessageSigner::GetKeysFromSecret(strMasterNodePrivKey, keyMasternode, pubKeyMasternode)) {
667  LogPrint(BCLog::MASTERNODE,"CMasternodePayments::ProcessBlock() - Error upon calling SetKey.\n");
668  return false;
669  }
670 
671  if (newWinner.Sign(keyMasternode, pubKeyMasternode)) {
672  if (AddWinningMasternode(newWinner)) {
673  newWinner.Relay();
674  nLastBlockHeight = nBlockHeight;
675  return true;
676  }
677  }
678 
679  return false;
680 }
681 
683 {
685  RelayInv(inv);
686 }
687 
689 {
691 
692  if (pmn != NULL) {
694  std::string strMessage = HEX_STR(ser);
695 
696  std::string strError = "";
697  if (!CMessageSigner::VerifyMessage(pmn->pubKeyMasternode, vchSig, strMessage, strError)) {
698  return error("CMasternodePaymentWinner::SignatureValid() - Got bad Masternode address signature for %s: %s\n", vinMasternode.prevout.hash.ToString(), strError);
699  }
700 
701  return true;
702  }
703 
704  return false;
705 }
706 
707 void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
708 {
710 
711  int nHeight;
712  {
713  TRY_LOCK(cs_main, locked);
714  if (!locked || chainActive.Tip() == NULL) return;
715  nHeight = chainActive.Tip()->nHeight;
716  }
717 
718  int nCount = (mnodeman.CountEnabled() * 1.25);
719  if (nCountNeeded > nCount) nCountNeeded = nCount;
720 
721  int nInvCount = 0;
722  std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
723  while (it != mapMasternodePayeeVotes.end()) {
724  CMasternodePaymentWinner winner = (*it).second;
725  if (winner.nBlockHeight >= nHeight - nCountNeeded && winner.nBlockHeight <= nHeight + 20) {
727  nInvCount++;
728  }
729  ++it;
730  }
732 }
733 
734 std::string CMasternodePayments::ToString() const
735 {
736  std::ostringstream info;
737 
738  info << "Votes: " << (int)mapMasternodePayeeVotes.size() << ", Blocks: " << (int)mapMasternodeBlocks.size();
739 
740  return info.str();
741 }
742 
743 
745 {
747 
748  int nOldestBlock = std::numeric_limits<int>::max();
749 
750  std::map<int, CMasternodeBlockPayees>::iterator it = mapMasternodeBlocks.begin();
751  while (it != mapMasternodeBlocks.end()) {
752  if ((*it).first < nOldestBlock) {
753  nOldestBlock = (*it).first;
754  }
755  it++;
756  }
757 
758  return nOldestBlock;
759 }
760 
761 
763 {
765 
766  int nNewestBlock = 0;
767 
768  std::map<int, CMasternodeBlockPayees>::iterator it = mapMasternodeBlocks.begin();
769  while (it != mapMasternodeBlocks.end()) {
770  if ((*it).first > nNewestBlock) {
771  nNewestBlock = (*it).first;
772  }
773  it++;
774  }
775 
776  return nNewestBlock;
777 }
CNode::HasFulfilledRequest
bool HasFulfilledRequest(std::string strRequest)
Definition: net.h:685
LOCK2
#define LOCK2(cs1, cs2)
Definition: sync.h:183
CMasternodePaymentWinner::GetHash
uint256 GetHash()
Definition: masternode-payments.h:182
IsBlockValueValid
bool IsBlockValueValid(int nHeight, CAmount nExpectedValue, CAmount nMinted)
Definition: masternode-payments.cpp:175
CMasternodePaymentWinner::Relay
void Relay()
Definition: masternode-payments.cpp:682
CMasternodePayments::nLastBlockHeight
int nLastBlockHeight
Definition: masternode-payments.h:235
CMasternodeMan::AskForMN
void AskForMN(CNode *pnode, CTxIn &vin)
Ask (source) node for mnb.
Definition: masternodeman.cpp:223
CMasternodeMan::CountEnabled
int CountEnabled(int protocolVersion=-1)
Definition: masternodeman.cpp:379
CAutoFile::read
CAutoFile & read(char *pch, size_t nSize)
Definition: streams.h:367
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
CMasternodePayments::CanVote
bool CanVote(COutPoint outMasternode, int nBlockHeight)
Definition: masternode-payments.h:266
CNode::GetId
NodeId GetId() const
Definition: net.h:423
CMasternodePaymentDB::Write
bool Write(const CMasternodePayments &objToSave)
Definition: masternode-payments.cpp:35
CKey::MakeNewKey
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:40
FLATDATA
#define FLATDATA(obj)
Definition: serialize.h:365
fs.h
CMasternodePaymentDB::Read
ReadResult Read(CMasternodePayments &objToLoad, bool fDryRun=false)
Definition: masternode-payments.cpp:66
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:13
CMasternodePayments::Sync
void Sync(CNode *node, int nCountNeeded)
Definition: masternode-payments.cpp:707
CDataStream::begin
const_iterator begin() const
Definition: streams.h:116
CMasternodePayments::GetBlockPayee
bool GetBlockPayee(int nBlockHeight, std::vector< unsigned char > &payee)
Definition: masternode-payments.cpp:398
GetRequiredPaymentsString
std::string GetRequiredPaymentsString(int nBlockHeight)
Definition: masternode-payments.cpp:222
CMasternodePaymentWinner
Definition: masternode-payments.h:160
sync.h
chainActive
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:70
COutPoint::hash
uint256 hash
Definition: transaction.h:39
GetScriptForDestination
CScript GetScriptForDestination(const CTxDestination &dest)
Definition: standard.cpp:285
IsBlockPayeeValid
bool IsBlockPayeeValid(const CBlock &block, int nBlockHeight)
Definition: masternode-payments.cpp:194
CBitcoinAddress
base58-encoded PRCY addresses.
Definition: base58.h:109
DumpMasternodePayments
void DumpMasternodePayments()
Definition: masternode-payments.cpp:148
CMasternodeMan::Find
CMasternode * Find(const CScript &payee)
Find an entry.
Definition: masternodeman.cpp:440
CActiveMasternode::vin
CTxIn vin
Definition: activemasternode.h:44
CMasternodeSync::IsBlockchainSynced
bool IsBlockchainSynced()
Definition: masternode-sync.cpp:32
CMasternodePaymentDB::strMagicMessage
std::string strMagicMessage
Definition: masternode-payments.h:42
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:181
CMasternodePaymentWinner::IsValid
bool IsValid(CNode *pnode, std::string &strError)
Definition: masternode-payments.cpp:583
CNode
Information about a peer.
Definition: net.h:306
masternode-sync.h
CMasternodePayments::ProcessBlock
bool ProcessBlock(int nBlockHeight)
Definition: masternode-payments.cpp:615
CMasternodePayments::mapMasternodePayeeVotes
std::map< uint256, CMasternodePaymentWinner > mapMasternodePayeeVotes
Definition: masternode-payments.h:238
CNode::PushInventory
void PushInventory(const CInv &inv)
Definition: net.h:494
CMasternodePayee
Definition: masternode-payments.h:60
CMasternodeMan::size
int size()
Return the number of (unique) Masternodes.
Definition: masternodeman.h:148
CMasternodePaymentWinner::AddPayee
void AddPayee(std::vector< unsigned char > payeeIn)
Definition: masternode-payments.h:197
AnnotatedMixin< std::recursive_mutex >
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
CMasternodeBlockPayees::vecPayments
std::vector< CMasternodePayee > vecPayments
Definition: masternode-payments.h:92
CMasternodePaymentDB
Save Masternode Payment Data (mnpayments.dat)
Definition: masternode-payments.h:38
TRY_LOCK
#define TRY_LOCK(cs, name)
Definition: sync.h:186
CMasternodePaymentWinner::Sign
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
Definition: masternode-payments.cpp:376
CInv
inv message data
Definition: protocol.h:358
CMasternodePaymentDB::IncorrectFormat
@ IncorrectFormat
Definition: masternode-payments.h:52
FormatMoney
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
Definition: utilmoneystr.cpp:13
masternodeman.h
CMasternodePaymentDB::CMasternodePaymentDB
CMasternodePaymentDB()
Definition: masternode-payments.cpp:29
CMessageSigner::VerifyMessage
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.
Definition: messagesigner.cpp:34
CBase58Data::ToString
std::string ToString() const
Definition: base58.cpp:200
CMasternode::vin
CTxIn vin
Definition: masternode.h:127
fMasterNode
bool fMasterNode
Definition: util.cpp:97
NetMsgType::MNWINNER
const char * MNWINNER
The mnwinner message is used to relay and distribute consensus for masternode payout ordering.
Definition: protocol.cpp:52
CNode::PushMessage
void PushMessage(const char *pszCommand)
Definition: net.h:518
CTxIn::masternodeStealthAddress
std::vector< unsigned char > masternodeStealthAddress
Definition: transaction.h:99
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:269
CKey::end
const unsigned char * end() const
Definition: key.h:101
CMasternodePayments::GetOldestBlock
int GetOldestBlock()
Definition: masternode-payments.cpp:744
CMessageSigner::SignMessage
static bool SignMessage(const std::string &strMessage, std::vector< unsigned char > &vchSigRet, const CKey &key)
Sign the message, returns true if successful.
Definition: messagesigner.cpp:25
CNode::nVersion
int nVersion
Definition: net.h:335
masternodeSync
CMasternodeSync masternodeSync
Definition: masternode-sync.cpp:19
CTxOut::nValue
CAmount nValue
Definition: transaction.h:167
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:303
strMasterNodePrivKey
std::string strMasterNodePrivKey
Definition: util.cpp:98
CPubKey::begin
const unsigned char * begin() const
Definition: pubkey.h:95
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
CKey::begin
const unsigned char * begin() const
Definition: key.h:100
CNode::FulfilledRequest
void FulfilledRequest(std::string strRequest)
Definition: net.h:705
ActiveProtocol
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
Definition: main.cpp:6844
CWallet::ComputeStealthDestination
static bool ComputeStealthDestination(const CKey &secret, const CPubKey &pubViewKey, const CPubKey &pubSpendKey, CPubKey &des)
Definition: wallet.cpp:6618
CMasternodePayments::GetRequiredPaymentsString
std::string GetRequiredPaymentsString(int nBlockHeight)
Definition: masternode-payments.cpp:532
CBudgetManager::IsBudgetPaymentBlock
bool IsBudgetPaymentBlock(int nBlockHeight)
Definition: masternode-budget.cpp:593
mnodeman
CMasternodeMan mnodeman
Masternode manager.
Definition: masternodeman.cpp:22
CMasternodeBlockPayees::IsTransactionValid
bool IsTransactionValid(const CTransaction &txNew)
Definition: masternode-payments.cpp:465
CMasternodePaymentDB::ReadResult
ReadResult
Definition: masternode-payments.h:45
CTxOut
An output of a transaction.
Definition: transaction.h:164
CMasternodePayments::CleanPaymentList
void CleanPaymentList()
Definition: masternode-payments.cpp:554
CMasternodePaymentWinner::payee
std::vector< unsigned char > payee
Definition: masternode-payments.h:166
CTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:286
CMasternodePayments::FillBlockPayee
bool FillBlockPayee(CMutableTransaction &txNew, int64_t nFees, bool fProofOfStake)
Definition: masternode-payments.cpp:227
GetBlockHash
bool GetBlockHash(uint256 &hash, int nBlockHeight)
Definition: masternode.cpp:26
fLiteMode
bool fLiteMode
Definition: util.cpp:100
CPubKey::end
const unsigned char * end() const
Definition: pubkey.h:96
CMasternodePaymentDB::Ok
@ Ok
Definition: masternode-payments.h:46
CMasternodePaymentDB::HashReadError
@ HashReadError
Definition: masternode-payments.h:48
CMasternodeBlockPayees::GetRequiredPaymentsString
std::string GetRequiredPaymentsString()
Definition: masternode-payments.cpp:512
CChainParams::LAST_POW_BLOCK
int LAST_POW_BLOCK() const
Definition: chainparams.h:111
CMasternodePaymentDB::FileError
@ FileError
Definition: masternode-payments.h:47
CMasternodeBlockPayees::nBlockHeight
int nBlockHeight
Definition: masternode-payments.h:91
CDataStream::end
const_iterator end() const
Definition: streams.h:118
CMasternodePayments::Clear
void Clear()
Definition: masternode-payments.h:248
RelayInv
void RelayInv(CInv &inv)
Definition: net.cpp:2077
CBaseChainParams::MAIN
@ MAIN
Definition: chainparamsbase.h:19
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
CAmount
int64_t CAmount
Amount in PRCY (Can be negative)
Definition: amount.h:17
NetMsgType::GETMNWINNERS
const char * GETMNWINNERS
The getmnwinners message is used to request winning masternode data from connected peers.
Definition: protocol.cpp:53
masternodePayments
CMasternodePayments masternodePayments
Object for who's going to get paid on which blocks.
Definition: masternode-payments.cpp:19
CMasternodeSync::AddedMasternodeWinner
void AddedMasternodeWinner(uint256 hash)
Definition: masternode-sync.cpp:102
SER_DISK
@ SER_DISK
Definition: serialize.h:160
CAutoFile::IsNull
bool IsNull() const
Return true if the wrapped FILE* is NULL, false otherwise.
Definition: streams.h:355
CTxOut::masternodeStealthAddress
std::vector< unsigned char > masternodeStealthAddress
Definition: transaction.h:177
masternode-payments.h
GetMasternodePayment
int64_t GetMasternodePayment(int nHeight, int64_t blockValue, int nMasternodeCount)
Definition: main.cpp:2454
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
CMasternodeBlockPayees
Definition: masternode-payments.h:88
HEX_DATA_STREAM_PROTOCOL
#define HEX_DATA_STREAM_PROTOCOL(protocolVersion)
Definition: streams.h:26
CKey::GetPubKey
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:79
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
CMasternodePaymentWinner::vinMasternode
CTxIn vinMasternode
Definition: masternode-payments.h:163
ExtractDestination
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: standard.cpp:199
CMasternodeSync::IsSynced
bool IsSynced()
Definition: masternode-sync.cpp:27
CAutoFile::fclose
void fclose()
Definition: streams.h:328
MASTERNODE_SYNC_MNW
#define MASTERNODE_SYNC_MNW
Definition: masternode-sync.h:12
CMasternode::pubKeyMasternode
CPubKey pubKeyMasternode
Definition: masternode.h:130
MNPAYMENTS_SIGNATURES_REQUIRED
#define MNPAYMENTS_SIGNATURES_REQUIRED
Definition: masternode-payments.h:25
CMasternodePayments::mapMasternodeBlocks
std::map< int, CMasternodeBlockPayees > mapMasternodeBlocks
Definition: masternode-payments.h:239
CTxDestination
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:81
CMasternodePaymentWinner::nBlockHeight
int nBlockHeight
Definition: masternode-payments.h:165
CMessageSigner::GetKeysFromSecret
static bool GetKeysFromSecret(const std::string &strSecret, CKey &keyRet, CPubKey &pubkeyRet)
Set the private/public key values, returns true if successful.
Definition: messagesigner.cpp:13
CBlock::vtx
std::vector< CTransaction > vtx
Definition: block.h:146
GetTimeMillis
int64_t GetTimeMillis()
Definition: utiltime.cpp:31
messagesigner.h
CBlock
Definition: block.h:142
CMutableTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:388
CWallet::DecodeStealthAddress
static bool DecodeStealthAddress(const std::string &stealth, CPubKey &pubViewKey, CPubKey &pubSpendKey, bool &hasPaymentID, uint64_t &paymentID)
Definition: wallet.cpp:6522
strprintf
#define strprintf
Definition: tinyformat.h:1056
CMasternode
Definition: masternode.h:107
CPubKey
An encapsulated public key.
Definition: pubkey.h:37
CTransaction::ToString
std::string ToString() const
Definition: transaction.cpp:217
MNPAYMENTS_SIGNATURES_TOTAL
#define MNPAYMENTS_SIGNATURES_TOTAL
Definition: masternode-payments.h:26
CKey
An encapsulated private key.
Definition: key.h:39
GetBudgetPaymentCycleBlocks
int GetBudgetPaymentCycleBlocks()
Definition: masternode-budget.cpp:28
utilmoneystr.h
BCLog::MASTERNODE
@ MASTERNODE
Definition: logging.h:62
LOCK
#define LOCK(cs)
Definition: sync.h:182
CScript::ToString
std::string ToString() const
Definition: script.cpp:266
CMasternodePayments::GetNewestBlock
int GetNewestBlock()
Definition: masternode-payments.cpp:762
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:86
HEX_STR
#define HEX_STR(a)
Definition: streams.h:27
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:349
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
masternode-budget.h
CMasternodePayments::IsTransactionValid
bool IsTransactionValid(const CTransaction &txNew, int nBlockHeight)
Definition: masternode-payments.cpp:543
NetMsgType::SYNCSTATUSCOUNT
const char * SYNCSTATUSCOUNT
The syncstatuscount message is used to track the layer 2 syncing process.
Definition: protocol.cpp:59
GetBlockValue
CAmount GetBlockValue(int nHeight)
Definition: main.cpp:2158
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:34
addrman.h
cs_mapMasternodePayeeVotes
RecursiveMutex cs_mapMasternodePayeeVotes
Definition: masternode-payments.cpp:23
cs_vecPayments
RecursiveMutex cs_vecPayments
Definition: masternode-payments.cpp:21
COutPoint::GetHash
uint256 GetHash()
Definition: transaction.cpp:31
CChain::Tip
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or NULL if none.
Definition: chain.h:596
budget
CBudgetManager budget
Definition: masternode-budget.cpp:19
CMasternodePaymentDB::IncorrectMagicMessage
@ IncorrectMagicMessage
Definition: masternode-payments.h:50
Hash
std::string Hash(std::string input)
Compute the 256-bit hash of a std::string.
Definition: hash.h:122
CMutableTransaction
A mutable version of CTransaction.
Definition: transaction.h:384
CMasternodePaymentDB::pathDB
fs::path pathDB
Definition: masternode-payments.h:41
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:162
CMasternode::protocolVersion
int protocolVersion
Definition: masternode.h:140
CMasternodePaymentWinner::SignatureValid
bool SignatureValid()
Definition: masternode-payments.cpp:688
util.h
CMasternodePayments::IsScheduled
bool IsScheduled(CMasternode &mn, int nNotBlockHeight)
Definition: masternode-payments.cpp:409
cs_mapMasternodeBlocks
RecursiveMutex cs_mapMasternodeBlocks
Definition: masternode-payments.cpp:22
MSG_MASTERNODE_WINNER
@ MSG_MASTERNODE_WINNER
Definition: protocol.h:395
CMasternodePaymentDB::IncorrectMagicNumber
@ IncorrectMagicNumber
Definition: masternode-payments.h:51
CMasternodePaymentWinner::vchSig
std::vector< unsigned char > vchSig
Definition: masternode-payments.h:167
CMasternodePayments
Definition: masternode-payments.h:231
CMasternodePayments::AddWinningMasternode
bool AddWinningMasternode(CMasternodePaymentWinner &winner)
Definition: masternode-payments.cpp:438
CMasternode::pubKeyCollateralAddress
CPubKey pubKeyCollateralAddress
Definition: masternode.h:129
FillBlockPayee
bool FillBlockPayee(CMutableTransaction &txNew, CAmount nFees, bool fProofOfStake)
Definition: masternode-payments.cpp:214
CMasternodePaymentDB::IncorrectHash
@ IncorrectHash
Definition: masternode-payments.h:49
error
bool error(const char *fmt, const Args &... args)
Definition: util.h:61
CMasternodePayments::ToString
std::string ToString() const
Definition: masternode-payments.cpp:734
CChainParams::MasternodeCountDrift
int MasternodeCountDrift() const
The masternode count that we will allow the see-saw reward payments to be off by.
Definition: chainparams.h:89
CMasternodeSync::mapSeenSyncMNW
std::map< uint256, int > mapSeenSyncMNW
Definition: masternode-sync.h:33
base_uint::ToString
std::string ToString() const
Definition: arith_uint256.cpp:199
Misbehaving
void Misbehaving(NodeId pnode, int howmuch) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Increase a node's misbehavior score.
Definition: main.cpp:2645
CMasternodePayments::ProcessMessageMasternodePayments
void ProcessMessageMasternodePayments(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
Definition: masternode-payments.cpp:298