Dash Core  0.12.2.1
P2P Digital Currency
governance-object.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "core_io.h"
6 #include "governance.h"
7 #include "governance-classes.h"
8 #include "governance-object.h"
9 #include "governance-vote.h"
10 #include "instantx.h"
11 #include "masternodeman.h"
12 #include "messagesigner.h"
13 #include "util.h"
14 
15 #include <univalue.h>
16 
18 : cs(),
19  nObjectType(GOVERNANCE_OBJECT_UNKNOWN),
20  nHashParent(),
21  nRevision(0),
22  nTime(0),
23  nDeletionTime(0),
24  nCollateralHash(),
25  strData(),
26  vinMasternode(),
27  vchSig(),
28  fCachedLocalValidity(false),
29  strLocalValidityError(),
30  fCachedFunding(false),
31  fCachedValid(true),
32  fCachedDelete(false),
33  fCachedEndorsed(false),
34  fDirtyCache(true),
35  fExpired(false),
36  fUnparsable(false),
37  mapCurrentMNVotes(),
38  mapOrphanVotes(),
39  fileVotes()
40 {
41  // PARSE JSON DATA STORAGE (STRDATA)
42  LoadData();
43 }
44 
45 CGovernanceObject::CGovernanceObject(uint256 nHashParentIn, int nRevisionIn, int64_t nTimeIn, uint256 nCollateralHashIn, std::string strDataIn)
46 : cs(),
47  nObjectType(GOVERNANCE_OBJECT_UNKNOWN),
48  nHashParent(nHashParentIn),
49  nRevision(nRevisionIn),
50  nTime(nTimeIn),
51  nDeletionTime(0),
52  nCollateralHash(nCollateralHashIn),
53  strData(strDataIn),
54  vinMasternode(),
55  vchSig(),
56  fCachedLocalValidity(false),
57  strLocalValidityError(),
58  fCachedFunding(false),
59  fCachedValid(true),
60  fCachedDelete(false),
61  fCachedEndorsed(false),
62  fDirtyCache(true),
63  fExpired(false),
64  fUnparsable(false),
65  mapCurrentMNVotes(),
66  mapOrphanVotes(),
67  fileVotes()
68 {
69  // PARSE JSON DATA STORAGE (STRDATA)
70  LoadData();
71 }
72 
74 : cs(),
75  nObjectType(other.nObjectType),
76  nHashParent(other.nHashParent),
77  nRevision(other.nRevision),
78  nTime(other.nTime),
79  nDeletionTime(other.nDeletionTime),
80  nCollateralHash(other.nCollateralHash),
81  strData(other.strData),
83  vchSig(other.vchSig),
84  fCachedLocalValidity(other.fCachedLocalValidity),
85  strLocalValidityError(other.strLocalValidityError),
86  fCachedFunding(other.fCachedFunding),
87  fCachedValid(other.fCachedValid),
88  fCachedDelete(other.fCachedDelete),
89  fCachedEndorsed(other.fCachedEndorsed),
90  fDirtyCache(other.fDirtyCache),
91  fExpired(other.fExpired),
92  fUnparsable(other.fUnparsable),
93  mapCurrentMNVotes(other.mapCurrentMNVotes),
94  mapOrphanVotes(other.mapOrphanVotes),
95  fileVotes(other.fileVotes)
96 {}
97 
99  const CGovernanceVote& vote,
100  CGovernanceException& exception,
101  CConnman& connman)
102 {
103  if(!mnodeman.Has(vote.GetMasternodeOutpoint())) {
104  std::ostringstream ostr;
105  ostr << "CGovernanceObject::ProcessVote -- Masternode index not found";
106  exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING);
108  if(pfrom) {
109  mnodeman.AskForMN(pfrom, vote.GetMasternodeOutpoint(), connman);
110  }
111  LogPrintf("%s\n", ostr.str());
112  }
113  else {
114  LogPrint("gobject", "%s\n", ostr.str());
115  }
116  return false;
117  }
118 
120  if(it == mapCurrentMNVotes.end()) {
121  it = mapCurrentMNVotes.insert(vote_m_t::value_type(vote.GetMasternodeOutpoint(), vote_rec_t())).first;
122  }
123  vote_rec_t& recVote = it->second;
124  vote_signal_enum_t eSignal = vote.GetSignal();
125  if(eSignal == VOTE_SIGNAL_NONE) {
126  std::ostringstream ostr;
127  ostr << "CGovernanceObject::ProcessVote -- Vote signal: none";
128  LogPrint("gobject", "%s\n", ostr.str());
129  exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING);
130  return false;
131  }
132  if(eSignal > MAX_SUPPORTED_VOTE_SIGNAL) {
133  std::ostringstream ostr;
134  ostr << "CGovernanceObject::ProcessVote -- Unsupported vote signal: " << CGovernanceVoting::ConvertSignalToString(vote.GetSignal());
135  LogPrintf("%s\n", ostr.str());
136  exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20);
137  return false;
138  }
139  vote_instance_m_it it2 = recVote.mapInstances.find(int(eSignal));
140  if(it2 == recVote.mapInstances.end()) {
141  it2 = recVote.mapInstances.insert(vote_instance_m_t::value_type(int(eSignal), vote_instance_t())).first;
142  }
143  vote_instance_t& voteInstance = it2->second;
144 
145  // Reject obsolete votes
146  if(vote.GetTimestamp() < voteInstance.nCreationTime) {
147  std::ostringstream ostr;
148  ostr << "CGovernanceObject::ProcessVote -- Obsolete vote";
149  LogPrint("gobject", "%s\n", ostr.str());
150  exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_NONE);
151  return false;
152  }
153 
154  int64_t nNow = GetAdjustedTime();
155  int64_t nVoteTimeUpdate = voteInstance.nTime;
157  int64_t nTimeDelta = nNow - voteInstance.nTime;
158  if(nTimeDelta < GOVERNANCE_UPDATE_MIN) {
159  std::ostringstream ostr;
160  ostr << "CGovernanceObject::ProcessVote -- Masternode voting too often"
161  << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort()
162  << ", governance object hash = " << GetHash().ToString()
163  << ", time delta = " << nTimeDelta;
164  LogPrint("gobject", "%s\n", ostr.str());
166  nVoteTimeUpdate = nNow;
167  return false;
168  }
169  }
170  // Finally check that the vote is actually valid (done last because of cost of signature verification)
171  if(!vote.IsValid(true)) {
172  std::ostringstream ostr;
173  ostr << "CGovernanceObject::ProcessVote -- Invalid vote"
174  << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort()
175  << ", governance object hash = " << GetHash().ToString()
176  << ", vote hash = " << vote.GetHash().ToString();
177  LogPrintf("%s\n", ostr.str());
178  exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20);
180  return false;
181  }
183  std::ostringstream ostr;
184  ostr << "CGovernanceObject::ProcessVote -- Unable to add governance vote"
185  << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort()
186  << ", governance object hash = " << GetHash().ToString();
187  LogPrint("gobject", "%s\n", ostr.str());
189  return false;
190  }
191  voteInstance = vote_instance_t(vote.GetOutcome(), nVoteTimeUpdate, vote.GetTimestamp());
192  if(!fileVotes.HasVote(vote.GetHash())) {
193  fileVotes.AddVote(vote);
194  }
195  fDirtyCache = true;
196  return true;
197 }
198 
200 {
201  vote_m_it it = mapCurrentMNVotes.begin();
202  while(it != mapCurrentMNVotes.end()) {
203  if(!mnodeman.Has(it->first)) {
205  mapCurrentMNVotes.erase(it++);
206  }
207  else {
208  ++it;
209  }
210  }
211 }
212 
214 {
215  LOCK(cs);
216  std::string strMessage = nHashParent.ToString() + "|" +
217  boost::lexical_cast<std::string>(nRevision) + "|" +
218  boost::lexical_cast<std::string>(nTime) + "|" +
219  strData + "|" +
222 
223  return strMessage;
224 }
225 
227 {
228  vinMasternode = CTxIn(outpoint);
229 }
230 
231 bool CGovernanceObject::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
232 {
233  std::string strError;
234  std::string strMessage = GetSignatureMessage();
235 
236  LOCK(cs);
237 
238  if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
239  LogPrintf("CGovernanceObject::Sign -- SignMessage() failed\n");
240  return false;
241  }
242 
243  if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
244  LogPrintf("CGovernanceObject::Sign -- VerifyMessage() failed, error: %s\n", strError);
245  return false;
246  }
247 
248  LogPrint("gobject", "CGovernanceObject::Sign -- pubkey id = %s, vin = %s\n",
249  pubKeyMasternode.GetID().ToString(), vinMasternode.prevout.ToStringShort());
250 
251 
252  return true;
253 }
254 
256 {
257  std::string strError;
258 
259  std::string strMessage = GetSignatureMessage();
260 
261  LOCK(cs);
262  if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
263  LogPrintf("CGovernance::CheckSignature -- VerifyMessage() failed, error: %s\n", strError);
264  return false;
265  }
266 
267  return true;
268 }
269 
271 {
272  // todo - 12.1
273  // - detect subtype from strData json, obj["subtype"]
274 
276  return -1;
277 }
278 
280 {
281  // CREATE HASH OF ALL IMPORTANT PIECES OF DATA
282 
284  ss << nHashParent;
285  ss << nRevision;
286  ss << nTime;
287  ss << strData;
288  ss << vinMasternode;
289  ss << vchSig;
290  // fee_tx is left out on purpose
291  uint256 h1 = ss.GetHash();
292 
293  DBG( printf("CGovernanceObject::GetHash %i %li %s\n", nRevision, nTime, strData.c_str()); );
294 
295  return h1;
296 }
297 
304 {
306  if(strData.empty()) {
307  return obj;
308  }
309 
310  UniValue objResult(UniValue::VOBJ);
311  GetData(objResult);
312 
313  std::vector<UniValue> arr1 = objResult.getValues();
314  std::vector<UniValue> arr2 = arr1.at( 0 ).getValues();
315  obj = arr2.at( 1 );
316 
317  return obj;
318 }
319 
329 {
330  // todo : 12.1 - resolved
331  //return;
332 
333  if(strData.empty()) {
334  return;
335  }
336 
337  try {
338  // ATTEMPT TO LOAD JSON STRING FROM STRDATA
339  UniValue objResult(UniValue::VOBJ);
340  GetData(objResult);
341 
342  DBG( cout << "CGovernanceObject::LoadData strData = "
343  << GetDataAsString()
344  << endl; );
345 
346  UniValue obj = GetJSONObject();
347  nObjectType = obj["type"].get_int();
348  }
349  catch(std::exception& e) {
350  fUnparsable = true;
351  std::ostringstream ostr;
352  ostr << "CGovernanceObject::LoadData Error parsing JSON"
353  << ", e.what() = " << e.what();
354  DBG( cout << ostr.str() << endl; );
355  LogPrintf("%s\n", ostr.str());
356  return;
357  }
358  catch(...) {
359  fUnparsable = true;
360  std::ostringstream ostr;
361  ostr << "CGovernanceObject::LoadData Unknown Error parsing JSON";
362  DBG( cout << ostr.str() << endl; );
363  LogPrintf("%s\n", ostr.str());
364  return;
365  }
366 }
367 
377 {
379  std::string s = GetDataAsString();
380  o.read(s);
381  objResult = o;
382 }
383 
391 {
392  return strData;
393 }
394 
396 {
397  std::vector<unsigned char> v = ParseHex(strData);
398  std::string s(v.begin(), v.end());
399 
400  return s;
401 }
402 
404 {
405  LOCK(cs_main);
406  // THIS DOES NOT CHECK COLLATERAL, THIS IS CHECKED UPON ORIGINAL ARRIVAL
408 };
409 
410 
411 bool CGovernanceObject::IsValidLocally(std::string& strError, bool fCheckCollateral)
412 {
413  bool fMissingMasternode = false;
414  bool fMissingConfirmations = false;
415 
416  return IsValidLocally(strError, fMissingMasternode, fMissingConfirmations, fCheckCollateral);
417 }
418 
419 bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMasternode, bool& fMissingConfirmations, bool fCheckCollateral)
420 {
421  fMissingMasternode = false;
422  fMissingConfirmations = false;
423 
424  if(fUnparsable) {
425  strError = "Object data unparseable";
426  return false;
427  }
428 
429  switch(nObjectType) {
433  break;
434  default:
435  strError = strprintf("Invalid object type %d", nObjectType);
436  return false;
437  }
438 
439  // IF ABSOLUTE NO COUNT (NO-YES VALID VOTES) IS MORE THAN 10% OF THE NETWORK MASTERNODES, OBJ IS INVALID
440 
441  // CHECK COLLATERAL IF REQUIRED (HIGH CPU USAGE)
442 
443  if(fCheckCollateral) {
445  std::string strOutpoint = vinMasternode.prevout.ToStringShort();
446  masternode_info_t infoMn;
448 
451  fMissingMasternode = true;
452  strError = "Masternode not found: " + strOutpoint;
454  strError = "Failed to find Masternode UTXO, missing masternode=" + strOutpoint + "\n";
456  strError = "Masternode UTXO should have 1000 DASH, missing masternode=" + strOutpoint + "\n";
457  }
458 
459  return false;
460  }
461 
462  // Check that we have a valid MN signature
463  if(!CheckSignature(infoMn.pubKeyMasternode)) {
464  strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey id = " + infoMn.pubKeyMasternode.GetID().ToString();
465  return false;
466  }
467 
468  return true;
469  }
470 
471  if (!IsCollateralValid(strError, fMissingConfirmations))
472  return false;
473  }
474 
475  /*
476  TODO
477 
478  - There might be an issue with multisig in the coinbase on mainnet, we will add support for it in a future release.
479  - Post 12.2+ (test multisig coinbase transaction)
480  */
481 
482  // 12.1 - todo - compile error
483  // if(address.IsPayToScriptHash()) {
484  // strError = "Governance system - multisig is not currently supported";
485  // return false;
486  // }
487 
488  return true;
489 }
490 
492 {
493  // Only 1 type has a fee for the moment but switch statement allows for future object types
494  switch(nObjectType) {
496  case GOVERNANCE_OBJECT_TRIGGER: return 0;
497  case GOVERNANCE_OBJECT_WATCHDOG: return 0;
498  default: return MAX_MONEY;
499  }
500 }
501 
502 bool CGovernanceObject::IsCollateralValid(std::string& strError, bool& fMissingConfirmations)
503 {
504  strError = "";
505  fMissingConfirmations = false;
506  CAmount nMinFee = GetMinCollateralFee();
507  uint256 nExpectedHash = GetHash();
508 
509  CTransaction txCollateral;
510  uint256 nBlockHash;
511 
512  // RETRIEVE TRANSACTION IN QUESTION
513 
514  if(!GetTransaction(nCollateralHash, txCollateral, Params().GetConsensus(), nBlockHash, true)){
515  strError = strprintf("Can't find collateral tx %s", txCollateral.ToString());
516  LogPrintf("CGovernanceObject::IsCollateralValid -- %s\n", strError);
517  return false;
518  }
519 
520  if(txCollateral.vout.size() < 1) {
521  strError = strprintf("tx vout size less than 1 | %d", txCollateral.vout.size());
522  LogPrintf("CGovernanceObject::IsCollateralValid -- %s\n", strError);
523  return false;
524  }
525 
526  // LOOK FOR SPECIALIZED GOVERNANCE SCRIPT (PROOF OF BURN)
527 
528  CScript findScript;
529  findScript << OP_RETURN << ToByteVector(nExpectedHash);
530 
531  DBG( cout << "IsCollateralValid: txCollateral.vout.size() = " << txCollateral.vout.size() << endl; );
532 
533  DBG( cout << "IsCollateralValid: findScript = " << ScriptToAsmStr( findScript, false ) << endl; );
534 
535  DBG( cout << "IsCollateralValid: nMinFee = " << nMinFee << endl; );
536 
537 
538  bool foundOpReturn = false;
539  BOOST_FOREACH(const CTxOut o, txCollateral.vout) {
540  DBG( cout << "IsCollateralValid txout : " << o.ToString()
541  << ", o.nValue = " << o.nValue
542  << ", o.scriptPubKey = " << ScriptToAsmStr( o.scriptPubKey, false )
543  << endl; );
545  strError = strprintf("Invalid Script %s", txCollateral.ToString());
546  LogPrintf ("CGovernanceObject::IsCollateralValid -- %s\n", strError);
547  return false;
548  }
549  if(o.scriptPubKey == findScript && o.nValue >= nMinFee) {
550  DBG( cout << "IsCollateralValid foundOpReturn = true" << endl; );
551  foundOpReturn = true;
552  }
553  else {
554  DBG( cout << "IsCollateralValid No match, continuing" << endl; );
555  }
556 
557  }
558 
559  if(!foundOpReturn){
560  strError = strprintf("Couldn't find opReturn %s in %s", nExpectedHash.ToString(), txCollateral.ToString());
561  LogPrintf ("CGovernanceObject::IsCollateralValid -- %s\n", strError);
562  return false;
563  }
564 
565  // GET CONFIRMATIONS FOR TRANSACTION
566 
568  int nConfirmationsIn = instantsend.GetConfirmations(nCollateralHash);
569  if (nBlockHash != uint256()) {
570  BlockMap::iterator mi = mapBlockIndex.find(nBlockHash);
571  if (mi != mapBlockIndex.end() && (*mi).second) {
572  CBlockIndex* pindex = (*mi).second;
573  if (chainActive.Contains(pindex)) {
574  nConfirmationsIn += chainActive.Height() - pindex->nHeight + 1;
575  }
576  }
577  }
578 
579  if(nConfirmationsIn < GOVERNANCE_FEE_CONFIRMATIONS) {
580  strError = strprintf("Collateral requires at least %d confirmations to be relayed throughout the network (it has only %d)", GOVERNANCE_FEE_CONFIRMATIONS, nConfirmationsIn);
581  if (nConfirmationsIn >= GOVERNANCE_MIN_RELAY_FEE_CONFIRMATIONS) {
582  fMissingConfirmations = true;
583  strError += ", pre-accepted -- waiting for required confirmations";
584  } else {
585  strError += ", rejected -- try again later";
586  }
587  LogPrintf ("CGovernanceObject::IsCollateralValid -- %s\n", strError);
588 
589  return false;
590  }
591 
592  strError = "valid";
593  return true;
594 }
595 
597 {
598  int nCount = 0;
599  for(vote_m_cit it = mapCurrentMNVotes.begin(); it != mapCurrentMNVotes.end(); ++it) {
600  const vote_rec_t& recVote = it->second;
601  vote_instance_m_cit it2 = recVote.mapInstances.find(eVoteSignalIn);
602  if(it2 == recVote.mapInstances.end()) {
603  continue;
604  }
605  const vote_instance_t& voteInstance = it2->second;
606  if(voteInstance.eOutcome == eVoteOutcomeIn) {
607  ++nCount;
608  }
609  }
610  return nCount;
611 }
612 
618 {
619  return GetYesCount(eVoteSignalIn) - GetNoCount(eVoteSignalIn);
620 }
621 
623 {
624  return GetNoCount(eVoteSignalIn) - GetYesCount(eVoteSignalIn);
625 }
626 
628 {
629  return CountMatchingVotes(eVoteSignalIn, VOTE_OUTCOME_YES);
630 }
631 
633 {
634  return CountMatchingVotes(eVoteSignalIn, VOTE_OUTCOME_NO);
635 }
636 
638 {
639  return CountMatchingVotes(eVoteSignalIn, VOTE_OUTCOME_ABSTAIN);
640 }
641 
642 bool CGovernanceObject::GetCurrentMNVotes(const COutPoint& mnCollateralOutpoint, vote_rec_t& voteRecord)
643 {
644  vote_m_it it = mapCurrentMNVotes.find(mnCollateralOutpoint);
645  if (it == mapCurrentMNVotes.end()) {
646  return false;
647  }
648  voteRecord = it->second;
649  return true;
650 }
651 
653 {
656 }
657 
659 {
660  // CALCULATE MINIMUM SUPPORT LEVELS REQUIRED
661 
662  int nMnCount = mnodeman.CountEnabled();
663  if(nMnCount == 0) return;
664 
665  // CALCULATE THE MINUMUM VOTE COUNT REQUIRED FOR FULL SIGNAL
666 
667  // todo - 12.1 - should be set to `10` after governance vote compression is implemented
668  int nAbsVoteReq = std::max(Params().GetConsensus().nGovernanceMinQuorum, nMnCount / 10);
669  int nAbsDeleteReq = std::max(Params().GetConsensus().nGovernanceMinQuorum, (2 * nMnCount) / 3);
670  // todo - 12.1 - Temporarily set to 1 for testing - reverted
671  //nAbsVoteReq = 1;
672 
673  // SET SENTINEL FLAGS TO FALSE
674 
675  fCachedFunding = false;
676  fCachedValid = true; //default to valid
677  fCachedEndorsed = false;
678  fDirtyCache = false;
679 
680  // SET SENTINEL FLAGS TO TRUE IF MIMIMUM SUPPORT LEVELS ARE REACHED
681  // ARE ANY OF THESE FLAGS CURRENTLY ACTIVATED?
682 
683  if(GetAbsoluteYesCount(VOTE_SIGNAL_FUNDING) >= nAbsVoteReq) fCachedFunding = true;
684  if((GetAbsoluteYesCount(VOTE_SIGNAL_DELETE) >= nAbsDeleteReq) && !fCachedDelete) {
685  fCachedDelete = true;
686  if(nDeletionTime == 0) {
688  }
689  }
690  if(GetAbsoluteYesCount(VOTE_SIGNAL_ENDORSED) >= nAbsVoteReq) fCachedEndorsed = true;
691 
692  if(GetAbsoluteNoCount(VOTE_SIGNAL_VALID) >= nAbsVoteReq) fCachedValid = false;
693 }
694 
696 {
697  // enable ADL (not necessary in our case, but good practice)
698  using std::swap;
699 
700  // by swapping the members of two classes,
701  // the two classes are effectively swapped
702  swap(first.nHashParent, second.nHashParent);
703  swap(first.nRevision, second.nRevision);
704  swap(first.nTime, second.nTime);
705  swap(first.nDeletionTime, second.nDeletionTime);
706  swap(first.nCollateralHash, second.nCollateralHash);
707  swap(first.strData, second.strData);
708  swap(first.nObjectType, second.nObjectType);
709 
710  // swap all cached valid flags
711  swap(first.fCachedFunding, second.fCachedFunding);
712  swap(first.fCachedValid, second.fCachedValid);
713  swap(first.fCachedDelete, second.fCachedDelete);
714  swap(first.fCachedEndorsed, second.fCachedEndorsed);
715  swap(first.fDirtyCache, second.fDirtyCache);
716  swap(first.fExpired, second.fExpired);
717 }
718 
720 {
721  int64_t nNow = GetAdjustedTime();
722  const vote_mcache_t::list_t& listVotes = mapOrphanVotes.GetItemList();
723  vote_mcache_t::list_cit it = listVotes.begin();
724  while(it != listVotes.end()) {
725  bool fRemove = false;
726  const COutPoint& key = it->key;
727  const vote_time_pair_t& pairVote = it->value;
728  const CGovernanceVote& vote = pairVote.first;
729  if(pairVote.second < nNow) {
730  fRemove = true;
731  }
732  else if(!mnodeman.Has(vote.GetMasternodeOutpoint())) {
733  ++it;
734  continue;
735  }
736  CGovernanceException exception;
737  if(!ProcessVote(NULL, vote, exception, connman)) {
738  LogPrintf("CGovernanceObject::CheckOrphanVotes -- Failed to add orphan vote: %s\n", exception.what());
739  }
740  else {
741  vote.Relay(connman);
742  fRemove = true;
743  }
744  ++it;
745  if(fRemove) {
746  mapOrphanVotes.Erase(key, pairVote);
747  }
748  }
749 }
bool AreRateChecksEnabled() const
Definition: governance.h:416
CMasternodeMan mnodeman
bool GetCurrentMNVotes(const COutPoint &mnCollateralOutpoint, vote_rec_t &voteRecord)
int64_t GetTimestamp() const
static const int64_t GOVERNANCE_FEE_CONFIRMATIONS
static const int64_t GOVERNANCE_ORPHAN_EXPIRATION_TIME
vote_m_t::iterator vote_m_it
bool Insert(const K &key, const V &value)
Definition: cachemultimap.h:92
std::pair< CGovernanceVote, int64_t > vote_time_pair_t
bool fCachedValid
true == minimum network has been reached flagging this object as a valid and understood goverance obj...
static const CAmount MAX_MONEY
Definition: amount.h:30
#define strprintf
Definition: tinyformat.h:1011
vote_instance_m_t mapInstances
static const int MIN_GOVERNANCE_PEER_PROTO_VERSION
void AddVote(const CGovernanceVote &vote)
#define DBG(x)
Definition: util.h:41
static const CAmount GOVERNANCE_PROPOSAL_FEE_TX
bool fCachedLocalValidity
is valid by blockchain
Default value, normally indicates no exception condition occurred.
CCriticalSection cs_main
Definition: validation.cpp:62
CAmount nValue
Definition: transaction.h:136
bool fUnparsable
Failed to parse object data.
std::string strLocalValidityError
Definition: net.h:108
static const int64_t GOVERNANCE_MIN_RELAY_FEE_CONFIRMATIONS
static const int GOVERNANCE_OBJECT_PROPOSAL
int CountMatchingVotes(vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn) const
CGovernanceObjectVoteFile fileVotes
void RelayInv(CInv &inv, const int minProtoVersion=MIN_PEER_PROTO_VERSION)
Definition: net.cpp:2528
CPubKey pubKeyMasternode
Definition: masternode.h:117
void Erase(const K &key)
vote_outcome_enum_t GetOutcome() const
void AskForMN(CNode *pnode, const COutPoint &outpoint, CConnman &connman)
Ask (source) node for mnb.
void ClearMasternodeVotes()
Called when MN&#39;s which have voted on this object have been removed.
bool fExpired
Object is no longer of interest.
vote_outcome_enum_t eOutcome
Requested operation cannot be performed.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:144
const list_t & GetItemList() const
int nObjectType
Object typecode.
uint256 GetHash() const
bool Contains(const CBlockIndex *pindex) const
Definition: chain.h:384
static CollateralStatus CheckCollateral(const COutPoint &outpoint)
Definition: masternode.cpp:116
int64_t CAmount
Definition: amount.h:14
uint256 GetHash()
Definition: hash.h:254
#define AssertLockHeld(cs)
Definition: sync.h:96
vote_signal_enum_t GetSignal() const
bool IsUnspendable() const
Definition: script.h:634
#define LogPrintf(...)
Definition: util.h:98
std::string GetSignatureMessage() const
Requested operation not currently possible, may resubmit later.
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Definition: core_write.cpp:75
static const int GOVERNANCE_OBJECT_WATCHDOG
COutPoint prevout
Definition: transaction.h:61
Definition: net.h:661
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
int GetConfirmations(const uint256 &nTXHash)
Definition: instantx.cpp:811
void Relay(CConnman &connman)
#define LOCK(cs)
Definition: sync.h:168
bool fDirtyCache
object was updated and cached values should be updated soon
const COutPoint & GetMasternodeOutpoint() const
int64_t nDeletionTime
time this object was marked for deletion
std::string strData
Data field - can be used for anything.
vote_m_t::const_iterator vote_m_cit
bool GetMasternodeInfo(const COutPoint &outpoint, masternode_info_t &mnInfoRet)
int GetYesCount(vote_signal_enum_t eVoteSignalIn) const
std::string GetDataAsHex()
int Height() const
Definition: chain.h:397
bool IsNormalPaymentScript() const
Definition: script.cpp:203
int GetAbsoluteNoCount(vote_signal_enum_t eVoteSignalIn) const
static const int GOVERNANCE_OBJECT_TRIGGER
CInstantSend instantsend
Definition: instantx.cpp:30
vector< unsigned char > ParseHex(const char *psz)
std::string GetDataAsString()
void RemoveVotesFromMasternode(const COutPoint &outpointMasternode)
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.
CChain chainActive
Definition: validation.cpp:65
std::string ToString() const
Definition: uint256.cpp:65
bool AddGovernanceVote(const COutPoint &outpoint, uint256 nGovernanceObjectHash)
bool IsCollateralValid(std::string &strError, bool &fMissingConfirmations)
Check the collateral transaction for the budget proposal/finalized budget.
bool IsValid() const
CScript scriptPubKey
Definition: transaction.h:137
void AddInvalidVote(const CGovernanceVote &vote)
Definition: governance.h:429
vote_mcache_t mapOrphanVotes
Limited map of votes orphaned by MN.
bool CheckSignature(CPubKey &pubKeyMasternode)
bool IsValidLocally(std::string &strError, bool fCheckCollateral)
void swap(CGovernanceObject &first, CGovernanceObject &second)
bool HasVote(const uint256 &nHash) const
void SetMasternodeVin(const COutPoint &outpoint)
void GetData(UniValue &objResult)
int CountEnabled(int nProtocolVersion=-1)
int GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const
std::vector< unsigned char > vchSig
CCriticalSection cs
critical section to protect the inner data structures
const uint256 & GetParentHash() const
const CChainParams & Params()
static const int64_t GOVERNANCE_UPDATE_MIN
Unusual condition requiring no caller action.
std::string ToString() const
Definition: transaction.cpp:63
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
static const int PROTOCOL_VERSION
Definition: version.h:13
vote_outcome_enum_t
int GetAbsoluteYesCount(vote_signal_enum_t eVoteSignalIn) const
int64_t GetAdjustedTime()
Definition: timedata.cpp:33
std::string ToString() const
vote_signal_enum_t
CTxIn vinMasternode
Masternode info for signed objects.
Definition: protocol.h:314
const std::vector< CTxOut > vout
Definition: transaction.h:234
uint256 nHashParent
parent object, 0 is root
static const int GOVERNANCE_OBJECT_UNKNOWN
uint256 nCollateralHash
fee-tx
static std::string ConvertSignalToString(vote_signal_enum_t nSignal)
bool Has(const COutPoint &outpoint)
bool fCachedFunding
true == minimum network support has been reached for this object to be funded (doesn&#39;t mean it will f...
Definition: pubkey.h:37
virtual uint256 GetHash()=0
static bool SignMessage(const std::string strMessage, std::vector< unsigned char > &vchSigRet, const CKey key)
Sign the message, returns true if successful.
int GetNoCount(vote_signal_enum_t eVoteSignalIn) const
static const int TRIGGER_SUPERBLOCK
bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow)
CGovernanceManager governance
Definition: governance.cpp:17
virtual const char * what() const
int64_t nTime
time this object was created
std::vector< unsigned char > vchSig
void Relay(CConnman &connman) const
bool read(const char *raw)
void CheckOrphanVotes(CConnman &connman)
Definition: key.h:35
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:113
std::string ToStringShort() const
Definition: transaction.cpp:17
static const int MAX_SUPPORTED_VOTE_SIGNAL
BlockMap mapBlockIndex
Definition: validation.cpp:64
bool ProcessVote(CNode *pfrom, const CGovernanceVote &vote, CGovernanceException &exception, CConnman &connman)
vote_instance_m_t::const_iterator vote_instance_m_cit
vote_instance_m_t::iterator vote_instance_m_it
bool fCachedDelete
true == minimum network support has been reached saying this object should be deleted from the system...
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:35
int nRevision
object revision in the system
std::vector< UniValue > getValues() const
Definition: univalue.cpp:296