PRCYCoin  2.0.0.7rc1
P2P Digital Currency
masternode-budget.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 "init.h"
8 #include "main.h"
9 
10 #include "addrman.h"
11 #include "fs.h"
12 #include "masternode-budget.h"
13 #include "masternode-sync.h"
14 #include "masternode.h"
15 #include "masternodeman.h"
16 #include "messagesigner.h"
17 #include "util.h"
18 
21 
22 std::map<uint256, int64_t> askedForSourceProposalOrBudget;
23 std::vector<CBudgetProposalBroadcast> vecImmatureBudgetProposals;
24 std::vector<CFinalizedBudgetBroadcast> vecImmatureFinalizedBudgets;
25 
27 
29 {
30  // Amount of blocks in a months period of time (using 1 minutes per) = (60*24*30)
31  if (Params().NetworkID() == CBaseChainParams::MAIN) return 43200;
32  //for testing purposes
33 
34  return 144; //ten times per day
35 }
36 
37 bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf)
38 {
39  CTransaction txCollateral;
40  uint256 nBlockHash;
41  if (!GetTransaction(nTxCollateralHash, txCollateral, nBlockHash, true)) {
42  strError = strprintf("Can't find collateral tx %s", txCollateral.ToString());
43  LogPrint(BCLog::MNBUDGET,"CBudgetProposalBroadcast::IsBudgetCollateralValid - %s\n", strError);
44  return false;
45  }
46 
47  if (txCollateral.vout.size() < 1) return false;
48  if (txCollateral.nLockTime != 0) return false;
49 
50  CScript findScript;
51  findScript << OP_RETURN << ToByteVector(nExpectedHash);
52 
53  bool foundOpReturn = false;
54  for (const CTxOut &o : txCollateral.vout) {
56  strError = strprintf("Invalid Script %s", txCollateral.ToString());
57  LogPrint(BCLog::MNBUDGET,"CBudgetProposalBroadcast::IsBudgetCollateralValid - %s\n", strError);
58  return false;
59  }
60  if (o.scriptPubKey == findScript && o.nValue >= PROPOSAL_FEE_TX) foundOpReturn = true;
61  }
62  if (!foundOpReturn) {
63  strError = strprintf("Couldn't find opReturn %s in %s", nExpectedHash.ToString(), txCollateral.ToString());
64  LogPrint(BCLog::MNBUDGET,"CBudgetProposalBroadcast::IsBudgetCollateralValid - %s\n", strError);
65  return false;
66  }
67 
68  // RETRIEVE CONFIRMATIONS AND NTIME
69  /*
70  - nTime starts as zero and is passed-by-reference out of this function and stored in the external proposal
71  - nTime is never validated via the hashing mechanism and comes from a full-validated source (the blockchain)
72  */
73 
74  int conf = GetIXConfirmations(nTxCollateralHash);
75  if (!nBlockHash.IsNull()) {
76  BlockMap::iterator mi = mapBlockIndex.find(nBlockHash);
77  if (mi != mapBlockIndex.end() && (*mi).second) {
78  CBlockIndex* pindex = (*mi).second;
79  if (chainActive.Contains(pindex)) {
80  conf += chainActive.Height() - pindex->nHeight + 1;
81  nTime = pindex->nTime;
82  }
83  }
84  }
85 
86  nConf = conf;
87 
88  //if we're syncing we won't have swiftTX information, so accept 1 confirmation
89  if (conf >= Params().Budget_Fee_Confirmations()) {
90  return true;
91  } else {
92  strError = strprintf("Collateral requires at least %d confirmations - %d confirmations", Params().Budget_Fee_Confirmations(), conf);
93  LogPrint(BCLog::MNBUDGET,"CBudgetProposalBroadcast::IsBudgetCollateralValid - %s - %d confirmations\n", strError, conf);
94  return false;
95  }
96 }
97 
99 {
100  LOCK(cs);
101 
102 
103  std::string strError = "";
104  std::map<uint256, CBudgetVote>::iterator it1 = mapOrphanMasternodeBudgetVotes.begin();
105  while (it1 != mapOrphanMasternodeBudgetVotes.end()) {
106  if (budget.UpdateProposal(((*it1).second), NULL, strError)) {
107  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckOrphanVotes - Proposal/Budget is known, activating and removing orphan vote\n");
108  mapOrphanMasternodeBudgetVotes.erase(it1++);
109  } else {
110  ++it1;
111  }
112  }
113  std::map<uint256, CFinalizedBudgetVote>::iterator it2 = mapOrphanFinalizedBudgetVotes.begin();
114  while (it2 != mapOrphanFinalizedBudgetVotes.end()) {
115  if (budget.UpdateFinalizedBudget(((*it2).second), NULL, strError)) {
116  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckOrphanVotes - Proposal/Budget is known, activating and removing orphan vote\n");
117  mapOrphanFinalizedBudgetVotes.erase(it2++);
118  } else {
119  ++it2;
120  }
121  }
122  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckOrphanVotes - Done\n");
123 }
124 
126 {
127  static int nSubmittedHeight = 0; // height at which final budget was submitted last time
128  int nCurrentHeight;
129 
130  {
131  TRY_LOCK(cs_main, locked);
132  if (!locked) return;
133  if (!chainActive.Tip()) return;
134  nCurrentHeight = chainActive.Height();
135  }
136 
137  int nBlockStart = nCurrentHeight - nCurrentHeight % GetBudgetPaymentCycleBlocks() + GetBudgetPaymentCycleBlocks();
138  if (nSubmittedHeight >= nBlockStart){
139  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - nSubmittedHeight(=%ld) < nBlockStart(=%ld) condition not fulfilled.\n", nSubmittedHeight, nBlockStart);
140  return;
141  }
142  // Submit final budget during the last 2 days before payment for Mainnet, about 9 minutes for Testnet
143  int nFinalizationStart = nBlockStart - ((GetBudgetPaymentCycleBlocks() / 30) * 2);
144  int nOffsetToStart = nFinalizationStart - nCurrentHeight;
145 
146  if (nBlockStart - nCurrentHeight > ((GetBudgetPaymentCycleBlocks() / 30) * 2)){
147  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Too early for finalization. Current block is %ld, next Superblock is %ld.\n", nCurrentHeight, nBlockStart);
148  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - First possible block for finalization: %ld. Last possible block for finalization: %ld. You have to wait for %ld block(s) until Budget finalization will be possible\n", nFinalizationStart, nBlockStart, nOffsetToStart);
149 
150  return;
151  }
152 
153  std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget();
154  std::string strBudgetName = "main";
155  std::vector<CTxBudgetPayment> vecTxBudgetPayments;
156 
157  for (unsigned int i = 0; i < vBudgetProposals.size(); i++) {
158  CTxBudgetPayment txBudgetPayment;
159  txBudgetPayment.nProposalHash = vBudgetProposals[i]->GetHash();
160  txBudgetPayment.payee = vBudgetProposals[i]->GetPayee();
161  txBudgetPayment.nAmount = vBudgetProposals[i]->GetAllotted();
162  vecTxBudgetPayments.push_back(txBudgetPayment);
163  }
164 
165  if (vecTxBudgetPayments.size() < 1) {
166  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Found No Proposals For Period\n");
167  return;
168  }
169 
170  CFinalizedBudgetBroadcast tempBudget(strBudgetName, nBlockStart, vecTxBudgetPayments, UINT256_ZERO);
171  if (mapSeenFinalizedBudgets.count(tempBudget.GetHash())) {
172  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Budget already exists - %s\n", tempBudget.GetHash().ToString());
173  nSubmittedHeight = nCurrentHeight;
174  return; //already exists
175  }
176 
177  //create fee tx
178  CTransaction tx;
179  uint256 txidCollateral;
180 
181  if (!mapCollateralTxids.count(tempBudget.GetHash())) {
182  CWalletTx wtx;
183  if (!pwalletMain->GetBudgetSystemCollateralTX(wtx, tempBudget.GetHash(), false)) {
184  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Can't make collateral transaction\n");
185  return;
186  }
187 
188  // Get our change address
189  CReserveKey reservekey(pwalletMain);
190  // Send the tx to the network. Do NOT use SwiftTx, locking might need too much time to propagate, especially for testnet
191  pwalletMain->CommitTransaction(wtx, reservekey, "NO-ix");
192  tx = (CTransaction)wtx;
193  txidCollateral = tx.GetHash();
194  mapCollateralTxids.insert(std::make_pair(tempBudget.GetHash(), txidCollateral));
195  } else {
196  txidCollateral = mapCollateralTxids[tempBudget.GetHash()];
197  }
198 
199  int conf = GetIXConfirmations(txidCollateral);
200  CTransaction txCollateral;
201  uint256 nBlockHash;
202 
203  if (!GetTransaction(txidCollateral, txCollateral, nBlockHash, true)) {
204  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Can't find collateral tx %s", txidCollateral.ToString());
205  return;
206  }
207 
208  if (!nBlockHash.IsNull()) {
209  BlockMap::iterator mi = mapBlockIndex.find(nBlockHash);
210  if (mi != mapBlockIndex.end() && (*mi).second) {
211  CBlockIndex* pindex = (*mi).second;
212  if (chainActive.Contains(pindex)) {
213  conf += chainActive.Height() - pindex->nHeight + 1;
214  }
215  }
216  }
217 
218  /*
219  Wait will we have 1 extra confirmation, otherwise some clients might reject this feeTX
220  -- This function is tied to NewBlock, so we will propagate this budget while the block is also propagating
221  */
222  if (conf < Params().Budget_Fee_Confirmations() + 1) {
223  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Collateral requires at least %d confirmations - %s - %d confirmations\n", Params().Budget_Fee_Confirmations() + 1, txidCollateral.ToString(), conf);
224  return;
225  }
226 
227  //create the proposal incase we're the first to make it
228  CFinalizedBudgetBroadcast finalizedBudgetBroadcast(strBudgetName, nBlockStart, vecTxBudgetPayments, txidCollateral);
229 
230  std::string strError = "";
231  if (!finalizedBudgetBroadcast.IsValid(strError)) {
232  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Invalid finalized budget - %s \n", strError);
233  return;
234  }
235 
236  LOCK(cs);
237  mapSeenFinalizedBudgets.insert(std::make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast));
238  finalizedBudgetBroadcast.Relay();
239  budget.AddFinalizedBudget(finalizedBudgetBroadcast);
240  nSubmittedHeight = nCurrentHeight;
241  LogPrint(BCLog::MNBUDGET,"CBudgetManager::SubmitFinalBudget - Done! %s\n", finalizedBudgetBroadcast.GetHash().ToString());
242 }
243 
244 //
245 // CBudgetDB
246 //
247 
249 {
250  pathDB = GetDataDir() / "budget.dat";
251  strMagicMessage = "MasternodeBudget";
252 }
253 
254 bool CBudgetDB::Write(const CBudgetManager& objToSave)
255 {
256  LOCK(objToSave.cs);
257 
258  int64_t nStart = GetTimeMillis();
259 
260  // serialize, checksum data up to that point, then append checksum
261  CDataStream ssObj(SER_DISK, CLIENT_VERSION);
262  ssObj << strMagicMessage; // masternode cache file specific magic message
263  ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
264  ssObj << objToSave;
265  uint256 hash = Hash(ssObj.begin(), ssObj.end());
266  ssObj << hash;
267 
268  // open output file, and associate with CAutoFile
269  FILE* file = fsbridge::fopen(pathDB, "wb");
270  CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
271  if (fileout.IsNull())
272  return error("%s : Failed to open file %s", __func__, pathDB.string());
273 
274  // Write and commit header, data
275  try {
276  fileout << ssObj;
277  } catch (const std::exception& e) {
278  return error("%s : Serialize or I/O error - %s", __func__, e.what());
279  }
280  fileout.fclose();
281 
282  LogPrint(BCLog::MNBUDGET,"Written info to budget.dat %dms\n", GetTimeMillis() - nStart);
283 
284  return true;
285 }
286 
288 {
289  LOCK(objToLoad.cs);
290 
291  int64_t nStart = GetTimeMillis();
292  // open input file, and associate with CAutoFile
293  FILE* file = fsbridge::fopen(pathDB, "rb");
294  CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
295  if (filein.IsNull()) {
296  error("%s : Failed to open file %s", __func__, pathDB.string());
297  return FileError;
298  }
299 
300  // use file size to size memory buffer
301  int fileSize = fs::file_size(pathDB);
302  int dataSize = fileSize - sizeof(uint256);
303  // Don't try to resize to a negative number if file is small
304  if (dataSize < 0)
305  dataSize = 0;
306  std::vector<unsigned char> vchData;
307  vchData.resize(dataSize);
308  uint256 hashIn;
309 
310  // read data and checksum from file
311  try {
312  filein.read((char*)&vchData[0], dataSize);
313  filein >> hashIn;
314  } catch (const std::exception& e) {
315  error("%s : Deserialize or I/O error - %s", __func__, e.what());
316  return HashReadError;
317  }
318  filein.fclose();
319 
320  CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);
321 
322  // verify stored checksum matches input data
323  uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
324  if (hashIn != hashTmp) {
325  error("%s : Checksum mismatch, data corrupted", __func__);
326  return IncorrectHash;
327  }
328 
329 
330  unsigned char pchMsgTmp[4];
331  std::string strMagicMessageTmp;
332  try {
333  // de-serialize file header (masternode cache file specific magic message) and ..
334  ssObj >> strMagicMessageTmp;
335 
336  // ... verify the message matches predefined one
337  if (strMagicMessage != strMagicMessageTmp) {
338  error("%s : Invalid masternode cache magic message", __func__);
339  return IncorrectMagicMessage;
340  }
341 
342 
343  // de-serialize file header (network specific magic number) and ..
344  ssObj >> FLATDATA(pchMsgTmp);
345 
346  // ... verify the network matches ours
347  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) {
348  error("%s : Invalid network magic number", __func__);
349  return IncorrectMagicNumber;
350  }
351 
352  // de-serialize data into CBudgetManager object
353  ssObj >> objToLoad;
354  } catch (const std::exception& e) {
355  objToLoad.Clear();
356  error("%s : Deserialize or I/O error - %s", __func__, e.what());
357  return IncorrectFormat;
358  }
359 
360  LogPrint(BCLog::MNBUDGET,"Loaded info from budget.dat %dms\n", GetTimeMillis() - nStart);
361  LogPrint(BCLog::MNBUDGET," %s\n", objToLoad.ToString());
362  if (!fDryRun) {
363  LogPrint(BCLog::MNBUDGET,"Budget manager - cleaning....\n");
364  objToLoad.CheckAndRemove();
365  LogPrint(BCLog::MNBUDGET,"Budget manager - result:\n");
366  LogPrint(BCLog::MNBUDGET," %s\n", objToLoad.ToString());
367  }
368 
369  return Ok;
370 }
371 
373 {
374  int64_t nStart = GetTimeMillis();
375 
376  CBudgetDB budgetdb;
377  CBudgetManager tempBudget;
378 
379  LogPrint(BCLog::MNBUDGET,"Verifying budget.dat format...\n");
380  CBudgetDB::ReadResult readResult = budgetdb.Read(tempBudget, true);
381  // there was an error and it was not an error on file opening => do not proceed
382  if (readResult == CBudgetDB::FileError)
383  LogPrint(BCLog::MNBUDGET,"Missing budgets file - budget.dat, will try to recreate\n");
384  else if (readResult != CBudgetDB::Ok) {
385  LogPrint(BCLog::MNBUDGET,"Error reading budget.dat: ");
386  if (readResult == CBudgetDB::IncorrectFormat)
387  LogPrint(BCLog::MNBUDGET,"magic is ok but data has invalid format, will try to recreate\n");
388  else {
389  LogPrint(BCLog::MNBUDGET,"file format is unknown or invalid, please fix it manually\n");
390  return;
391  }
392  }
393  LogPrint(BCLog::MNBUDGET,"Writting info to budget.dat...\n");
394  budgetdb.Write(budget);
395 
396  LogPrint(BCLog::MNBUDGET,"Budget dump finished %dms\n", GetTimeMillis() - nStart);
397 }
398 
400 {
401  std::string strError = "";
402  if (!finalizedBudget.IsValid(strError)) return false;
403 
404  if (mapFinalizedBudgets.count(finalizedBudget.GetHash())) {
405  return false;
406  }
407 
408  mapFinalizedBudgets.insert(std::make_pair(finalizedBudget.GetHash(), finalizedBudget));
409  return true;
410 }
411 
413 {
414  LOCK(cs);
415  std::string strError = "";
416  if (!budgetProposal.IsValid(strError)) {
417  LogPrint(BCLog::MNBUDGET,"CBudgetManager::AddProposal - invalid budget proposal - %s\n", strError);
418  return false;
419  }
420 
421  if (mapProposals.count(budgetProposal.GetHash())) {
422  return false;
423  }
424 
425  mapProposals.insert(std::make_pair(budgetProposal.GetHash(), budgetProposal));
426  LogPrint(BCLog::MNBUDGET,"CBudgetManager::AddProposal - proposal %s added\n", budgetProposal.GetName ().c_str ());
427  return true;
428 }
429 
431 {
432  LogPrint(BCLog::MNBUDGET, "CBudgetManager::CheckAndRemove\n");
433 
434  // std::map<uint256, CFinalizedBudget> tmpMapFinalizedBudgets;
435  // std::map<uint256, CBudgetProposal> tmpMapProposals;
436 
437  std::string strError = "";
438 
439  LogPrint(BCLog::MNBUDGET, "CBudgetManager::CheckAndRemove - mapFinalizedBudgets cleanup - size before: %d\n", mapFinalizedBudgets.size());
440  std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
441  while (it != mapFinalizedBudgets.end()) {
442  CFinalizedBudget* pfinalizedBudget = &((*it).second);
443 
444  pfinalizedBudget->fValid = pfinalizedBudget->IsValid(strError);
445  if (!strError.empty ()) {
446  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckAndRemove - Invalid finalized budget: %s\n", strError);
447  }
448  else {
449  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckAndRemove - Found valid finalized budget: %s %s\n",
450  pfinalizedBudget->strBudgetName.c_str(), pfinalizedBudget->nFeeTXHash.ToString().c_str());
451  }
452 
453  if (pfinalizedBudget->fValid) {
454  pfinalizedBudget->AutoCheck();
455  // tmpMapFinalizedBudgets.insert(std::make_pair(pfinalizedBudget->GetHash(), *pfinalizedBudget));
456  }
457 
458  ++it;
459  }
460 
461  LogPrint(BCLog::MNBUDGET, "CBudgetManager::CheckAndRemove - mapProposals cleanup - size before: %d\n", mapProposals.size());
462  std::map<uint256, CBudgetProposal>::iterator it2 = mapProposals.begin();
463  while (it2 != mapProposals.end()) {
464  CBudgetProposal* pbudgetProposal = &((*it2).second);
465  pbudgetProposal->fValid = pbudgetProposal->IsValid(strError);
466  if (!strError.empty ()) {
467  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckAndRemove - Invalid budget proposal - %s\n", strError);
468  strError = "";
469  }
470  else {
471  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckAndRemove - Found valid budget proposal: %s %s\n",
472  pbudgetProposal->strProposalName.c_str(), pbudgetProposal->nFeeTXHash.ToString().c_str());
473  }
474  if (pbudgetProposal->fValid) {
475  // tmpMapProposals.insert(std::make_pair(pbudgetProposal->GetHash(), *pbudgetProposal));
476  }
477 
478  ++it2;
479  }
480  // Remove invalid entries by overwriting complete map
481  // mapFinalizedBudgets = tmpMapFinalizedBudgets;
482  // mapProposals = tmpMapProposals;
483 
484  // LogPrint(BCLog::MNBUDGET, "CBudgetManager::CheckAndRemove - mapFinalizedBudgets cleanup - size after: %d\n", mapFinalizedBudgets.size());
485  // LogPrint(BCLog::MNBUDGET, "CBudgetManager::CheckAndRemove - mapProposals cleanup - size after: %d\n", mapProposals.size());
486  LogPrint(BCLog::MNBUDGET,"CBudgetManager::CheckAndRemove - PASSED\n");
487 
488 }
489 
490 bool CBudgetManager::FillBlockPayee(CMutableTransaction& txNew, CAmount nFees, bool fProofOfStake)
491 {
492  LOCK(cs);
493  LogPrintf("%s: budget manager filling block payee\n", __func__);
494  CBlockIndex* pindexPrev = chainActive.Tip();
495  if (!pindexPrev) return false;
496 
497  int nHighestCount = 0;
498  CScript payee;
499  CAmount nAmount = 0;
500 
501  // ------- Grab The Highest Count
502 
503  std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
504  while (it != mapFinalizedBudgets.end()) {
505  CFinalizedBudget* pfinalizedBudget = &((*it).second);
506  if (pfinalizedBudget->GetVoteCount() > nHighestCount &&
507  pindexPrev->nHeight + 1 >= pfinalizedBudget->GetBlockStart() &&
508  pindexPrev->nHeight + 1 <= pfinalizedBudget->GetBlockEnd() &&
509  pfinalizedBudget->GetPayeeAndAmount(pindexPrev->nHeight + 1, payee, nAmount)) {
510  nHighestCount = pfinalizedBudget->GetVoteCount();
511  }
512 
513  ++it;
514  }
515 
516  CAmount blockValue = GetBlockValue(pindexPrev->nHeight);
517 
518  if (fProofOfStake) {
519  if (nHighestCount > 0) {
520  unsigned int i = txNew.vout.size();
521  txNew.vout.resize(i + 1);
522  txNew.vout[i].scriptPubKey = payee;
523  txNew.vout[i].nValue = nAmount;
524 
525  CTxDestination address1;
526  ExtractDestination(payee, address1);
527  CBitcoinAddress address2(address1);
528  LogPrint(BCLog::MNBUDGET,"CBudgetManager::FillBlockPayee - Budget payment to %s for %lld, nHighestCount = %d\n", address2.ToString(), nAmount, nHighestCount);
529  }
530  else {
531  LogPrint(BCLog::MNBUDGET,"CBudgetManager::FillBlockPayee - No Budget payment, nHighestCount = %d\n", nHighestCount);
532  }
533  } else {
534  //miners get the full amount on these blocks and transaction fee
535  txNew.vout[0].nValue = blockValue;
536 
537  if (nHighestCount > 0) {
538  txNew.vout.resize(2);
539 
540  //these are super blocks, so their value can be much larger than normal
541  txNew.vout[1].scriptPubKey = payee;
542  txNew.vout[1].nValue = nAmount;
543 
544  CTxDestination address1;
545  ExtractDestination(payee, address1);
546  CBitcoinAddress address2(address1);
547 
548  LogPrint(BCLog::MNBUDGET,"CBudgetManager::FillBlockPayee - Budget payment to %s for %lld\n", address2.ToString(), nAmount);
549  }
550  }
551  return true;
552 }
553 
555 {
556  if (mapFinalizedBudgets.count(nHash))
557  return &mapFinalizedBudgets[nHash];
558 
559  return NULL;
560 }
561 
562 CBudgetProposal* CBudgetManager::FindProposal(const std::string& strProposalName)
563 {
564  //find the prop with the highest yes count
565 
566  int nYesCount = -99999;
567  CBudgetProposal* pbudgetProposal = NULL;
568 
569  std::map<uint256, CBudgetProposal>::iterator it = mapProposals.begin();
570  while (it != mapProposals.end()) {
571  if ((*it).second.strProposalName == strProposalName && (*it).second.GetYeas() > nYesCount) {
572  pbudgetProposal = &((*it).second);
573  nYesCount = pbudgetProposal->GetYeas();
574  }
575  ++it;
576  }
577 
578  if (nYesCount == -99999) return NULL;
579 
580  return pbudgetProposal;
581 }
582 
584 {
585  LOCK(cs);
586 
587  if (mapProposals.count(nHash))
588  return &mapProposals[nHash];
589 
590  return NULL;
591 }
592 
594 {
595  int nHighestCount = -1;
596  int nFivePercent = mnodeman.CountEnabled(ActiveProtocol()) / 20;
597 
598  std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
599  while (it != mapFinalizedBudgets.end()) {
600  CFinalizedBudget* pfinalizedBudget = &((*it).second);
601  if (pfinalizedBudget->GetVoteCount() > nHighestCount &&
602  nBlockHeight >= pfinalizedBudget->GetBlockStart() &&
603  nBlockHeight <= pfinalizedBudget->GetBlockEnd()) {
604  nHighestCount = pfinalizedBudget->GetVoteCount();
605  }
606 
607  ++it;
608  }
609 
610  LogPrint(BCLog::MNBUDGET,"CBudgetManager::IsBudgetPaymentBlock() - nHighestCount: %lli, 5%% of Masternodes: %lli. Number of budgets: %lli\n",
611  nHighestCount, nFivePercent, mapFinalizedBudgets.size());
612 
613  // If budget doesn't have 5% of the network votes, then we should pay a masternode instead
614  if (nHighestCount > nFivePercent) return true;
615 
616  return false;
617 }
618 
619 bool CBudgetManager::IsTransactionValid(const CTransaction& txNew, int nBlockHeight)
620 {
621  LOCK(cs);
622 
623  int nHighestCount = 0;
624  int nFivePercent = mnodeman.CountEnabled(ActiveProtocol()) / 20;
625  std::vector<CFinalizedBudget*> ret;
626 
627  // ------- Grab The Highest Count
628 
629  std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
630  while (it != mapFinalizedBudgets.end()) {
631  CFinalizedBudget* pfinalizedBudget = &((*it).second);
632  if (pfinalizedBudget->GetVoteCount() > nHighestCount &&
633  nBlockHeight >= pfinalizedBudget->GetBlockStart() &&
634  nBlockHeight <= pfinalizedBudget->GetBlockEnd()) {
635  nHighestCount = pfinalizedBudget->GetVoteCount();
636  }
637 
638  ++it;
639  }
640 
641  LogPrint(BCLog::MNBUDGET,"CBudgetManager::IsTransactionValid() - nHighestCount: %lli, 5%% of Masternodes: %lli mapFinalizedBudgets.size(): %ld\n",
642  nHighestCount, nFivePercent, mapFinalizedBudgets.size());
643  /*
644  If budget doesn't have 5% of the network votes, then we should pay a masternode instead
645  */
646  if (nHighestCount < nFivePercent) return false;
647 
648  // check the highest finalized budgets (+/- 10% to assist in consensus)
649 
650  it = mapFinalizedBudgets.begin();
651  while (it != mapFinalizedBudgets.end()) {
652  CFinalizedBudget* pfinalizedBudget = &((*it).second);
653 
654  if (pfinalizedBudget->GetVoteCount() > nHighestCount - mnodeman.CountEnabled(ActiveProtocol()) / 10) {
655  if (nBlockHeight >= pfinalizedBudget->GetBlockStart() && nBlockHeight <= pfinalizedBudget->GetBlockEnd()) {
656  if (pfinalizedBudget->IsTransactionValid(txNew, nBlockHeight)) {
657  return true;
658  }
659  }
660  }
661 
662  ++it;
663  }
664 
665  //we looked through all of the known budgets
666  return false;
667 }
668 
669 std::vector<CBudgetProposal*> CBudgetManager::GetAllProposals()
670 {
671  LOCK(cs);
672 
673  std::vector<CBudgetProposal*> vBudgetProposalRet;
674 
675  std::map<uint256, CBudgetProposal>::iterator it = mapProposals.begin();
676  while (it != mapProposals.end()) {
677  (*it).second.CleanAndRemove(false);
678 
679  CBudgetProposal* pbudgetProposal = &((*it).second);
680  vBudgetProposalRet.push_back(pbudgetProposal);
681 
682  ++it;
683  }
684 
685  return vBudgetProposalRet;
686 }
687 
688 //
689 // Sort by votes, if there's a tie sort by their feeHash TX
690 //
692  bool operator()(const std::pair<CBudgetProposal*, int>& left, const std::pair<CBudgetProposal*, int>& right)
693  {
694  if (left.second != right.second)
695  return (left.second > right.second);
696  return (left.first->nFeeTXHash > right.first->nFeeTXHash);
697  }
698 };
699 
700 //Need to review this function
701 std::vector<CBudgetProposal*> CBudgetManager::GetBudget()
702 {
703  LOCK(cs);
704 
705  // ------- Sort budgets by Yes Count
706 
707  std::vector<std::pair<CBudgetProposal*, int> > vBudgetPorposalsSort;
708 
709  std::map<uint256, CBudgetProposal>::iterator it = mapProposals.begin();
710  while (it != mapProposals.end()) {
711  (*it).second.CleanAndRemove(false);
712  vBudgetPorposalsSort.push_back(std::make_pair(&((*it).second), (*it).second.GetYeas() - (*it).second.GetNays()));
713  ++it;
714  }
715 
716  std::sort(vBudgetPorposalsSort.begin(), vBudgetPorposalsSort.end(), sortProposalsByVotes());
717 
718  // ------- Grab The Budgets In Order
719 
720  std::vector<CBudgetProposal*> vBudgetProposalsRet;
721 
722  CAmount nBudgetAllocated = 0;
723  CBlockIndex* pindexPrev = chainActive.Tip();
724  if (pindexPrev == NULL) return vBudgetProposalsRet;
725 
726  int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % GetBudgetPaymentCycleBlocks() + GetBudgetPaymentCycleBlocks();
727  int nBlockEnd = nBlockStart + GetBudgetPaymentCycleBlocks() - 1;
728  CAmount nTotalBudget = GetTotalBudget(nBlockStart);
729 
730 
731  std::vector<std::pair<CBudgetProposal*, int> >::iterator it2 = vBudgetPorposalsSort.begin();
732  while (it2 != vBudgetPorposalsSort.end()) {
733  CBudgetProposal* pbudgetProposal = (*it2).first;
734 
735  LogPrint(BCLog::MNBUDGET,"CBudgetManager::GetBudget() - Processing Budget %s\n", pbudgetProposal->strProposalName.c_str());
736  //prop start/end should be inside this period
737  if (pbudgetProposal->fValid && pbudgetProposal->nBlockStart <= nBlockStart &&
738  pbudgetProposal->nBlockEnd >= nBlockEnd &&
739  pbudgetProposal->GetYeas() - pbudgetProposal->GetNays() > mnodeman.CountEnabled(ActiveProtocol()) / 10 &&
740  pbudgetProposal->IsEstablished()) {
741 
742  LogPrint(BCLog::MNBUDGET,"CBudgetManager::GetBudget() - Check 1 passed: valid=%d | %ld <= %ld | %ld >= %ld | Yeas=%d Nays=%d Count=%d | established=%d\n",
743  pbudgetProposal->fValid, pbudgetProposal->nBlockStart, nBlockStart, pbudgetProposal->nBlockEnd,
744  nBlockEnd, pbudgetProposal->GetYeas(), pbudgetProposal->GetNays(), mnodeman.CountEnabled(ActiveProtocol()) / 10,
745  pbudgetProposal->IsEstablished());
746 
747  if (pbudgetProposal->GetAmount() + nBudgetAllocated <= nTotalBudget) {
748  pbudgetProposal->SetAllotted(pbudgetProposal->GetAmount());
749  nBudgetAllocated += pbudgetProposal->GetAmount();
750  vBudgetProposalsRet.push_back(pbudgetProposal);
751  LogPrint(BCLog::MNBUDGET,"CBudgetManager::GetBudget() - Check 2 passed: Budget added\n");
752  } else {
753  pbudgetProposal->SetAllotted(0);
754  LogPrint(BCLog::MNBUDGET,"CBudgetManager::GetBudget() - Check 2 failed: no amount allotted\n");
755  }
756  }
757  else {
758  LogPrint(BCLog::MNBUDGET,"CBudgetManager::GetBudget() - Check 1 failed: valid=%d | %ld <= %ld | %ld >= %ld | Yeas=%d Nays=%d Count=%d | established=%d\n",
759  pbudgetProposal->fValid, pbudgetProposal->nBlockStart, nBlockStart, pbudgetProposal->nBlockEnd,
760  nBlockEnd, pbudgetProposal->GetYeas(), pbudgetProposal->GetNays(), mnodeman.CountEnabled(ActiveProtocol()) / 10,
761  pbudgetProposal->IsEstablished());
762  }
763 
764  ++it2;
765  }
766 
767  return vBudgetProposalsRet;
768 }
769 
770 // Sort by votes, if there's a tie sort by their feeHash TX
772  bool operator()(const std::pair<CFinalizedBudget*, int>& left, const std::pair<CFinalizedBudget*, int>& right)
773  {
774  if (left.second != right.second)
775  return left.second > right.second;
776  return (left.first->nFeeTXHash > right.first->nFeeTXHash);
777  }
778 };
779 
780 std::vector<CFinalizedBudget*> CBudgetManager::GetFinalizedBudgets()
781 {
782  LOCK(cs);
783 
784  std::vector<CFinalizedBudget*> vFinalizedBudgetsRet;
785  std::vector<std::pair<CFinalizedBudget*, int> > vFinalizedBudgetsSort;
786 
787  // ------- Grab The Budgets In Order
788 
789  std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
790  while (it != mapFinalizedBudgets.end()) {
791  CFinalizedBudget* pfinalizedBudget = &((*it).second);
792 
793  vFinalizedBudgetsSort.push_back(std::make_pair(pfinalizedBudget, pfinalizedBudget->GetVoteCount()));
794  ++it;
795  }
796  std::sort(vFinalizedBudgetsSort.begin(), vFinalizedBudgetsSort.end(), sortFinalizedBudgetsByVotes());
797 
798  std::vector<std::pair<CFinalizedBudget*, int> >::iterator it2 = vFinalizedBudgetsSort.begin();
799  while (it2 != vFinalizedBudgetsSort.end()) {
800  vFinalizedBudgetsRet.push_back((*it2).first);
801  ++it2;
802  }
803 
804  return vFinalizedBudgetsRet;
805 }
806 
807 std::string CBudgetManager::GetRequiredPaymentsString(int nBlockHeight)
808 {
809  LOCK(cs);
810 
811  std::string ret = "unknown-budget";
812 
813  std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
814  while (it != mapFinalizedBudgets.end()) {
815  CFinalizedBudget* pfinalizedBudget = &((*it).second);
816  if (nBlockHeight >= pfinalizedBudget->GetBlockStart() && nBlockHeight <= pfinalizedBudget->GetBlockEnd()) {
817  CTxBudgetPayment payment;
818  if (pfinalizedBudget->GetBudgetPaymentByBlock(nBlockHeight, payment)) {
819  if (ret == "unknown-budget") {
820  ret = payment.nProposalHash.ToString();
821  } else {
822  ret += ",";
823  ret += payment.nProposalHash.ToString();
824  }
825  } else {
826  LogPrint(BCLog::MNBUDGET,"CBudgetManager::GetRequiredPaymentsString - Couldn't find budget payment for block %d\n", nBlockHeight);
827  }
828  }
829 
830  ++it;
831  }
832 
833  return ret;
834 }
835 
837 {
838  if (chainActive.Tip() == NULL) return 0;
839 
840  //get block value and calculate from that
841  CAmount nSubsidy = 0;
842  if (nHeight <= Params().LAST_POW_BLOCK() && nHeight >= 151200) {
843  nSubsidy = 50 * COIN;
844  } else if (nHeight <= 302399 && nHeight > Params().LAST_POW_BLOCK()) {
845  nSubsidy = 50 * COIN;
846  } else if (nHeight <= 345599 && nHeight >= 302400) {
847  nSubsidy = 45 * COIN;
848  } else if (nHeight <= 388799 && nHeight >= 345600) {
849  nSubsidy = 40 * COIN;
850  } else if (nHeight <= 431999 && nHeight >= 388800) {
851  nSubsidy = 35 * COIN;
852  } else if (nHeight <= 475199 && nHeight >= 432000) {
853  nSubsidy = 30 * COIN;
854  } else if (nHeight <= 518399 && nHeight >= 475200) {
855  nSubsidy = 25 * COIN;
856  } else if (nHeight <= 561599 && nHeight >= 518400) {
857  nSubsidy = 20 * COIN;
858  } else if (nHeight <= 604799 && nHeight >= 561600) {
859  nSubsidy = 15 * COIN;
860  } else if (nHeight <= 647999 && nHeight >= 604800) {
861  nSubsidy = 10 * COIN;
862  } else if (nHeight >= 648000) {
863  nSubsidy = 5 * COIN;
864  } else {
865  nSubsidy = 0 * COIN;
866  }
867 
868  // Amount of blocks in a months period of time (using 1 minutes per) = (60*24*30)
869  if (nHeight <= 172800) {
870  return 648000 * COIN;
871  } else {
872  return ((nSubsidy / 100) * 10) * 1440 * 30;
873  }
874 }
875 
877 {
878  TRY_LOCK(cs, fBudgetNewBlock);
879  if (!fBudgetNewBlock) return;
880 
882 
883  if (strBudgetMode == "suggest") { //suggest the budget we see
885  }
886 
887  //this function should be called 1/14 blocks, allowing up to 100 votes per day on all proposals
888  if (chainActive.Height() % 14 != 0) return;
889 
890  // incremental sync with our peers
891  if (masternodeSync.IsSynced()) {
892  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - incremental sync started\n");
893  if (chainActive.Height() % 1440 == secp256k1_rand32() % 1440) {
894  ClearSeen();
895  ResetSync();
896  }
897 
898  LOCK(cs_vNodes);
899  for (CNode* pnode : vNodes)
900  if (pnode->nVersion >= ActiveProtocol())
901  Sync(pnode, UINT256_ZERO, true);
902 
903  MarkSynced();
904  }
905 
906 
907  CheckAndRemove();
908 
909  //remove invalid votes once in a while (we have to check the signatures and validity of every vote, somewhat CPU intensive)
910 
911  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - askedForSourceProposalOrBudget cleanup - size: %d\n", askedForSourceProposalOrBudget.size());
912  std::map<uint256, int64_t>::iterator it = askedForSourceProposalOrBudget.begin();
913  while (it != askedForSourceProposalOrBudget.end()) {
914  if ((*it).second > GetTime() - (60 * 60 * 24)) {
915  ++it;
916  } else {
917  askedForSourceProposalOrBudget.erase(it++);
918  }
919  }
920 
921  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - mapProposals cleanup - size: %d\n", mapProposals.size());
922  std::map<uint256, CBudgetProposal>::iterator it2 = mapProposals.begin();
923  while (it2 != mapProposals.end()) {
924  (*it2).second.CleanAndRemove(false);
925  ++it2;
926  }
927 
928  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - mapFinalizedBudgets cleanup - size: %d\n", mapFinalizedBudgets.size());
929  std::map<uint256, CFinalizedBudget>::iterator it3 = mapFinalizedBudgets.begin();
930  while (it3 != mapFinalizedBudgets.end()) {
931  (*it3).second.CleanAndRemove(false);
932  ++it3;
933  }
934 
935  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - vecImmatureBudgetProposals cleanup - size: %d\n", vecImmatureBudgetProposals.size());
936  std::vector<CBudgetProposalBroadcast>::iterator it4 = vecImmatureBudgetProposals.begin();
937  while (it4 != vecImmatureBudgetProposals.end()) {
938  std::string strError = "";
939  int nConf = 0;
940  if (!IsBudgetCollateralValid((*it4).nFeeTXHash, (*it4).GetHash(), strError, (*it4).nTime, nConf)) {
941  ++it4;
942  continue;
943  }
944 
945  if (!(*it4).IsValid(strError)) {
946  LogPrint(BCLog::MNBUDGET,"mprop (immature) - invalid budget proposal - %s\n", strError);
947  it4 = vecImmatureBudgetProposals.erase(it4);
948  continue;
949  }
950 
951  CBudgetProposal budgetProposal((*it4));
952  if (AddProposal(budgetProposal)) {
953  (*it4).Relay();
954  }
955 
956  LogPrint(BCLog::MNBUDGET,"mprop (immature) - new budget - %s\n", (*it4).GetHash().ToString());
957  it4 = vecImmatureBudgetProposals.erase(it4);
958  }
959 
960  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - vecImmatureFinalizedBudgets cleanup - size: %d\n", vecImmatureFinalizedBudgets.size());
961  std::vector<CFinalizedBudgetBroadcast>::iterator it5 = vecImmatureFinalizedBudgets.begin();
962  while (it5 != vecImmatureFinalizedBudgets.end()) {
963  std::string strError = "";
964  int nConf = 0;
965  if (!IsBudgetCollateralValid((*it5).nFeeTXHash, (*it5).GetHash(), strError, (*it5).nTime, nConf)) {
966  ++it5;
967  continue;
968  }
969 
970  if (!(*it5).IsValid(strError)) {
971  LogPrint(BCLog::MNBUDGET,"fbs (immature) - invalid finalized budget - %s\n", strError);
972  it5 = vecImmatureFinalizedBudgets.erase(it5);
973  continue;
974  }
975 
976  LogPrint(BCLog::MNBUDGET,"fbs (immature) - new finalized budget - %s\n", (*it5).GetHash().ToString());
977 
978  CFinalizedBudget finalizedBudget((*it5));
979  if (AddFinalizedBudget(finalizedBudget)) {
980  (*it5).Relay();
981  }
982 
983  it5 = vecImmatureFinalizedBudgets.erase(it5);
984  }
985  LogPrint(BCLog::MNBUDGET,"CBudgetManager::NewBlock - PASSED\n");
986 }
987 
988 void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
989 {
990  // lite mode is not supported
991  if (fLiteMode) return;
992  if (!masternodeSync.IsBlockchainSynced()) return;
993 
994  LOCK(cs_budget);
995 
996  if (strCommand == NetMsgType::BUDGETVOTESYNC) { //Masternode vote sync
997  uint256 nProp;
998  vRecv >> nProp;
999 
1000  if (Params().NetworkID() == CBaseChainParams::MAIN) {
1001  if (nProp.IsNull()) {
1002  if (pfrom->HasFulfilledRequest("budgetvotesync")) {
1003  LogPrint(BCLog::MNBUDGET,"mnvs - peer already asked me for the list\n");
1004  LOCK(cs_main);
1005  Misbehaving(pfrom->GetId(), 20);
1006  return;
1007  }
1008  pfrom->FulfilledRequest("budgetvotesync");
1009  }
1010  }
1011 
1012  Sync(pfrom, nProp);
1013  LogPrint(BCLog::MNBUDGET, "mnvs - Sent Masternode votes to peer %i\n", pfrom->GetId());
1014  }
1015 
1016  if (strCommand == NetMsgType::BUDGETPROPOSAL) { //Masternode Proposal
1017  CBudgetProposalBroadcast budgetProposalBroadcast;
1018  vRecv >> budgetProposalBroadcast;
1019 
1020  if (mapSeenMasternodeBudgetProposals.count(budgetProposalBroadcast.GetHash())) {
1021  masternodeSync.AddedBudgetItem(budgetProposalBroadcast.GetHash());
1022  return;
1023  }
1024 
1025  std::string strError = "";
1026  int nConf = 0;
1027  if (!IsBudgetCollateralValid(budgetProposalBroadcast.nFeeTXHash, budgetProposalBroadcast.GetHash(), strError, budgetProposalBroadcast.nTime, nConf)) {
1028  LogPrint(BCLog::MNBUDGET,"Proposal FeeTX is not valid - %s - %s\n", budgetProposalBroadcast.nFeeTXHash.ToString(), strError);
1029  if (nConf >= 1) vecImmatureBudgetProposals.push_back(budgetProposalBroadcast);
1030  return;
1031  }
1032 
1033  mapSeenMasternodeBudgetProposals.insert(std::make_pair(budgetProposalBroadcast.GetHash(), budgetProposalBroadcast));
1034 
1035  if (!budgetProposalBroadcast.IsValid(strError)) {
1036  LogPrint(BCLog::MNBUDGET,"mprop - invalid budget proposal - %s\n", strError);
1037  return;
1038  }
1039 
1040  CBudgetProposal budgetProposal(budgetProposalBroadcast);
1041  if (AddProposal(budgetProposal)) {
1042  budgetProposalBroadcast.Relay();
1043  }
1044  masternodeSync.AddedBudgetItem(budgetProposalBroadcast.GetHash());
1045 
1046  LogPrint(BCLog::MNBUDGET,"mprop - new budget - %s\n", budgetProposalBroadcast.GetHash().ToString());
1047 
1048  //We might have active votes for this proposal that are valid now
1049  CheckOrphanVotes();
1050  }
1051 
1052  if (strCommand == NetMsgType::BUDGETVOTE) { // Budget Vote
1053  CBudgetVote vote;
1054  vRecv >> vote;
1055  vote.fValid = true;
1056 
1057  if (mapSeenMasternodeBudgetVotes.count(vote.GetHash())) {
1058  masternodeSync.AddedBudgetItem(vote.GetHash());
1059  return;
1060  }
1061 
1062  CMasternode* pmn = mnodeman.Find(vote.vin);
1063  if (pmn == NULL) {
1064  LogPrint(BCLog::MNBUDGET,"mvote - unknown masternode - vin: %s\n", vote.vin.prevout.hash.ToString());
1065  mnodeman.AskForMN(pfrom, vote.vin);
1066  return;
1067  }
1068 
1069 
1070  mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote));
1071  if (!vote.SignatureValid(true)) {
1072  if (masternodeSync.IsSynced()) {
1073  LogPrintf("CBudgetManager::ProcessMessage() : mvote - signature invalid\n");
1074  LOCK(cs_main);
1075  Misbehaving(pfrom->GetId(), 20);
1076  }
1077  // it could just be a non-synced masternode
1078  mnodeman.AskForMN(pfrom, vote.vin);
1079  return;
1080  }
1081 
1082  std::string strError = "";
1083  if (UpdateProposal(vote, pfrom, strError)) {
1084  vote.Relay();
1085  masternodeSync.AddedBudgetItem(vote.GetHash());
1086  }
1087 
1088  LogPrint(BCLog::MNBUDGET,"mvote - new budget vote for budget %s - %s\n", vote.nProposalHash.ToString(), vote.GetHash().ToString());
1089  }
1090 
1091  if (strCommand == NetMsgType::FINALBUDGET) { //Finalized Budget Suggestion
1092  CFinalizedBudgetBroadcast finalizedBudgetBroadcast;
1093  vRecv >> finalizedBudgetBroadcast;
1094 
1095  if (mapSeenFinalizedBudgets.count(finalizedBudgetBroadcast.GetHash())) {
1096  masternodeSync.AddedBudgetItem(finalizedBudgetBroadcast.GetHash());
1097  return;
1098  }
1099 
1100  std::string strError = "";
1101  int nConf = 0;
1102  if (!IsBudgetCollateralValid(finalizedBudgetBroadcast.nFeeTXHash, finalizedBudgetBroadcast.GetHash(), strError, finalizedBudgetBroadcast.nTime, nConf)) {
1103  LogPrint(BCLog::MNBUDGET,"Finalized Budget FeeTX is not valid - %s - %s\n", finalizedBudgetBroadcast.nFeeTXHash.ToString(), strError);
1104 
1105  if (nConf >= 1) vecImmatureFinalizedBudgets.push_back(finalizedBudgetBroadcast);
1106  return;
1107  }
1108 
1109  mapSeenFinalizedBudgets.insert(std::make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast));
1110 
1111  if (!finalizedBudgetBroadcast.IsValid(strError)) {
1112  LogPrint(BCLog::MNBUDGET,"fbs - invalid finalized budget - %s\n", strError);
1113  return;
1114  }
1115 
1116  LogPrint(BCLog::MNBUDGET,"fbs - new finalized budget - %s\n", finalizedBudgetBroadcast.GetHash().ToString());
1117 
1118  CFinalizedBudget finalizedBudget(finalizedBudgetBroadcast);
1119  if (AddFinalizedBudget(finalizedBudget)) {
1120  finalizedBudgetBroadcast.Relay();
1121  }
1122  masternodeSync.AddedBudgetItem(finalizedBudgetBroadcast.GetHash());
1123 
1124  //we might have active votes for this budget that are now valid
1125  CheckOrphanVotes();
1126  }
1127 
1128  if (strCommand == NetMsgType::FINALBUDGETVOTE) { //Finalized Budget Vote
1129  CFinalizedBudgetVote vote;
1130  vRecv >> vote;
1131  vote.fValid = true;
1132 
1133  if (mapSeenFinalizedBudgetVotes.count(vote.GetHash())) {
1134  masternodeSync.AddedBudgetItem(vote.GetHash());
1135  return;
1136  }
1137 
1138  CMasternode* pmn = mnodeman.Find(vote.vin);
1139  if (pmn == NULL) {
1140  LogPrint(BCLog::MNBUDGET, "fbvote - unknown masternode - vin: %s\n", vote.vin.prevout.hash.ToString());
1141  mnodeman.AskForMN(pfrom, vote.vin);
1142  return;
1143  }
1144 
1145  mapSeenFinalizedBudgetVotes.insert(std::make_pair(vote.GetHash(), vote));
1146  if (!vote.SignatureValid(true)) {
1147  if (masternodeSync.IsSynced()) {
1148  LogPrintf("CBudgetManager::ProcessMessage() : fbvote - signature invalid\n");
1149  LOCK(cs_main);
1150  Misbehaving(pfrom->GetId(), 20);
1151  }
1152  // it could just be a non-synced masternode
1153  mnodeman.AskForMN(pfrom, vote.vin);
1154  return;
1155  }
1156 
1157  std::string strError = "";
1158  if (UpdateFinalizedBudget(vote, pfrom, strError)) {
1159  vote.Relay();
1160  masternodeSync.AddedBudgetItem(vote.GetHash());
1161 
1162  LogPrint(BCLog::MNBUDGET,"fbvote - new finalized budget vote - %s\n", vote.GetHash().ToString());
1163  } else {
1164  LogPrint(BCLog::MNBUDGET,"fbvote - rejected finalized budget vote - %s - %s\n", vote.GetHash().ToString(), strError);
1165  }
1166  }
1167 }
1168 
1170 {
1171  if (mapProposals.count(nHash)) return true;
1172  return false;
1173 }
1174 
1175 //mark that a full sync is needed
1177 {
1178  LOCK(cs);
1179 
1180 
1181  std::map<uint256, CBudgetProposalBroadcast>::iterator it1 = mapSeenMasternodeBudgetProposals.begin();
1182  while (it1 != mapSeenMasternodeBudgetProposals.end()) {
1183  CBudgetProposal* pbudgetProposal = FindProposal((*it1).first);
1184  if (pbudgetProposal && pbudgetProposal->fValid) {
1185  //mark votes
1186  std::map<uint256, CBudgetVote>::iterator it2 = pbudgetProposal->mapVotes.begin();
1187  while (it2 != pbudgetProposal->mapVotes.end()) {
1188  (*it2).second.fSynced = false;
1189  ++it2;
1190  }
1191  }
1192  ++it1;
1193  }
1194 
1195  std::map<uint256, CFinalizedBudgetBroadcast>::iterator it3 = mapSeenFinalizedBudgets.begin();
1196  while (it3 != mapSeenFinalizedBudgets.end()) {
1197  CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first);
1198  if (pfinalizedBudget && pfinalizedBudget->fValid) {
1199  //send votes
1200  std::map<uint256, CFinalizedBudgetVote>::iterator it4 = pfinalizedBudget->mapVotes.begin();
1201  while (it4 != pfinalizedBudget->mapVotes.end()) {
1202  (*it4).second.fSynced = false;
1203  ++it4;
1204  }
1205  }
1206  ++it3;
1207  }
1208 }
1209 
1211 {
1212  LOCK(cs);
1213 
1214  /*
1215  Mark that we've sent all valid items
1216  */
1217 
1218  std::map<uint256, CBudgetProposalBroadcast>::iterator it1 = mapSeenMasternodeBudgetProposals.begin();
1219  while (it1 != mapSeenMasternodeBudgetProposals.end()) {
1220  CBudgetProposal* pbudgetProposal = FindProposal((*it1).first);
1221  if (pbudgetProposal && pbudgetProposal->fValid) {
1222  //mark votes
1223  std::map<uint256, CBudgetVote>::iterator it2 = pbudgetProposal->mapVotes.begin();
1224  while (it2 != pbudgetProposal->mapVotes.end()) {
1225  if ((*it2).second.fValid)
1226  (*it2).second.fSynced = true;
1227  ++it2;
1228  }
1229  }
1230  ++it1;
1231  }
1232 
1233  std::map<uint256, CFinalizedBudgetBroadcast>::iterator it3 = mapSeenFinalizedBudgets.begin();
1234  while (it3 != mapSeenFinalizedBudgets.end()) {
1235  CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first);
1236  if (pfinalizedBudget && pfinalizedBudget->fValid) {
1237  //mark votes
1238  std::map<uint256, CFinalizedBudgetVote>::iterator it4 = pfinalizedBudget->mapVotes.begin();
1239  while (it4 != pfinalizedBudget->mapVotes.end()) {
1240  if ((*it4).second.fValid)
1241  (*it4).second.fSynced = true;
1242  ++it4;
1243  }
1244  }
1245  ++it3;
1246  }
1247 }
1248 
1249 
1250 void CBudgetManager::Sync(CNode* pfrom, uint256 nProp, bool fPartial)
1251 {
1252  LOCK(cs);
1253 
1254  /*
1255  Sync with a client on the network
1256 
1257  --
1258 
1259  This code checks each of the hash maps for all known budget proposals and finalized budget proposals, then checks them against the
1260  budget object to see if they're OK. If all checks pass, we'll send it to the peer.
1261 
1262  */
1263 
1264  int nInvCount = 0;
1265 
1266  std::map<uint256, CBudgetProposalBroadcast>::iterator it1 = mapSeenMasternodeBudgetProposals.begin();
1267  while (it1 != mapSeenMasternodeBudgetProposals.end()) {
1268  CBudgetProposal* pbudgetProposal = FindProposal((*it1).first);
1269  if (pbudgetProposal && pbudgetProposal->fValid && (nProp.IsNull() || (*it1).first == nProp)) {
1270  pfrom->PushInventory(CInv(MSG_BUDGET_PROPOSAL, (*it1).second.GetHash()));
1271  nInvCount++;
1272 
1273  //send votes
1274  std::map<uint256, CBudgetVote>::iterator it2 = pbudgetProposal->mapVotes.begin();
1275  while (it2 != pbudgetProposal->mapVotes.end()) {
1276  if ((*it2).second.fValid) {
1277  if ((fPartial && !(*it2).second.fSynced) || !fPartial) {
1278  pfrom->PushInventory(CInv(MSG_BUDGET_VOTE, (*it2).second.GetHash()));
1279  nInvCount++;
1280  }
1281  }
1282  ++it2;
1283  }
1284  }
1285  ++it1;
1286  }
1287 
1289 
1290  LogPrint(BCLog::MNBUDGET, "CBudgetManager::Sync - sent %d items\n", nInvCount);
1291 
1292  nInvCount = 0;
1293 
1294  std::map<uint256, CFinalizedBudgetBroadcast>::iterator it3 = mapSeenFinalizedBudgets.begin();
1295  while (it3 != mapSeenFinalizedBudgets.end()) {
1296  CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first);
1297  if (pfinalizedBudget && pfinalizedBudget->fValid && (nProp.IsNull() || (*it3).first == nProp)) {
1298  pfrom->PushInventory(CInv(MSG_BUDGET_FINALIZED, (*it3).second.GetHash()));
1299  nInvCount++;
1300 
1301  //send votes
1302  std::map<uint256, CFinalizedBudgetVote>::iterator it4 = pfinalizedBudget->mapVotes.begin();
1303  while (it4 != pfinalizedBudget->mapVotes.end()) {
1304  if ((*it4).second.fValid) {
1305  if ((fPartial && !(*it4).second.fSynced) || !fPartial) {
1306  pfrom->PushInventory(CInv(MSG_BUDGET_FINALIZED_VOTE, (*it4).second.GetHash()));
1307  nInvCount++;
1308  }
1309  }
1310  ++it4;
1311  }
1312  }
1313  ++it3;
1314  }
1315 
1317  LogPrint(BCLog::MNBUDGET, "CBudgetManager::Sync - sent %d items\n", nInvCount);
1318 }
1319 
1320 bool CBudgetManager::UpdateProposal(CBudgetVote& vote, CNode* pfrom, std::string& strError)
1321 {
1322  LOCK(cs);
1323 
1324  if (!mapProposals.count(vote.nProposalHash)) {
1325  if (pfrom) {
1326  // only ask for missing items after our syncing process is complete --
1327  // otherwise we'll think a full sync succeeded when they return a result
1328  if (!masternodeSync.IsSynced()) return false;
1329 
1330  LogPrint(BCLog::MNBUDGET,"CBudgetManager::UpdateProposal - Unknown proposal %d, asking for source proposal\n", vote.nProposalHash.ToString());
1332 
1333  if (!askedForSourceProposalOrBudget.count(vote.nProposalHash)) {
1336  }
1337  }
1338 
1339  strError = "Proposal not found!";
1340  return false;
1341  }
1342 
1343 
1344  return mapProposals[vote.nProposalHash].AddOrUpdateVote(vote, strError);
1345 }
1346 
1347 bool CBudgetManager::UpdateFinalizedBudget(CFinalizedBudgetVote& vote, CNode* pfrom, std::string& strError)
1348 {
1349  LOCK(cs);
1350 
1351  if (!mapFinalizedBudgets.count(vote.nBudgetHash)) {
1352  if (pfrom) {
1353  // only ask for missing items after our syncing process is complete --
1354  // otherwise we'll think a full sync succeeded when they return a result
1355  if (!masternodeSync.IsSynced()) return false;
1356 
1357  LogPrint(BCLog::MNBUDGET,"CBudgetManager::UpdateFinalizedBudget - Unknown Finalized Proposal %s, asking for source budget\n", vote.nBudgetHash.ToString());
1359 
1360  if (!askedForSourceProposalOrBudget.count(vote.nBudgetHash)) {
1363  }
1364  }
1365 
1366  strError = "Finalized Budget " + vote.nBudgetHash.ToString() + " not found!";
1367  return false;
1368  }
1369  LogPrint(BCLog::MNBUDGET,"CBudgetManager::UpdateFinalizedBudget - Finalized Proposal %s added\n", vote.nBudgetHash.ToString());
1370  return mapFinalizedBudgets[vote.nBudgetHash].AddOrUpdateVote(vote, strError);
1371 }
1372 
1374 {
1375  strProposalName = "unknown";
1376  nBlockStart = 0;
1377  nBlockEnd = 0;
1378  nAmount = 0;
1379  nTime = 0;
1380  fValid = true;
1381 }
1382 
1383 CBudgetProposal::CBudgetProposal(std::string strProposalNameIn, std::string strURLIn, int nBlockStartIn, int nBlockEndIn, CScript addressIn, CAmount nAmountIn, uint256 nFeeTXHashIn)
1384 {
1385  strProposalName = strProposalNameIn;
1386  strURL = strURLIn;
1387  nBlockStart = nBlockStartIn;
1388  nBlockEnd = nBlockEndIn;
1389  address = addressIn;
1390  nAmount = nAmountIn;
1391  nFeeTXHash = nFeeTXHashIn;
1392  fValid = true;
1393 }
1394 
1396 {
1398  strURL = other.strURL;
1399  nBlockStart = other.nBlockStart;
1400  nBlockEnd = other.nBlockEnd;
1401  address = other.address;
1402  nAmount = other.nAmount;
1403  nTime = other.nTime;
1404  nFeeTXHash = other.nFeeTXHash;
1405  mapVotes = other.mapVotes;
1406  fValid = true;
1407 }
1408 
1409 bool CBudgetProposal::IsValid(std::string& strError, bool fCheckCollateral)
1410 {
1411  if (GetNays() - GetYeas() > mnodeman.CountEnabled(ActiveProtocol()) / 10) {
1412  strError = "Proposal " + strProposalName + ": Active removal";
1413  return false;
1414  }
1415 
1416  if (nBlockStart < 0) {
1417  strError = "Invalid Proposal";
1418  return false;
1419  }
1420 
1421  if (nBlockEnd < nBlockStart) {
1422  strError = "Proposal " + strProposalName + ": Invalid nBlockEnd (end before start)";
1423  return false;
1424  }
1425 
1426  if (nAmount < 10 * COIN) {
1427  strError = "Proposal " + strProposalName + ": Invalid nAmount";
1428  return false;
1429  }
1430 
1431  if (address == CScript()) {
1432  strError = "Proposal " + strProposalName + ": Invalid Payment Address";
1433  return false;
1434  }
1435 
1436  if (fCheckCollateral) {
1437  int nConf = 0;
1438  if (!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError, nTime, nConf)) {
1439  strError = "Proposal " + strProposalName + ": Invalid collateral";
1440  return false;
1441  }
1442  }
1443 
1444  /*
1445  TODO: There might be an issue with multisig in the coinbase on mainnet, we will add support for it in a future release.
1446  */
1447  if (address.IsPayToScriptHash()) {
1448  strError = "Proposal " + strProposalName + ": Multisig is not currently supported.";
1449  return false;
1450  }
1451 
1452  //if proposal doesn't gain traction within 2 weeks, remove it
1453  // nTime not being saved correctly
1454  // -- TODO: We should keep track of the last time the proposal was valid, if it's invalid for 2 weeks, erase it
1455  // if(nTime + (60*60*24*2) < GetAdjustedTime()) {
1456  // if(GetYeas()-GetNays() < (mnodeman.CountEnabled(ActiveProtocol())/10)) {
1457  // strError = "Not enough support";
1458  // return false;
1459  // }
1460  // }
1461 
1462  //can only pay out 10% of the possible coins (min value of coins)
1464  strError = "Proposal " + strProposalName + ": Payment more than max";
1465  return false;
1466  }
1467 
1468  CBlockIndex* pindexPrev = chainActive.Tip();
1469  if (pindexPrev == NULL) {
1470  strError = "Proposal " + strProposalName + ": Tip is NULL";
1471  return true;
1472  }
1473 
1474  // Calculate maximum block this proposal will be valid, which is start of proposal + (number of payments * cycle)
1475  int nProposalEnd = GetBlockStart() + (GetBudgetPaymentCycleBlocks() * GetTotalPaymentCount());
1476 
1477  // if (GetBlockEnd() < pindexPrev->nHeight - GetBudgetPaymentCycleBlocks() / 2) {
1478  if(nProposalEnd < pindexPrev->nHeight){
1479  strError = "Proposal " + strProposalName + ": Invalid nBlockEnd (" + std::to_string(nProposalEnd) + ") < current height (" + std::to_string(pindexPrev->nHeight) + ")";
1480  return false;
1481  }
1482 
1483  return true;
1484 }
1485 
1486 bool CBudgetProposal::AddOrUpdateVote(CBudgetVote& vote, std::string& strError)
1487 {
1488  std::string strAction = "New vote inserted:";
1489  LOCK(cs);
1490 
1491  uint256 hash = vote.vin.prevout.GetHash();
1492 
1493  if (mapVotes.count(hash)) {
1494  if (mapVotes[hash].nTime > vote.nTime) {
1495  strError = strprintf("new vote older than existing vote - %s\n", vote.GetHash().ToString());
1496  LogPrint(BCLog::MNBUDGET, "CBudgetProposal::AddOrUpdateVote - %s\n", strError);
1497  return false;
1498  }
1499  if (vote.nTime - mapVotes[hash].nTime < BUDGET_VOTE_UPDATE_MIN) {
1500  strError = strprintf("time between votes is too soon - %s - %lli sec < %lli sec\n", vote.GetHash().ToString(), vote.nTime - mapVotes[hash].nTime,BUDGET_VOTE_UPDATE_MIN);
1501  LogPrint(BCLog::MNBUDGET, "CBudgetProposal::AddOrUpdateVote - %s\n", strError);
1502  return false;
1503  }
1504  strAction = "Existing vote updated:";
1505  }
1506 
1507  if (vote.nTime > GetTime() + (60 * 60)) {
1508  strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() + (60 * 60));
1509  LogPrint(BCLog::MNBUDGET, "CBudgetProposal::AddOrUpdateVote - %s\n", strError);
1510  return false;
1511  }
1512 
1513  mapVotes[hash] = vote;
1514  LogPrint(BCLog::MNBUDGET, "CBudgetProposal::AddOrUpdateVote - %s %s\n", strAction.c_str(), vote.GetHash().ToString().c_str());
1515 
1516  return true;
1517 }
1518 
1519 // If masternode voted for a proposal, but is now invalid -- remove the vote
1520 void CBudgetProposal::CleanAndRemove(bool fSignatureCheck)
1521 {
1522  std::map<uint256, CBudgetVote>::iterator it = mapVotes.begin();
1523 
1524  while (it != mapVotes.end()) {
1525  (*it).second.fValid = (*it).second.SignatureValid(fSignatureCheck);
1526  ++it;
1527  }
1528 }
1529 
1531 {
1532  int yeas = 0;
1533  int nays = 0;
1534 
1535  std::map<uint256, CBudgetVote>::iterator it = mapVotes.begin();
1536 
1537  while (it != mapVotes.end()) {
1538  if ((*it).second.nVote == VOTE_YES) yeas++;
1539  if ((*it).second.nVote == VOTE_NO) nays++;
1540  ++it;
1541  }
1542 
1543  if (yeas + nays == 0) return 0.0f;
1544 
1545  return ((double)(yeas) / (double)(yeas + nays));
1546 }
1547 
1549 {
1550  int ret = 0;
1551 
1552  std::map<uint256, CBudgetVote>::iterator it = mapVotes.begin();
1553  while (it != mapVotes.end()) {
1554  if ((*it).second.nVote == VOTE_YES && (*it).second.fValid) ret++;
1555  ++it;
1556  }
1557 
1558  return ret;
1559 }
1560 
1562 {
1563  int ret = 0;
1564 
1565  std::map<uint256, CBudgetVote>::iterator it = mapVotes.begin();
1566  while (it != mapVotes.end()) {
1567  if ((*it).second.nVote == VOTE_NO && (*it).second.fValid) ret++;
1568  ++it;
1569  }
1570 
1571  return ret;
1572 }
1573 
1575 {
1576  int ret = 0;
1577 
1578  std::map<uint256, CBudgetVote>::iterator it = mapVotes.begin();
1579  while (it != mapVotes.end()) {
1580  if ((*it).second.nVote == VOTE_ABSTAIN && (*it).second.fValid) ret++;
1581  ++it;
1582  }
1583 
1584  return ret;
1585 }
1586 
1588 {
1589  //end block is half way through the next cycle (so the proposal will be removed much after the payment is sent)
1590 
1592 }
1593 
1595 {
1596  CBlockIndex* pindexPrev = chainActive.Tip();
1597  if (pindexPrev == NULL) return -1;
1598 
1599  if (pindexPrev->nHeight >= GetBlockEndCycle()) return -1;
1600 
1601  return pindexPrev->nHeight - pindexPrev->nHeight % GetBudgetPaymentCycleBlocks();
1602 }
1603 
1605 {
1606  // XX42: right now single payment proposals have nBlockEnd have a cycle too early!
1607  // switch back if it break something else
1608  //end block is half way through the next cycle (so the proposal will be removed much after the payment is sent)
1609  // return nBlockEnd - GetBudgetPaymentCycleBlocks() / 2;
1610 
1611  // End block is half way through the next cycle (so the proposal will be removed much after the payment is sent)
1612  return nBlockEnd;
1613 
1614 }
1615 
1617 {
1619 }
1620 
1622 {
1623  // If this budget starts in the future, this value will be wrong
1624  int nPayments = (GetBlockEndCycle() - GetBlockCurrentCycle()) / GetBudgetPaymentCycleBlocks() - 1;
1625  // Take the lowest value
1626  return std::min(nPayments, GetTotalPaymentCount());
1627 }
1628 
1629 CBudgetProposalBroadcast::CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn)
1630 {
1631  strProposalName = strProposalNameIn;
1632  strURL = strURLIn;
1633 
1634  nBlockStart = nBlockStartIn;
1635 
1636  int nCycleStart = nBlockStart - nBlockStart % GetBudgetPaymentCycleBlocks();
1637 
1638  // XX42: right now single payment proposals have nBlockEnd have a cycle too early!
1639  // switch back if it break something else
1640  //calculate the end of the cycle for this vote, add half a cycle (vote will be deleted after that block)
1641  // nBlockEnd = nCycleStart + GetBudgetPaymentCycleBlocks() * nPaymentCount + GetBudgetPaymentCycleBlocks() / 2;
1642 
1643  // Calculate the end of the cycle for this vote, vote will be deleted after next cycle
1644  nBlockEnd = nCycleStart + (GetBudgetPaymentCycleBlocks() + 1) * nPaymentCount;
1645 
1646  address = addressIn;
1647  nAmount = nAmountIn;
1648 
1649  nFeeTXHash = nFeeTXHashIn;
1650 }
1651 
1653 {
1655  RelayInv(inv);
1656 }
1657 
1659 {
1660  vin = CTxIn();
1661  nProposalHash = 0;
1662  nVote = VOTE_ABSTAIN;
1663  nTime = 0;
1664  fValid = true;
1665  fSynced = false;
1666 }
1667 
1668 CBudgetVote::CBudgetVote(CTxIn vinIn, uint256 nProposalHashIn, int nVoteIn)
1669 {
1670  vin = vinIn;
1671  nProposalHash = nProposalHashIn;
1672  nVote = nVoteIn;
1673  nTime = GetAdjustedTime();
1674  fValid = true;
1675  fSynced = false;
1676 }
1677 
1679 {
1680  CInv inv(MSG_BUDGET_VOTE, GetHash());
1681  RelayInv(inv);
1682 }
1683 
1684 bool CBudgetVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
1685 {
1686  std::string strError = "";
1687  //std::string strMessage = vin.prevout.ToStringShort() + nProposalHash.ToString() + std::to_string(nVote) + std::to_string(nTime);
1688 
1689  CPubKey pubKeyCollateralAddress;
1690  CKey keyCollateralAddress;
1691 
1693  std::string strMessage = HEX_STR(ser);
1694 
1695  if (!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
1696  LogPrint(BCLog::MNBUDGET,"CBudgetVote::Sign - Error upon calling SignMessage");
1697  return false;
1698  }
1699 
1700  if (!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
1701  LogPrint(BCLog::MNBUDGET,"CBudgetVote::Sign - Error upon calling VerifyMessage: %s", strError);
1702  return false;
1703  }
1704 
1705  return true;
1706 }
1707 
1708 bool CBudgetVote::SignatureValid(bool fSignatureCheck)
1709 {
1710  std::string strError = "";
1712  std::string strMessage = HEX_STR(ser);
1713 
1714  CMasternode* pmn = mnodeman.Find(vin);
1715 
1716  if (pmn == NULL) {
1717  LogPrint(BCLog::MNBUDGET,"CBudgetVote::SignatureValid() - Unknown Masternode - %s\n", vin.prevout.hash.ToString());
1718  return false;
1719  }
1720 
1721  if (!fSignatureCheck) return true;
1722 
1723  if (!CMessageSigner::VerifyMessage(pmn->pubKeyMasternode, vchSig, strMessage, strError)) {
1724  LogPrint(BCLog::MNBUDGET,"CBudgetVote::SignatureValid() - Verify message failed, error: %s\n", strError);
1725  return false;
1726  }
1727 
1728  return true;
1729 }
1730 
1732 {
1733  strBudgetName = "";
1734  nBlockStart = 0;
1735  vecBudgetPayments.clear();
1736  mapVotes.clear();
1737  nFeeTXHash = 0;
1738  nTime = 0;
1739  fValid = true;
1740  fAutoChecked = false;
1741 }
1742 
1744 {
1745  strBudgetName = other.strBudgetName;
1746  nBlockStart = other.nBlockStart;
1748  mapVotes = other.mapVotes;
1749  nFeeTXHash = other.nFeeTXHash;
1750  nTime = other.nTime;
1751  fValid = true;
1752  fAutoChecked = false;
1753 }
1754 
1756 {
1757  LOCK(cs);
1758 
1759  uint256 hash = vote.vin.prevout.GetHash();
1760  std::string strAction = "New vote inserted:";
1761 
1762  if (mapVotes.count(hash)) {
1763  if (mapVotes[hash].nTime > vote.nTime) {
1764  strError = strprintf("new vote older than existing vote - %s\n", vote.GetHash().ToString());
1765  LogPrint(BCLog::MNBUDGET, "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
1766  return false;
1767  }
1768  if (vote.nTime - mapVotes[hash].nTime < BUDGET_VOTE_UPDATE_MIN) {
1769  strError = strprintf("time between votes is too soon - %s - %lli sec < %lli sec\n", vote.GetHash().ToString(), vote.nTime - mapVotes[hash].nTime,BUDGET_VOTE_UPDATE_MIN);
1770  LogPrint(BCLog::MNBUDGET, "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
1771  return false;
1772  }
1773  strAction = "Existing vote updated:";
1774  }
1775 
1776  if (vote.nTime > GetTime() + (60 * 60)) {
1777  strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() + (60 * 60));
1778  LogPrint(BCLog::MNBUDGET, "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
1779  return false;
1780  }
1781 
1782  mapVotes[hash] = vote;
1783  LogPrint(BCLog::MNBUDGET, "CFinalizedBudget::AddOrUpdateVote - %s %s\n", strAction.c_str(), vote.GetHash().ToString().c_str());
1784  return true;
1785 }
1786 
1787 //evaluate if we should vote for this. Masternode only
1789 {
1790  LOCK(cs);
1791 
1792  CBlockIndex* pindexPrev = chainActive.Tip();
1793  if (!pindexPrev) return;
1794 
1795  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - %lli - %d\n", pindexPrev->nHeight, fAutoChecked);
1796 
1797  if (!fMasterNode || fAutoChecked) return;
1798 
1799  //do this 1 in 4 blocks -- spread out the voting activity on mainnet
1800  // -- this function is only called every fourteenth block, so this is really 1 in 56 blocks
1801  if (Params().NetworkID() == CBaseChainParams::MAIN && secp256k1_rand32() % 4 != 0) {
1802  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - waiting\n");
1803  return;
1804  }
1805 
1806  fAutoChecked = true; //we only need to check this once
1807 
1808 
1809  if (strBudgetMode == "auto") //only vote for exact matches
1810  {
1811  std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget();
1812 
1813 
1814  for (unsigned int i = 0; i < vecBudgetPayments.size(); i++) {
1815  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vecBudgetPayments[i].nProposalHash.ToString());
1816  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - Payee %d %s\n", i, vecBudgetPayments[i].payee.ToString());
1817  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vecBudgetPayments[i].nAmount);
1818  }
1819 
1820  for (unsigned int i = 0; i < vBudgetProposals.size(); i++) {
1821  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vBudgetProposals[i]->GetHash().ToString());
1822  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - Payee %d %s\n", i, vBudgetProposals[i]->GetPayee().ToString());
1823  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vBudgetProposals[i]->GetAmount());
1824  }
1825 
1826  if (vBudgetProposals.size() == 0) {
1827  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - Can't get Budget, aborting\n");
1828  return;
1829  }
1830 
1831  if (vBudgetProposals.size() != vecBudgetPayments.size()) {
1832  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - Budget length doesn't match. vBudgetProposals.size()=%ld != vecBudgetPayments.size()=%ld\n",
1833  vBudgetProposals.size(), vecBudgetPayments.size());
1834  return;
1835  }
1836 
1837 
1838  for (unsigned int i = 0; i < vecBudgetPayments.size(); i++) {
1839  if (i > vBudgetProposals.size() - 1) {
1840  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - Proposal size mismatch, i=%d > (vBudgetProposals.size() - 1)=%d\n", i, vBudgetProposals.size() - 1);
1841  return;
1842  }
1843 
1844  if (vecBudgetPayments[i].nProposalHash != vBudgetProposals[i]->GetHash()) {
1845  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - item #%d doesn't match %s %s\n", i, vecBudgetPayments[i].nProposalHash.ToString(), vBudgetProposals[i]->GetHash().ToString());
1846  return;
1847  }
1848 
1849  // if(vecBudgetPayments[i].payee != vBudgetProposals[i]->GetPayee()){ -- triggered with false positive
1850  if (vecBudgetPayments[i].payee.ToString() != vBudgetProposals[i]->GetPayee().ToString()) {
1851  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - item #%d payee doesn't match %s %s\n", i, vecBudgetPayments[i].payee.ToString(), vBudgetProposals[i]->GetPayee().ToString());
1852  return;
1853  }
1854 
1855  if (vecBudgetPayments[i].nAmount != vBudgetProposals[i]->GetAmount()) {
1856  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - item #%d payee doesn't match %lli %lli\n", i, vecBudgetPayments[i].nAmount, vBudgetProposals[i]->GetAmount());
1857  return;
1858  }
1859  }
1860 
1861  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::AutoCheck - Finalized Budget Matches! Submitting Vote.\n");
1862  SubmitVote();
1863  }
1864 }
1865 // If masternode voted for a proposal, but is now invalid -- remove the vote
1866 void CFinalizedBudget::CleanAndRemove(bool fSignatureCheck)
1867 {
1868  std::map<uint256, CFinalizedBudgetVote>::iterator it = mapVotes.begin();
1869 
1870  while (it != mapVotes.end()) {
1871  (*it).second.fValid = (*it).second.SignatureValid(fSignatureCheck);
1872  ++it;
1873  }
1874 }
1875 
1876 
1878 {
1879  CAmount ret = 0;
1880 
1881  for (unsigned int i = 0; i < vecBudgetPayments.size(); i++) {
1882  ret += vecBudgetPayments[i].nAmount;
1883  }
1884 
1885  return ret;
1886 }
1887 
1889 {
1890  LOCK(cs);
1891  std::string ret = "";
1892 
1893  for (CTxBudgetPayment& budgetPayment : vecBudgetPayments) {
1894  CBudgetProposal* pbudgetProposal = budget.FindProposal(budgetPayment.nProposalHash);
1895 
1896  std::string token = budgetPayment.nProposalHash.ToString();
1897 
1898  if (pbudgetProposal) token = pbudgetProposal->GetName();
1899  if (ret == "") {
1900  ret = token;
1901  } else {
1902  ret += "," + token;
1903  }
1904  }
1905  return ret;
1906 }
1907 
1909 {
1910  std::string retBadHashes = "";
1911  std::string retBadPayeeOrAmount = "";
1912 
1913  for (int nBlockHeight = GetBlockStart(); nBlockHeight <= GetBlockEnd(); nBlockHeight++) {
1914  CTxBudgetPayment budgetPayment;
1915  if (!GetBudgetPaymentByBlock(nBlockHeight, budgetPayment)) {
1916  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld\n", nBlockHeight);
1917  continue;
1918  }
1919 
1920  CBudgetProposal* pbudgetProposal = budget.FindProposal(budgetPayment.nProposalHash);
1921  if (!pbudgetProposal) {
1922  if (retBadHashes == "") {
1923  retBadHashes = "Unknown proposal hash! Check this proposal before voting" + budgetPayment.nProposalHash.ToString();
1924  } else {
1925  retBadHashes += "," + budgetPayment.nProposalHash.ToString();
1926  }
1927  } else {
1928  if (pbudgetProposal->GetPayee() != budgetPayment.payee || pbudgetProposal->GetAmount() != budgetPayment.nAmount) {
1929  if (retBadPayeeOrAmount == "") {
1930  retBadPayeeOrAmount = "Budget payee/nAmount doesn't match our proposal! " + budgetPayment.nProposalHash.ToString();
1931  } else {
1932  retBadPayeeOrAmount += "," + budgetPayment.nProposalHash.ToString();
1933  }
1934  }
1935  }
1936  }
1937 
1938  if (retBadHashes == "" && retBadPayeeOrAmount == "") return "OK";
1939 
1940  return retBadHashes + retBadPayeeOrAmount;
1941 }
1942 
1943 bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral)
1944 {
1945  // Must be the correct block for payment to happen (once a month)
1947  strError = "Invalid BlockStart";
1948  return false;
1949  }
1950 
1951  // The following 2 checks check the same (basically if vecBudgetPayments.size() > 100)
1952  if (GetBlockEnd() - nBlockStart > 100) {
1953  strError = "Invalid BlockEnd";
1954  return false;
1955  }
1956  if ((int)vecBudgetPayments.size() > 100) {
1957  strError = "Invalid budget payments count (too many)";
1958  return false;
1959  }
1960  if (strBudgetName == "") {
1961  strError = "Invalid Budget Name";
1962  return false;
1963  }
1964  if (nBlockStart == 0) {
1965  strError = "Budget " + strBudgetName + " Invalid BlockStart == 0";
1966  return false;
1967  }
1968  if (nFeeTXHash.IsNull()) {
1969  strError = "Budget " + strBudgetName + " Invalid FeeTx == 0";
1970  return false;
1971  }
1972 
1973  // Can only pay out 10% of the possible coins (min value of coins)
1975  strError = "Budget " + strBudgetName + " Invalid Payout (more than max)";
1976  return false;
1977  }
1978 
1979  std::string strError2 = "";
1980  if (fCheckCollateral) {
1981  int nConf = 0;
1982  if (!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)) {
1983  {
1984  strError = "Budget " + strBudgetName + " Invalid Collateral : " + strError2;
1985  return false;
1986  }
1987  }
1988  }
1989 
1990  CBlockIndex* pindexPrev = chainActive.Tip();
1991  if (pindexPrev == NULL) return true;
1992 
1993  return true;
1994 }
1995 
1996 bool CFinalizedBudget::IsTransactionValid(const CTransaction& txNew, int nBlockHeight)
1997 {
1998  int nCurrentBudgetPayment = nBlockHeight - GetBlockStart();
1999  if (nCurrentBudgetPayment < 0) {
2000  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d\n", nBlockHeight, GetBlockStart());
2001  return false;
2002  }
2003 
2004  if (nCurrentBudgetPayment > (int)vecBudgetPayments.size() - 1) {
2005  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d\n", nCurrentBudgetPayment + 1, (int)vecBudgetPayments.size());
2006  return false;
2007  }
2008 
2009  bool found = false;
2010  for (CTxOut out : txNew.vout) {
2011  if (vecBudgetPayments[nCurrentBudgetPayment].payee == out.scriptPubKey && vecBudgetPayments[nCurrentBudgetPayment].nAmount == out.nValue) {
2012  found = true;
2013  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::IsTransactionValid - Found valid Budget Payment of %d for %d\n",
2014  vecBudgetPayments[nCurrentBudgetPayment].nAmount, vecBudgetPayments[nCurrentBudgetPayment].nProposalHash.GetHex());
2015  }
2016  }
2017 
2018  if (!found) {
2019  CTxDestination address1;
2020  ExtractDestination(vecBudgetPayments[nCurrentBudgetPayment].payee, address1);
2021  CBitcoinAddress address2(address1);
2022 
2023  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::IsTransactionValid - Missing required payment - %s: %d c: %d\n",
2024  address2.ToString(), vecBudgetPayments[nCurrentBudgetPayment].nAmount, nCurrentBudgetPayment);
2025  }
2026 
2027  return found;
2028 }
2029 
2031 {
2032  std::string strError = "";
2033  CPubKey pubKeyMasternode;
2034  CKey keyMasternode;
2035 
2036  if (!CMessageSigner::GetKeysFromSecret(strMasterNodePrivKey, keyMasternode, pubKeyMasternode)) {
2037  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::SubmitVote - Error upon calling SetKey\n");
2038  return;
2039  }
2040 
2042  if (!vote.Sign(keyMasternode, pubKeyMasternode)) {
2043  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::SubmitVote - Failure to sign.");
2044  return;
2045  }
2046 
2047  if (budget.UpdateFinalizedBudget(vote, NULL, strError)) {
2048  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::SubmitVote - new finalized budget vote - %s\n", vote.GetHash().ToString());
2049 
2050  budget.mapSeenFinalizedBudgetVotes.insert(std::make_pair(vote.GetHash(), vote));
2051  vote.Relay();
2052  } else {
2053  LogPrint(BCLog::MNBUDGET,"CFinalizedBudget::SubmitVote : Error submitting vote - %s\n", strError);
2054  }
2055 }
2056 
2058 {
2059  strBudgetName = "";
2060  nBlockStart = 0;
2061  vecBudgetPayments.clear();
2062  mapVotes.clear();
2063  vchSig.clear();
2064  nFeeTXHash = 0;
2065 }
2066 
2068 {
2069  strBudgetName = other.strBudgetName;
2070  nBlockStart = other.nBlockStart;
2071  for (CTxBudgetPayment out : other.vecBudgetPayments)
2072  vecBudgetPayments.push_back(out);
2073  mapVotes = other.mapVotes;
2074  nFeeTXHash = other.nFeeTXHash;
2075 }
2076 
2077 CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn)
2078 {
2079  strBudgetName = strBudgetNameIn;
2080  nBlockStart = nBlockStartIn;
2081  for (CTxBudgetPayment out : vecBudgetPaymentsIn)
2082  vecBudgetPayments.push_back(out);
2083  mapVotes.clear();
2084  nFeeTXHash = nFeeTXHashIn;
2085 }
2086 
2088 {
2090  RelayInv(inv);
2091 }
2092 
2094 {
2095  vin = CTxIn();
2096  nBudgetHash = 0;
2097  nTime = 0;
2098  vchSig.clear();
2099  fValid = true;
2100  fSynced = false;
2101 }
2102 
2104 {
2105  vin = vinIn;
2106  nBudgetHash = nBudgetHashIn;
2107  nTime = GetAdjustedTime();
2108  vchSig.clear();
2109  fValid = true;
2110  fSynced = false;
2111 }
2112 
2114 {
2116  RelayInv(inv);
2117 }
2118 
2119 bool CFinalizedBudgetVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
2120 {
2121  std::string strError = "";
2122  //std::string strMessage = vin.prevout.ToStringShort() + nBudgetHash.ToString() + std::to_string(nTime);
2123 
2124  CPubKey pubKeyCollateralAddress;
2125  CKey keyCollateralAddress;
2126 
2127  HEX_DATA_STREAM_PROTOCOL(PROTOCOL_VERSION) << vin.prevout << nBudgetHash << nTime;
2128  std::string strMessage = HEX_STR(ser);
2129 
2130  if (!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
2131  LogPrint(BCLog::MNBUDGET,"CFinalizedBudgetVote::Sign - Error upon calling SignMessage");
2132  return false;
2133  }
2134 
2135  if (!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
2136  LogPrint(BCLog::MNBUDGET,"CFinalizedBudgetVote::Sign - Error upon calling VerifyMessage: %s", strError);
2137  return false;
2138  }
2139 
2140  return true;
2141 }
2142 
2143 bool CFinalizedBudgetVote::SignatureValid(bool fSignatureCheck)
2144 {
2145  std::string strError;
2146  HEX_DATA_STREAM_PROTOCOL(PROTOCOL_VERSION) << vin.prevout << nBudgetHash << nTime;
2147  std::string strMessage = HEX_STR(ser);
2148 
2149  CMasternode* pmn = mnodeman.Find(vin);
2150 
2151  if (pmn == NULL) {
2152  LogPrint(BCLog::MNBUDGET,"CFinalizedBudgetVote::SignatureValid() - Unknown Masternode %s\n", strMessage);
2153  return false;
2154  }
2155 
2156  if (!fSignatureCheck) return true;
2157 
2158  if (!CMessageSigner::VerifyMessage(pmn->pubKeyMasternode, vchSig, strMessage, strError)) {
2159  LogPrint(BCLog::MNBUDGET,"CFinalizedBudgetVote::SignatureValid() - Verify message failed %s: %s\n", strMessage, strError);
2160  return false;
2161  }
2162 
2163  return true;
2164 }
2165 
2166 std::string CBudgetManager::ToString() const
2167 {
2168  std::ostringstream info;
2169 
2170  info << "Proposals: " << (int)mapProposals.size() << ", Budgets: " << (int)mapFinalizedBudgets.size() << ", Seen Budgets: " << (int)mapSeenMasternodeBudgetProposals.size() << ", Seen Budget Votes: " << (int)mapSeenMasternodeBudgetVotes.size() << ", Seen Final Budgets: " << (int)mapSeenFinalizedBudgets.size() << ", Seen Final Budget Votes: " << (int)mapSeenFinalizedBudgetVotes.size();
2171 
2172  return info.str();
2173 }
CNode::HasFulfilledRequest
bool HasFulfilledRequest(std::string strRequest)
Definition: net.h:685
CBudgetManager::PropExists
bool PropExists(uint256 nHash)
Definition: masternode-budget.cpp:1169
CTxIn
An input of a transaction.
Definition: transaction.h:83
CBudgetProposal::nFeeTXHash
uint256 nFeeTXHash
Definition: masternode-budget.h:472
UINT256_ZERO
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:129
CBudgetManager::mapSeenMasternodeBudgetProposals
std::map< uint256, CBudgetProposalBroadcast > mapSeenMasternodeBudgetProposals
Definition: masternode-budget.h:187
vNodes
std::vector< CNode * > vNodes
Definition: net.cpp:85
CBudgetManager::GetFinalizedBudgets
std::vector< CFinalizedBudget * > GetFinalizedBudgets()
Definition: masternode-budget.cpp:780
CMasternodeMan::AskForMN
void AskForMN(CNode *pnode, CTxIn &vin)
Ask (source) node for mnb.
Definition: masternodeman.cpp:223
CBudgetManager::FindFinalizedBudget
CFinalizedBudget * FindFinalizedBudget(uint256 nHash)
Definition: masternode-budget.cpp:554
CBudgetVote::Sign
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
Definition: masternode-budget.cpp:1684
MASTERNODE_SYNC_BUDGET
#define MASTERNODE_SYNC_BUDGET
Definition: masternode-sync.h:13
CFinalizedBudget::AddOrUpdateVote
bool AddOrUpdateVote(CFinalizedBudgetVote &vote, std::string &strError)
Definition: masternode-budget.cpp:1755
CMasternodeMan::CountEnabled
int CountEnabled(int protocolVersion=-1)
Definition: masternodeman.cpp:379
CScript::IsNormalPaymentScript
bool IsNormalPaymentScript() const
Definition: script.cpp:211
CFinalizedBudgetVote::SignatureValid
bool SignatureValid(bool fSignatureCheck)
Definition: masternode-budget.cpp:2143
CAutoFile::read
CAutoFile & read(char *pch, size_t nSize)
Definition: streams.h:367
CBudgetManager::ResetSync
void ResetSync()
Definition: masternode-budget.cpp:1176
GetTime
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:19
activeMasternode
CActiveMasternode activeMasternode
Keep track of the active Masternode.
Definition: masternodeman.cpp:24
CBudgetManager::mapOrphanMasternodeBudgetVotes
std::map< uint256, CBudgetVote > mapOrphanMasternodeBudgetVotes
Definition: masternode-budget.h:189
CNode::GetId
NodeId GetId() const
Definition: net.h:423
CMasternodeSync::RequestedMasternodeAssets
int RequestedMasternodeAssets
Definition: masternode-sync.h:57
CBudgetDB::ReadResult
ReadResult
Definition: masternode-budget.h:153
CBudgetManager::mapSeenFinalizedBudgets
std::map< uint256, CFinalizedBudgetBroadcast > mapSeenFinalizedBudgets
Definition: masternode-budget.h:190
CBudgetProposal::nBlockEnd
int nBlockEnd
Definition: masternode-budget.h:468
FLATDATA
#define FLATDATA(obj)
Definition: serialize.h:365
fs.h
CFinalizedBudget::nBlockStart
int nBlockStart
Definition: masternode-budget.h:316
sortProposalsByVotes::operator()
bool operator()(const std::pair< CBudgetProposal *, int > &left, const std::pair< CBudgetProposal *, int > &right)
Definition: masternode-budget.cpp:692
CWallet::CommitTransaction
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, std::string strCommand=NetMsgType::TX)
Call after CreateTransaction unless you want to abort.
Definition: wallet.cpp:4458
CFinalizedBudget::vecBudgetPayments
std::vector< CTxBudgetPayment > vecBudgetPayments
Definition: masternode-budget.h:317
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:13
CDataStream::begin
const_iterator begin() const
Definition: streams.h:116
MSG_BUDGET_PROPOSAL
@ MSG_BUDGET_PROPOSAL
Definition: protocol.h:398
CBudgetProposal::GetAmount
CAmount GetAmount()
Definition: masternode-budget.h:511
VOTE_YES
#define VOTE_YES
Definition: masternode-budget.h:30
chainActive
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:70
CBudgetDB::IncorrectFormat
@ IncorrectFormat
Definition: masternode-budget.h:160
COutPoint::hash
uint256 hash
Definition: transaction.h:39
CBudgetManager::mapSeenMasternodeBudgetVotes
std::map< uint256, CBudgetVote > mapSeenMasternodeBudgetVotes
Definition: masternode-budget.h:188
CBudgetManager::GetAllProposals
std::vector< CBudgetProposal * > GetAllProposals()
Definition: masternode-budget.cpp:669
CBitcoinAddress
base58-encoded PRCY addresses.
Definition: base58.h:109
CMasternodeMan::Find
CMasternode * Find(const CScript &payee)
Find an entry.
Definition: masternodeman.cpp:440
NetMsgType::FINALBUDGET
const char * FINALBUDGET
The finalbudget message is used to broadcast or relay finalized budget metadata to connected peers.
Definition: protocol.cpp:57
CActiveMasternode::vin
CTxIn vin
Definition: activemasternode.h:44
CMasternodeSync::IsBlockchainSynced
bool IsBlockchainSynced()
Definition: masternode-sync.cpp:32
CFinalizedBudgetVote::fValid
bool fValid
Definition: masternode-budget.h:109
CFinalizedBudgetVote::vchSig
std::vector< unsigned char > vchSig
Definition: masternode-budget.h:114
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:181
CNode
Information about a peer.
Definition: net.h:306
CReserveKey
A key allocated from the key pool.
Definition: wallet.h:679
CBudgetProposal::GetTotalPaymentCount
int GetTotalPaymentCount()
Definition: masternode-budget.cpp:1616
CTransaction::nLockTime
const uint32_t nLockTime
Definition: transaction.h:287
CBudgetProposal::strURL
std::string strURL
Definition: masternode-budget.h:466
ToByteVector
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:32
CBudgetDB::IncorrectHash
@ IncorrectHash
Definition: masternode-budget.h:157
CFinalizedBudget::fValid
bool fValid
Definition: masternode-budget.h:314
CBudgetProposal::GetRatio
double GetRatio()
Definition: masternode-budget.cpp:1530
masternode-sync.h
CBudgetProposal::address
CScript address
Definition: masternode-budget.h:470
CNode::PushInventory
void PushInventory(const CInv &inv)
Definition: net.h:494
CBudgetProposal::cs
RecursiveMutex cs
Definition: masternode-budget.h:455
AnnotatedMixin< std::recursive_mutex >
CBudgetVote::CBudgetVote
CBudgetVote()
Definition: masternode-budget.cpp:1658
CBudgetDB::strMagicMessage
std::string strMagicMessage
Definition: masternode-budget.h:150
cs_vNodes
RecursiveMutex cs_vNodes
Definition: net.cpp:86
TRY_LOCK
#define TRY_LOCK(cs, name)
Definition: sync.h:186
vecImmatureFinalizedBudgets
std::vector< CFinalizedBudgetBroadcast > vecImmatureFinalizedBudgets
Definition: masternode-budget.cpp:24
CBudgetProposal::GetAbstains
int GetAbstains()
Definition: masternode-budget.cpp:1574
CScript::IsPayToScriptHash
bool IsPayToScriptHash() const
Definition: script.cpp:235
CInv
inv message data
Definition: protocol.h:358
CBudgetVote::fSynced
bool fSynced
Definition: masternode-budget.h:57
CBudgetManager::UpdateProposal
bool UpdateProposal(CBudgetVote &vote, CNode *pfrom, std::string &strError)
Definition: masternode-budget.cpp:1320
masternodeman.h
CBudgetVote::Relay
void Relay()
Definition: masternode-budget.cpp:1678
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
askedForSourceProposalOrBudget
std::map< uint256, int64_t > askedForSourceProposalOrBudget
Definition: masternode-budget.cpp:22
CFinalizedBudget::GetProposals
std::string GetProposals()
Definition: masternode-budget.cpp:1888
CBudgetProposal::GetRemainingPaymentCount
int GetRemainingPaymentCount()
Definition: masternode-budget.cpp:1621
fMasterNode
bool fMasterNode
Definition: util.cpp:97
CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast
CFinalizedBudgetBroadcast()
Definition: masternode-budget.cpp:2057
HEX_DATA_STREAM
#define HEX_DATA_STREAM
Definition: streams.h:25
CFinalizedBudget::strBudgetName
std::string strBudgetName
Definition: masternode-budget.h:315
CBudgetManager::ToString
std::string ToString() const
Definition: masternode-budget.cpp:2166
CNode::PushMessage
void PushMessage(const char *pszCommand)
Definition: net.h:518
CTxBudgetPayment::payee
CScript payee
Definition: masternode-budget.h:280
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:269
CFinalizedBudgetVote::Relay
void Relay()
Definition: masternode-budget.cpp:2113
CBudgetManager::mapProposals
std::map< uint256, CBudgetProposal > mapProposals
Definition: masternode-budget.h:184
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
CBudgetManager::UpdateFinalizedBudget
bool UpdateFinalizedBudget(CFinalizedBudgetVote &vote, CNode *pfrom, std::string &strError)
Definition: masternode-budget.cpp:1347
CBudgetVote
Definition: masternode-budget.h:53
masternodeSync
CMasternodeSync masternodeSync
Definition: masternode-sync.cpp:19
NetMsgType::BUDGETVOTESYNC
const char * BUDGETVOTESYNC
The budgetvotesync message is used to request budget vote data from connected peers.
Definition: protocol.cpp:56
CBlockIndex::nTime
unsigned int nTime
Definition: chain.h:228
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
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
CBudgetVote::GetHash
uint256 GetHash()
Definition: masternode-budget.h:79
CNode::FulfilledRequest
void FulfilledRequest(std::string strRequest)
Definition: net.h:705
CBudgetManager::cs
RecursiveMutex cs
Definition: masternode-budget.h:181
ActiveProtocol
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
Definition: main.cpp:6844
CWallet::GetBudgetSystemCollateralTX
bool GetBudgetSystemCollateralTX(CTransaction &tx, uint256 hash, bool useIX)
Definition: wallet.cpp:3063
CBudgetProposal::nTime
int64_t nTime
Definition: masternode-budget.h:471
strBudgetMode
std::string strBudgetMode
Definition: util.cpp:109
CBudgetProposal::GetYeas
int GetYeas()
Definition: masternode-budget.cpp:1548
CBudgetManager::IsBudgetPaymentBlock
bool IsBudgetPaymentBlock(int nBlockHeight)
Definition: masternode-budget.cpp:593
CFinalizedBudgetBroadcast::Relay
void Relay()
Definition: masternode-budget.cpp:2087
mnodeman
CMasternodeMan mnodeman
Masternode manager.
Definition: masternodeman.cpp:22
CBudgetDB::IncorrectMagicMessage
@ IncorrectMagicMessage
Definition: masternode-budget.h:158
OP_RETURN
@ OP_RETURN
Definition: script.h:76
CBudgetManager::GetBudget
std::vector< CBudgetProposal * > GetBudget()
Definition: masternode-budget.cpp:701
CBudgetProposal
Definition: masternode-budget.h:451
CBudgetManager::Sync
void Sync(CNode *node, uint256 nProp, bool fPartial=false)
Definition: masternode-budget.cpp:1250
CTxOut
An output of a transaction.
Definition: transaction.h:164
GetTransaction
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock.
Definition: main.cpp:2010
MASTERNODE_SYNC_BUDGET_PROP
#define MASTERNODE_SYNC_BUDGET_PROP
Definition: masternode-sync.h:14
init.h
CBudgetProposalBroadcast::Relay
void Relay()
Definition: masternode-budget.cpp:1652
CTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:286
CBudgetManager::mapFinalizedBudgets
std::map< uint256, CFinalizedBudget > mapFinalizedBudgets
Definition: masternode-budget.h:185
CTxOut::scriptPubKey
CScript scriptPubKey
Definition: transaction.h:168
CBudgetProposal::nBlockStart
int nBlockStart
Definition: masternode-budget.h:467
vecImmatureBudgetProposals
std::vector< CBudgetProposalBroadcast > vecImmatureBudgetProposals
Definition: masternode-budget.cpp:23
CBudgetProposal::AddOrUpdateVote
bool AddOrUpdateVote(CBudgetVote &vote, std::string &strError)
Definition: masternode-budget.cpp:1486
CBudgetVote::SignatureValid
bool SignatureValid(bool fSignatureCheck)
Definition: masternode-budget.cpp:1708
CBudgetManager::IsTransactionValid
bool IsTransactionValid(const CTransaction &txNew, int nBlockHeight)
Definition: masternode-budget.cpp:619
fLiteMode
bool fLiteMode
Definition: util.cpp:100
CFinalizedBudget::nFeeTXHash
uint256 nFeeTXHash
Definition: masternode-budget.h:319
CDataStream::end
const_iterator end() const
Definition: streams.h:118
sortProposalsByVotes
Definition: masternode-budget.cpp:691
RelayInv
void RelayInv(CInv &inv)
Definition: net.cpp:2077
CBaseChainParams::MAIN
@ MAIN
Definition: chainparamsbase.h:19
VOTE_ABSTAIN
#define VOTE_ABSTAIN
Definition: masternode-budget.h:29
CFinalizedBudget::CFinalizedBudget
CFinalizedBudget()
Definition: masternode-budget.cpp:1731
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
CAmount
int64_t CAmount
Amount in PRCY (Can be negative)
Definition: amount.h:17
NetMsgType::FINALBUDGETVOTE
const char * FINALBUDGETVOTE
The finalbudgetvote message is used to broadcast or relay finalized budget votes to connected peers.
Definition: protocol.cpp:58
CFinalizedBudget::GetTotalPayout
CAmount GetTotalPayout()
Definition: masternode-budget.cpp:1877
CFinalizedBudgetVote::Sign
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
Definition: masternode-budget.cpp:2119
CBudgetDB::HashReadError
@ HashReadError
Definition: masternode-budget.h:156
CFinalizedBudget::GetBudgetPaymentByBlock
bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment &payment)
Definition: masternode-budget.h:338
SER_DISK
@ SER_DISK
Definition: serialize.h:160
cs_budget
RecursiveMutex cs_budget
Definition: masternode-budget.cpp:20
CTxBudgetPayment::nProposalHash
uint256 nProposalHash
Definition: masternode-budget.h:279
CAutoFile::IsNull
bool IsNull() const
Return true if the wrapped FILE* is NULL, false otherwise.
Definition: streams.h:355
CBudgetManager::FillBlockPayee
bool FillBlockPayee(CMutableTransaction &txNew, CAmount nFees, bool fProofOfStake)
Definition: masternode-budget.cpp:490
CFinalizedBudgetBroadcast
Definition: masternode-budget.h:399
sortFinalizedBudgetsByVotes
Definition: masternode-budget.cpp:771
CFinalizedBudget::GetBlockEnd
int GetBlockEnd()
Definition: masternode-budget.h:335
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
uint256::GetHash
uint64_t GetHash(const uint256 &salt) const
Definition: uint256.cpp:99
HEX_DATA_STREAM_PROTOCOL
#define HEX_DATA_STREAM_PROTOCOL(protocolVersion)
Definition: streams.h:26
CBudgetManager::FindProposal
CBudgetProposal * FindProposal(const std::string &strProposalName)
Definition: masternode-budget.cpp:562
CBudgetVote::nTime
int64_t nTime
Definition: masternode-budget.h:61
CBudgetManager::SubmitFinalBudget
void SubmitFinalBudget()
Definition: masternode-budget.cpp:125
VOTE_NO
#define VOTE_NO
Definition: masternode-budget.h:31
CFinalizedBudget
Definition: masternode-budget.h:306
CFinalizedBudgetVote
Definition: masternode-budget.h:106
LogPrint
#define LogPrint(category,...)
Definition: logging.h:162
CBudgetManager::mapCollateralTxids
std::map< uint256, uint256 > mapCollateralTxids
Definition: masternode-budget.h:177
CMasternodeSync::AddedBudgetItem
void AddedBudgetItem(uint256 hash)
Definition: masternode-sync.cpp:115
CFinalizedBudget::GetPayeeAndAmount
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript &payee, CAmount &nAmount)
Definition: masternode-budget.h:348
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:363
base_uint::IsNull
bool IsNull() const
Definition: arith_uint256.h:312
ExtractDestination
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: standard.cpp:199
CBudgetDB::CBudgetDB
CBudgetDB()
Definition: masternode-budget.cpp:248
CMasternodeSync::IsSynced
bool IsSynced()
Definition: masternode-sync.cpp:27
CBudgetProposal::GetBlockCurrentCycle
int GetBlockCurrentCycle()
Definition: masternode-budget.cpp:1594
CTxBudgetPayment::nAmount
CAmount nAmount
Definition: masternode-budget.h:281
CAutoFile::fclose
void fclose()
Definition: streams.h:328
CBudgetManager::GetRequiredPaymentsString
std::string GetRequiredPaymentsString(int nBlockHeight)
Definition: masternode-budget.cpp:807
CMasternode::pubKeyMasternode
CPubKey pubKeyMasternode
Definition: masternode.h:130
CBudgetProposal::IsEstablished
bool IsEstablished()
Definition: masternode-budget.h:488
CTxDestination
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:81
CChain::Height
int Height() const
Return the maximal height in the chain.
Definition: chain.h:641
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
NetMsgType::BUDGETPROPOSAL
const char * BUDGETPROPOSAL
The budgetproposal message is used to broadcast or relay budget proposal metadata to connected peers.
Definition: protocol.cpp:54
CBudgetProposal::CBudgetProposal
CBudgetProposal()
Definition: masternode-budget.cpp:1373
CBudgetProposal::SetAllotted
void SetAllotted(CAmount nAllotedIn)
Definition: masternode-budget.h:512
CBudgetVote::vchSig
std::vector< unsigned char > vchSig
Definition: masternode-budget.h:62
CBudgetManager
Definition: masternode-budget.h:172
CFinalizedBudget::AutoCheck
void AutoCheck()
Definition: masternode-budget.cpp:1788
GetTimeMillis
int64_t GetTimeMillis()
Definition: utiltime.cpp:31
CFinalizedBudgetVote::CFinalizedBudgetVote
CFinalizedBudgetVote()
Definition: masternode-budget.cpp:2093
messagesigner.h
CBudgetVote::nProposalHash
uint256 nProposalHash
Definition: masternode-budget.h:59
CMutableTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:388
strprintf
#define strprintf
Definition: tinyformat.h:1056
CMasternode
Definition: masternode.h:107
MSG_BUDGET_FINALIZED
@ MSG_BUDGET_FINALIZED
Definition: protocol.h:399
CFinalizedBudget::GetHash
uint256 GetHash()
Definition: masternode-budget.h:370
CBudgetDB::pathDB
fs::path pathDB
Definition: masternode-budget.h:149
CPubKey
An encapsulated public key.
Definition: pubkey.h:37
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:30
CBudgetManager::ProcessMessage
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
Definition: masternode-budget.cpp:988
CBudgetManager::ClearSeen
void ClearSeen()
Definition: masternode-budget.h:200
CBudgetProposal::IsValid
bool IsValid(std::string &strError, bool fCheckCollateral=true)
Definition: masternode-budget.cpp:1409
CTransaction::ToString
std::string ToString() const
Definition: transaction.cpp:217
CFinalizedBudgetBroadcast::vchSig
std::vector< unsigned char > vchSig
Definition: masternode-budget.h:402
MASTERNODE_SYNC_BUDGET_FIN
#define MASTERNODE_SYNC_BUDGET_FIN
Definition: masternode-sync.h:15
CKey
An encapsulated private key.
Definition: key.h:39
GetBudgetPaymentCycleBlocks
int GetBudgetPaymentCycleBlocks()
Definition: masternode-budget.cpp:28
CTxBudgetPayment
Definition: masternode-budget.h:276
NetMsgType::BUDGETVOTE
const char * BUDGETVOTE
The budgetvote message is used to broadcast or relay budget proposal votes to connected peers.
Definition: protocol.cpp:55
CBudgetManager::AddProposal
bool AddProposal(CBudgetProposal &budgetProposal)
Definition: masternode-budget.cpp:412
main.h
CFinalizedBudget::CleanAndRemove
void CleanAndRemove(bool fSignatureCheck)
Definition: masternode-budget.cpp:1866
LOCK
#define LOCK(cs)
Definition: sync.h:182
CBudgetProposal::nAmount
CAmount nAmount
Definition: masternode-budget.h:469
IsBudgetCollateralValid
bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string &strError, int64_t &nTime, int &nConf)
Definition: masternode-budget.cpp:37
CBudgetDB::Ok
@ Ok
Definition: masternode-budget.h:154
CBudgetProposal::GetNays
int GetNays()
Definition: masternode-budget.cpp:1561
MSG_BUDGET_FINALIZED_VOTE
@ MSG_BUDGET_FINALIZED_VOTE
Definition: protocol.h:400
CWalletTx
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:792
CFinalizedBudgetVote::vin
CTxIn vin
Definition: masternode-budget.h:111
CBudgetProposalBroadcast
Definition: masternode-budget.h:553
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:86
CFinalizedBudget::IsValid
bool IsValid(std::string &strError, bool fCheckCollateral=true)
Definition: masternode-budget.cpp:1943
HEX_STR
#define HEX_STR(a)
Definition: streams.h:27
CBudgetDB::FileError
@ FileError
Definition: masternode-budget.h:155
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:349
CFinalizedBudget::IsTransactionValid
bool IsTransactionValid(const CTransaction &txNew, int nBlockHeight)
Definition: masternode-budget.cpp:1996
masternode.h
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
masternode-budget.h
CFinalizedBudgetVote::nTime
int64_t nTime
Definition: masternode-budget.h:113
CBudgetDB::IncorrectMagicNumber
@ IncorrectMagicNumber
Definition: masternode-budget.h:159
CChain::Contains
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:626
CFinalizedBudget::SubmitVote
void SubmitVote()
Definition: masternode-budget.cpp:2030
NetMsgType::SYNCSTATUSCOUNT
const char * SYNCSTATUSCOUNT
The syncstatuscount message is used to track the layer 2 syncing process.
Definition: protocol.cpp:59
CBudgetManager::AddFinalizedBudget
bool AddFinalizedBudget(CFinalizedBudget &finalizedBudget)
Definition: masternode-budget.cpp:399
CBudgetDB::Write
bool Write(const CBudgetManager &objToSave)
Definition: masternode-budget.cpp:254
CFinalizedBudget::GetStatus
std::string GetStatus()
Definition: masternode-budget.cpp:1908
GetBlockValue
CAmount GetBlockValue(int nHeight)
Definition: main.cpp:2158
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:34
CBudgetVote::fValid
bool fValid
Definition: masternode-budget.h:56
CBudgetProposal::GetBlockEndCycle
int GetBlockEndCycle()
Definition: masternode-budget.cpp:1604
addrman.h
CBudgetProposal::GetBlockStart
int GetBlockStart()
Definition: masternode-budget.h:499
CTransaction::GetHash
const uint256 & GetHash() const
Definition: transaction.h:342
CBudgetManager::MarkSynced
void MarkSynced()
Definition: masternode-budget.cpp:1210
CBudgetProposal::GetHash
uint256 GetHash()
Definition: masternode-budget.h:517
COutPoint::GetHash
uint256 GetHash()
Definition: transaction.cpp:31
CBudgetDB::Read
ReadResult Read(CBudgetManager &objToLoad, bool fDryRun=false)
Definition: masternode-budget.cpp:287
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
BCLog::MNBUDGET
@ MNBUDGET
Definition: logging.h:63
DumpBudgets
void DumpBudgets()
Definition: masternode-budget.cpp:372
CBudgetProposal::GetName
std::string GetName()
Definition: masternode-budget.h:497
CBudgetProposal::mapVotes
std::map< uint256, CBudgetVote > mapVotes
Definition: masternode-budget.h:474
nSubmittedFinalBudget
int nSubmittedFinalBudget
Definition: masternode-budget.cpp:26
CBudgetManager::CheckAndRemove
void CheckAndRemove()
Definition: masternode-budget.cpp:430
CFinalizedBudget::mapVotes
std::map< uint256, CFinalizedBudgetVote > mapVotes
Definition: masternode-budget.h:318
CScript::IsUnspendable
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack.
Definition: script.h:628
CFinalizedBudget::cs
RecursiveMutex cs
Definition: masternode-budget.h:310
budget
CBudgetManager budget
Definition: masternode-budget.cpp:19
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
CBudgetManager::NewBlock
void NewBlock()
Definition: masternode-budget.cpp:876
CBudgetManager::mapSeenFinalizedBudgetVotes
std::map< uint256, CFinalizedBudgetVote > mapSeenFinalizedBudgetVotes
Definition: masternode-budget.h:191
CBudgetProposal::fValid
bool fValid
Definition: masternode-budget.h:459
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:162
MSG_BUDGET_VOTE
@ MSG_BUDGET_VOTE
Definition: protocol.h:397
pwalletMain
CWallet * pwalletMain
Definition: wallet.cpp:49
CBudgetManager::mapOrphanFinalizedBudgetVotes
std::map< uint256, CFinalizedBudgetVote > mapOrphanFinalizedBudgetVotes
Definition: masternode-budget.h:192
CFinalizedBudget::GetVoteCount
int GetVoteCount()
Definition: masternode-budget.h:336
CBudgetManager::Clear
void Clear()
Definition: masternode-budget.h:240
CFinalizedBudgetVote::fSynced
bool fSynced
Definition: masternode-budget.h:110
CBudgetVote::vin
CTxIn vin
Definition: masternode-budget.h:58
GetIXConfirmations
int GetIXConfirmations(uint256 nTXHash)
Definition: main.cpp:1392
util.h
CBudgetVote::nVote
int nVote
Definition: masternode-budget.h:60
CBudgetProposal::GetBlockStartCycle
int GetBlockStartCycle()
Definition: masternode-budget.cpp:1587
CFinalizedBudgetVote::nBudgetHash
uint256 nBudgetHash
Definition: masternode-budget.h:112
CBudgetManager::GetTotalBudget
CAmount GetTotalBudget(int nHeight)
Definition: masternode-budget.cpp:836
CBudgetDB
Save Budget Manager (budget.dat)
Definition: masternode-budget.h:146
CBudgetProposal::CleanAndRemove
void CleanAndRemove(bool fSignatureCheck)
Definition: masternode-budget.cpp:1520
CBudgetManager::CheckOrphanVotes
void CheckOrphanVotes()
Definition: masternode-budget.cpp:98
CFinalizedBudget::nTime
int64_t nTime
Definition: masternode-budget.h:320
error
bool error(const char *fmt, const Args &... args)
Definition: util.h:61
mapBlockIndex
BlockMap mapBlockIndex
Definition: main.cpp:67
CBudgetProposalBroadcast::CBudgetProposalBroadcast
CBudgetProposalBroadcast()
Definition: masternode-budget.h:556
CFinalizedBudget::fAutoChecked
bool fAutoChecked
Definition: masternode-budget.h:311
CFinalizedBudgetVote::GetHash
uint256 GetHash()
Definition: masternode-budget.h:123
CFinalizedBudget::GetBlockStart
int GetBlockStart()
Definition: masternode-budget.h:334
CBudgetProposal::GetPayee
CScript GetPayee()
Definition: masternode-budget.h:501
sortFinalizedBudgetsByVotes::operator()
bool operator()(const std::pair< CFinalizedBudget *, int > &left, const std::pair< CFinalizedBudget *, int > &right)
Definition: masternode-budget.cpp:772
CBudgetProposal::strProposalName
std::string strProposalName
Definition: masternode-budget.h:460
Misbehaving
void Misbehaving(NodeId pnode, int howmuch) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Increase a node's misbehavior score.
Definition: main.cpp:2645
base_uint::ToString
std::string ToString() const
Definition: arith_uint256.cpp:199