Dash Core  0.12.2.1
P2P Digital Currency
governance.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 //#define ENABLE_DASH_DEBUG
6 
7 #include "activemasternode.h"
8 #include "governance.h"
9 #include "governance-vote.h"
10 #include "governance-classes.h"
11 #include "governance-validators.h"
12 #include "init.h"
13 #include "validation.h"
14 #include "masternode.h"
15 #include "masternode-sync.h"
16 #include "masternodeconfig.h"
17 #include "masternodeman.h"
18 #include "messagesigner.h"
19 #include "rpc/server.h"
20 #include "util.h"
21 #include "utilmoneystr.h"
22 
23 #include <boost/lexical_cast.hpp>
24 
25 UniValue gobject(const UniValue& params, bool fHelp)
26 {
27  std::string strCommand;
28  if (params.size() >= 1)
29  strCommand = params[0].get_str();
30 
31  if (fHelp ||
32  (strCommand != "vote-many" && strCommand != "vote-conf" && strCommand != "vote-alias" && strCommand != "prepare" && strCommand != "submit" && strCommand != "count" &&
33  strCommand != "deserialize" && strCommand != "get" && strCommand != "getvotes" && strCommand != "getcurrentvotes" && strCommand != "list" && strCommand != "diff" &&
34  strCommand != "check" ))
35  throw std::runtime_error(
36  "gobject \"command\"...\n"
37  "Manage governance objects\n"
38  "\nAvailable commands:\n"
39  " check - Validate governance object data (proposal only)\n"
40  " prepare - Prepare governance object by signing and creating tx\n"
41  " submit - Submit governance object to network\n"
42  " deserialize - Deserialize governance object from hex string to JSON\n"
43  " count - Count governance objects and votes\n"
44  " get - Get governance object by hash\n"
45  " getvotes - Get all votes for a governance object hash (including old votes)\n"
46  " getcurrentvotes - Get only current (tallying) votes for a governance object hash (does not include old votes)\n"
47  " list - List governance objects (can be filtered by signal and/or object type)\n"
48  " diff - List differences since last diff\n"
49  " vote-alias - Vote on a governance object by masternode alias (using masternode.conf setup)\n"
50  " vote-conf - Vote on a governance object by masternode configured in dash.conf\n"
51  " vote-many - Vote on a governance object by all masternodes (using masternode.conf setup)\n"
52  );
53 
54 
55  if(strCommand == "count")
56  return governance.ToString();
57  /*
58  ------ Example Governance Item ------
59 
60  gobject submit 6e622bb41bad1fb18e7f23ae96770aeb33129e18bd9efe790522488e580a0a03 0 1 1464292854 "beer-reimbursement" 5b5b22636f6e7472616374222c207b2270726f6a6563745f6e616d65223a20225c22626565722d7265696d62757273656d656e745c22222c20227061796d656e745f61646472657373223a20225c225879324c4b4a4a64655178657948726e34744744514238626a6876464564615576375c22222c2022656e645f64617465223a202231343936333030343030222c20226465736372697074696f6e5f75726c223a20225c227777772e646173687768616c652e6f72672f702f626565722d7265696d62757273656d656e745c22222c2022636f6e74726163745f75726c223a20225c22626565722d7265696d62757273656d656e742e636f6d2f3030312e7064665c22222c20227061796d656e745f616d6f756e74223a20223233342e323334323232222c2022676f7665726e616e63655f6f626a6563745f6964223a2037342c202273746172745f64617465223a202231343833323534303030227d5d5d1
61  */
62 
63  // DEBUG : TEST DESERIALIZATION OF GOVERNANCE META DATA
64  if(strCommand == "deserialize")
65  {
66  if (params.size() != 2) {
67  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject deserialize <data-hex>'");
68  }
69 
70  std::string strHex = params[1].get_str();
71 
72  std::vector<unsigned char> v = ParseHex(strHex);
73  std::string s(v.begin(), v.end());
74 
76  u.read(s);
77 
78  return u.write().c_str();
79  }
80 
81  // VALIDATE A GOVERNANCE OBJECT PRIOR TO SUBMISSION
82  if(strCommand == "check")
83  {
84  if (params.size() != 2) {
85  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject check <data-hex>'");
86  }
87 
88  // ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
89 
90  uint256 hashParent;
91 
92  int nRevision = 1;
93 
94  int64_t nTime = GetAdjustedTime();
95  std::string strData = params[1].get_str();
96 
97  CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strData);
98 
100  CProposalValidator validator(strData);
101  if(!validator.Validate()) {
102  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
103  }
104  }
105  else {
106  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid object type, only proposals can be validated");
107  }
108 
109  UniValue objResult(UniValue::VOBJ);
110 
111  objResult.push_back(Pair("Object status", "OK"));
112 
113  return objResult;
114  }
115 
116  // PREPARE THE GOVERNANCE OBJECT BY CREATING A COLLATERAL TRANSACTION
117  if(strCommand == "prepare")
118  {
119  if (params.size() != 5) {
120  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject prepare <parent-hash> <revision> <time> <data-hex>'");
121  }
122 
123  // ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
124 
125  uint256 hashParent;
126 
127  // -- attach to root node (root node doesn't really exist, but has a hash of zero)
128  if(params[1].get_str() == "0") {
129  hashParent = uint256();
130  } else {
131  hashParent = ParseHashV(params[1], "fee-txid, parameter 1");
132  }
133 
134  std::string strRevision = params[2].get_str();
135  std::string strTime = params[3].get_str();
136  int nRevision = boost::lexical_cast<int>(strRevision);
137  int nTime = boost::lexical_cast<int>(strTime);
138  std::string strData = params[4].get_str();
139 
140  // CREATE A NEW COLLATERAL TRANSACTION FOR THIS SPECIFIC OBJECT
141 
142  CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strData);
143 
144  if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
145  CProposalValidator validator(strData);
146  if(!validator.Validate()) {
147  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
148  }
149  }
150 
151  if((govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) ||
153  throw JSONRPCError(RPC_INVALID_PARAMETER, "Trigger and watchdog objects need not be prepared (however only masternodes can create them)");
154  }
155 
156  {
157  LOCK(cs_main);
158  std::string strError = "";
159  if(!govobj.IsValidLocally(strError, false))
160  throw JSONRPCError(RPC_INTERNAL_ERROR, "Governance object is not valid - " + govobj.GetHash().ToString() + " - " + strError);
161  }
162 
163  CWalletTx wtx;
164  if(!pwalletMain->GetBudgetSystemCollateralTX(wtx, govobj.GetHash(), govobj.GetMinCollateralFee(), false)) {
165  throw JSONRPCError(RPC_INTERNAL_ERROR, "Error making collateral transaction for governance object. Please check your wallet balance and make sure your wallet is unlocked.");
166  }
167 
168  // -- make our change address
169  CReserveKey reservekey(pwalletMain);
170  // -- send the tx to the network
171  pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get(), NetMsgType::TX);
172 
173  DBG( cout << "gobject: prepare "
174  << " strData = " << govobj.GetDataAsString()
175  << ", hash = " << govobj.GetHash().GetHex()
176  << ", txidFee = " << wtx.GetHash().GetHex()
177  << endl; );
178 
179  return wtx.GetHash().ToString();
180  }
181 
182  // AFTER COLLATERAL TRANSACTION HAS MATURED USER CAN SUBMIT GOVERNANCE OBJECT TO PROPAGATE NETWORK
183  if(strCommand == "submit")
184  {
185  if ((params.size() < 5) || (params.size() > 6)) {
186  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject submit <parent-hash> <revision> <time> <data-hex> <fee-txid>'");
187  }
188 
190  throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Must wait for client to sync with masternode network. Try again in a minute or so.");
191  }
192 
193  bool fMnFound = mnodeman.Has(activeMasternode.outpoint);
194 
195  DBG( cout << "gobject: submit activeMasternode.pubKeyMasternode = " << activeMasternode.pubKeyMasternode.GetHash().ToString()
196  << ", outpoint = " << activeMasternode.outpoint.ToStringShort()
197  << ", params.size() = " << params.size()
198  << ", fMnFound = " << fMnFound << endl; );
199 
200  // ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
201 
202  uint256 txidFee;
203 
204  if(params.size() == 6) {
205  txidFee = ParseHashV(params[5], "fee-txid, parameter 6");
206  }
207  uint256 hashParent;
208  if(params[1].get_str() == "0") { // attach to root node (root node doesn't really exist, but has a hash of zero)
209  hashParent = uint256();
210  } else {
211  hashParent = ParseHashV(params[1], "parent object hash, parameter 2");
212  }
213 
214  // GET THE PARAMETERS FROM USER
215 
216  std::string strRevision = params[2].get_str();
217  std::string strTime = params[3].get_str();
218  int nRevision = boost::lexical_cast<int>(strRevision);
219  int nTime = boost::lexical_cast<int>(strTime);
220  std::string strData = params[4].get_str();
221 
222  CGovernanceObject govobj(hashParent, nRevision, nTime, txidFee, strData);
223 
224  DBG( cout << "gobject: submit "
225  << " strData = " << govobj.GetDataAsString()
226  << ", hash = " << govobj.GetHash().GetHex()
227  << ", txidFee = " << txidFee.GetHex()
228  << endl; );
229 
230  if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
231  CProposalValidator validator(strData);
232  if(!validator.Validate()) {
233  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
234  }
235  }
236 
237  // Attempt to sign triggers if we are a MN
238  if((govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) ||
240  if(fMnFound) {
243  }
244  else {
245  LogPrintf("gobject(submit) -- Object submission rejected because node is not a masternode\n");
246  throw JSONRPCError(RPC_INVALID_PARAMETER, "Only valid masternodes can submit this type of object");
247  }
248  }
249  else {
250  if(params.size() != 6) {
251  LogPrintf("gobject(submit) -- Object submission rejected because fee tx not provided\n");
252  throw JSONRPCError(RPC_INVALID_PARAMETER, "The fee-txid parameter must be included to submit this type of object");
253  }
254  }
255 
256  std::string strHash = govobj.GetHash().ToString();
257 
258  std::string strError = "";
259  bool fMissingMasternode;
260  bool fMissingConfirmations;
261  {
262  LOCK(cs_main);
263  if(!govobj.IsValidLocally(strError, fMissingMasternode, fMissingConfirmations, true) && !fMissingConfirmations) {
264  LogPrintf("gobject(submit) -- Object submission rejected because object is not valid - hash = %s, strError = %s\n", strHash, strError);
265  throw JSONRPCError(RPC_INTERNAL_ERROR, "Governance object is not valid - " + strHash + " - " + strError);
266  }
267  }
268 
269  // RELAY THIS OBJECT
270  // Reject if rate check fails but don't update buffer
271  if(!governance.MasternodeRateCheck(govobj)) {
272  LogPrintf("gobject(submit) -- Object submission rejected because of rate check failure - hash = %s\n", strHash);
273  throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
274  }
275 
276  LogPrintf("gobject(submit) -- Adding locally created governance object - %s\n", strHash);
277 
278  if(fMissingConfirmations) {
280  govobj.Relay(*g_connman);
281  } else {
283  }
284 
285  return govobj.GetHash().ToString();
286  }
287 
288  if(strCommand == "vote-conf")
289  {
290  if(params.size() != 4)
291  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject vote-conf <governance-hash> [funding|valid|delete] [yes|no|abstain]'");
292 
293  uint256 hash;
294  std::string strVote;
295 
296  hash = ParseHashV(params[1], "Object hash");
297  std::string strVoteSignal = params[2].get_str();
298  std::string strVoteOutcome = params[3].get_str();
299 
300  vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
301  if(eVoteSignal == VOTE_SIGNAL_NONE) {
303  "Invalid vote signal. Please using one of the following: "
304  "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
305  }
306 
307  vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
308  if(eVoteOutcome == VOTE_OUTCOME_NONE) {
309  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain'");
310  }
311 
312  int nSuccessful = 0;
313  int nFailed = 0;
314 
315  UniValue resultsObj(UniValue::VOBJ);
316 
317  std::vector<unsigned char> vchMasterNodeSignature;
318  std::string strMasterNodeSignMessage;
319 
320  UniValue statusObj(UniValue::VOBJ);
321  UniValue returnObj(UniValue::VOBJ);
322 
323  CMasternode mn;
324  bool fMnFound = mnodeman.Get(activeMasternode.outpoint, mn);
325 
326  if(!fMnFound) {
327  nFailed++;
328  statusObj.push_back(Pair("result", "failed"));
329  statusObj.push_back(Pair("errorMessage", "Can't find masternode by collateral output"));
330  resultsObj.push_back(Pair("dash.conf", statusObj));
331  returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
332  returnObj.push_back(Pair("detail", resultsObj));
333  return returnObj;
334  }
335 
336  CGovernanceVote vote(mn.vin.prevout, hash, eVoteSignal, eVoteOutcome);
338  nFailed++;
339  statusObj.push_back(Pair("result", "failed"));
340  statusObj.push_back(Pair("errorMessage", "Failure to sign."));
341  resultsObj.push_back(Pair("dash.conf", statusObj));
342  returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
343  returnObj.push_back(Pair("detail", resultsObj));
344  return returnObj;
345  }
346 
347  CGovernanceException exception;
348  if(governance.ProcessVoteAndRelay(vote, exception, *g_connman)) {
349  nSuccessful++;
350  statusObj.push_back(Pair("result", "success"));
351  }
352  else {
353  nFailed++;
354  statusObj.push_back(Pair("result", "failed"));
355  statusObj.push_back(Pair("errorMessage", exception.GetMessage()));
356  }
357 
358  resultsObj.push_back(Pair("dash.conf", statusObj));
359 
360  returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
361  returnObj.push_back(Pair("detail", resultsObj));
362 
363  return returnObj;
364  }
365 
366  if(strCommand == "vote-many")
367  {
368  if(params.size() != 4)
369  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject vote-many <governance-hash> [funding|valid|delete] [yes|no|abstain]'");
370 
371  uint256 hash;
372  std::string strVote;
373 
374  hash = ParseHashV(params[1], "Object hash");
375  std::string strVoteSignal = params[2].get_str();
376  std::string strVoteOutcome = params[3].get_str();
377 
378 
379  vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
380  if(eVoteSignal == VOTE_SIGNAL_NONE) {
382  "Invalid vote signal. Please using one of the following: "
383  "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
384  }
385 
386  vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
387  if(eVoteOutcome == VOTE_OUTCOME_NONE) {
388  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain'");
389  }
390 
391  int nSuccessful = 0;
392  int nFailed = 0;
393 
394  std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
395  mnEntries = masternodeConfig.getEntries();
396 
397  UniValue resultsObj(UniValue::VOBJ);
398 
400  std::string strError;
401  std::vector<unsigned char> vchMasterNodeSignature;
402  std::string strMasterNodeSignMessage;
403 
404  CPubKey pubKeyCollateralAddress;
405  CKey keyCollateralAddress;
406  CPubKey pubKeyMasternode;
407  CKey keyMasternode;
408 
409  UniValue statusObj(UniValue::VOBJ);
410 
411  if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){
412  nFailed++;
413  statusObj.push_back(Pair("result", "failed"));
414  statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly"));
415  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
416  continue;
417  }
418 
419  uint256 nTxHash;
420  nTxHash.SetHex(mne.getTxHash());
421 
422  int nOutputIndex = 0;
423  if(!ParseInt32(mne.getOutputIndex(), &nOutputIndex)) {
424  continue;
425  }
426 
427  COutPoint outpoint(nTxHash, nOutputIndex);
428 
429  CMasternode mn;
430  bool fMnFound = mnodeman.Get(outpoint, mn);
431 
432  if(!fMnFound) {
433  nFailed++;
434  statusObj.push_back(Pair("result", "failed"));
435  statusObj.push_back(Pair("errorMessage", "Can't find masternode by collateral output"));
436  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
437  continue;
438  }
439 
440  CGovernanceVote vote(mn.vin.prevout, hash, eVoteSignal, eVoteOutcome);
441  if(!vote.Sign(keyMasternode, pubKeyMasternode)){
442  nFailed++;
443  statusObj.push_back(Pair("result", "failed"));
444  statusObj.push_back(Pair("errorMessage", "Failure to sign."));
445  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
446  continue;
447  }
448 
449  CGovernanceException exception;
450  if(governance.ProcessVoteAndRelay(vote, exception, *g_connman)) {
451  nSuccessful++;
452  statusObj.push_back(Pair("result", "success"));
453  }
454  else {
455  nFailed++;
456  statusObj.push_back(Pair("result", "failed"));
457  statusObj.push_back(Pair("errorMessage", exception.GetMessage()));
458  }
459 
460  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
461  }
462 
463  UniValue returnObj(UniValue::VOBJ);
464  returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
465  returnObj.push_back(Pair("detail", resultsObj));
466 
467  return returnObj;
468  }
469 
470 
471  // MASTERNODES CAN VOTE ON GOVERNANCE OBJECTS ON THE NETWORK FOR VARIOUS SIGNALS AND OUTCOMES
472  if(strCommand == "vote-alias")
473  {
474  if(params.size() != 5)
475  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject vote-alias <governance-hash> [funding|valid|delete] [yes|no|abstain] <alias-name>'");
476 
477  uint256 hash;
478  std::string strVote;
479 
480  // COLLECT NEEDED PARAMETRS FROM USER
481 
482  hash = ParseHashV(params[1], "Object hash");
483  std::string strVoteSignal = params[2].get_str();
484  std::string strVoteOutcome = params[3].get_str();
485  std::string strAlias = params[4].get_str();
486 
487  // CONVERT NAMED SIGNAL/ACTION AND CONVERT
488 
489  vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
490  if(eVoteSignal == VOTE_SIGNAL_NONE) {
492  "Invalid vote signal. Please using one of the following: "
493  "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
494  }
495 
496  vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
497  if(eVoteOutcome == VOTE_OUTCOME_NONE) {
498  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain'");
499  }
500 
501  // EXECUTE VOTE FOR EACH MASTERNODE, COUNT SUCCESSES VS FAILURES
502 
503  int nSuccessful = 0;
504  int nFailed = 0;
505 
506  std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
507  mnEntries = masternodeConfig.getEntries();
508 
509  UniValue resultsObj(UniValue::VOBJ);
510 
512  {
513  // IF WE HAVE A SPECIFIC NODE REQUESTED TO VOTE, DO THAT
514  if(strAlias != mne.getAlias()) continue;
515 
516  // INIT OUR NEEDED VARIABLES TO EXECUTE THE VOTE
517  std::string strError;
518  std::vector<unsigned char> vchMasterNodeSignature;
519  std::string strMasterNodeSignMessage;
520 
521  CPubKey pubKeyCollateralAddress;
522  CKey keyCollateralAddress;
523  CPubKey pubKeyMasternode;
524  CKey keyMasternode;
525 
526  // SETUP THE SIGNING KEY FROM MASTERNODE.CONF ENTRY
527 
528  UniValue statusObj(UniValue::VOBJ);
529 
530  if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) {
531  nFailed++;
532  statusObj.push_back(Pair("result", "failed"));
533  statusObj.push_back(Pair("errorMessage", strprintf("Invalid masternode key %s.", mne.getPrivKey())));
534  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
535  continue;
536  }
537 
538  // SEARCH FOR THIS MASTERNODE ON THE NETWORK, THE NODE MUST BE ACTIVE TO VOTE
539 
540  uint256 nTxHash;
541  nTxHash.SetHex(mne.getTxHash());
542 
543  int nOutputIndex = 0;
544  if(!ParseInt32(mne.getOutputIndex(), &nOutputIndex)) {
545  continue;
546  }
547 
548  COutPoint outpoint(nTxHash, nOutputIndex);
549 
550  CMasternode mn;
551  bool fMnFound = mnodeman.Get(outpoint, mn);
552 
553  if(!fMnFound) {
554  nFailed++;
555  statusObj.push_back(Pair("result", "failed"));
556  statusObj.push_back(Pair("errorMessage", "Masternode must be publically available on network to vote. Masternode not found."));
557  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
558  continue;
559  }
560 
561  // CREATE NEW GOVERNANCE OBJECT VOTE WITH OUTCOME/SIGNAL
562 
563  CGovernanceVote vote(outpoint, hash, eVoteSignal, eVoteOutcome);
564  if(!vote.Sign(keyMasternode, pubKeyMasternode)) {
565  nFailed++;
566  statusObj.push_back(Pair("result", "failed"));
567  statusObj.push_back(Pair("errorMessage", "Failure to sign."));
568  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
569  continue;
570  }
571 
572  // UPDATE LOCAL DATABASE WITH NEW OBJECT SETTINGS
573 
574  CGovernanceException exception;
575  if(governance.ProcessVoteAndRelay(vote, exception, *g_connman)) {
576  nSuccessful++;
577  statusObj.push_back(Pair("result", "success"));
578  }
579  else {
580  nFailed++;
581  statusObj.push_back(Pair("result", "failed"));
582  statusObj.push_back(Pair("errorMessage", exception.GetMessage()));
583  }
584 
585  resultsObj.push_back(Pair(mne.getAlias(), statusObj));
586  }
587 
588  // REPORT STATS TO THE USER
589 
590  UniValue returnObj(UniValue::VOBJ);
591  returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
592  returnObj.push_back(Pair("detail", resultsObj));
593 
594  return returnObj;
595  }
596 
597  // USERS CAN QUERY THE SYSTEM FOR A LIST OF VARIOUS GOVERNANCE ITEMS
598  if(strCommand == "list" || strCommand == "diff")
599  {
600  if (params.size() > 3)
601  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject [list|diff] ( signal type )'");
602 
603  // GET MAIN PARAMETER FOR THIS MODE, VALID OR ALL?
604 
605  std::string strCachedSignal = "valid";
606  if (params.size() >= 2) strCachedSignal = params[1].get_str();
607  if (strCachedSignal != "valid" && strCachedSignal != "funding" && strCachedSignal != "delete" && strCachedSignal != "endorsed" && strCachedSignal != "all")
608  return "Invalid signal, should be 'valid', 'funding', 'delete', 'endorsed' or 'all'";
609 
610  std::string strType = "all";
611  if (params.size() == 3) strType = params[2].get_str();
612  if (strType != "proposals" && strType != "triggers" && strType != "watchdogs" && strType != "all")
613  return "Invalid type, should be 'proposals', 'triggers', 'watchdogs' or 'all'";
614 
615  // GET STARTING TIME TO QUERY SYSTEM WITH
616 
617  int nStartTime = 0; //list
618  if(strCommand == "diff") nStartTime = governance.GetLastDiffTime();
619 
620  // SETUP BLOCK INDEX VARIABLE / RESULTS VARIABLE
621 
622  UniValue objResult(UniValue::VOBJ);
623 
624  // GET MATCHING GOVERNANCE OBJECTS
625 
627 
628  std::vector<CGovernanceObject*> objs = governance.GetAllNewerThan(nStartTime);
630 
631  // CREATE RESULTS FOR USER
632 
633  BOOST_FOREACH(CGovernanceObject* pGovObj, objs)
634  {
635  if(strCachedSignal == "valid" && !pGovObj->IsSetCachedValid()) continue;
636  if(strCachedSignal == "funding" && !pGovObj->IsSetCachedFunding()) continue;
637  if(strCachedSignal == "delete" && !pGovObj->IsSetCachedDelete()) continue;
638  if(strCachedSignal == "endorsed" && !pGovObj->IsSetCachedEndorsed()) continue;
639 
640  if(strType == "proposals" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_PROPOSAL) continue;
641  if(strType == "triggers" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_TRIGGER) continue;
642  if(strType == "watchdogs" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_WATCHDOG) continue;
643 
644  UniValue bObj(UniValue::VOBJ);
645  bObj.push_back(Pair("DataHex", pGovObj->GetDataAsHex()));
646  bObj.push_back(Pair("DataString", pGovObj->GetDataAsString()));
647  bObj.push_back(Pair("Hash", pGovObj->GetHash().ToString()));
648  bObj.push_back(Pair("CollateralHash", pGovObj->GetCollateralHash().ToString()));
649  bObj.push_back(Pair("ObjectType", pGovObj->GetObjectType()));
650  bObj.push_back(Pair("CreationTime", pGovObj->GetCreationTime()));
651  const CTxIn& masternodeVin = pGovObj->GetMasternodeVin();
652  if(masternodeVin != CTxIn()) {
653  bObj.push_back(Pair("SigningMasternode", masternodeVin.prevout.ToStringShort()));
654  }
655 
656  // REPORT STATUS FOR FUNDING VOTES SPECIFICALLY
657  bObj.push_back(Pair("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(VOTE_SIGNAL_FUNDING)));
658  bObj.push_back(Pair("YesCount", pGovObj->GetYesCount(VOTE_SIGNAL_FUNDING)));
659  bObj.push_back(Pair("NoCount", pGovObj->GetNoCount(VOTE_SIGNAL_FUNDING)));
660  bObj.push_back(Pair("AbstainCount", pGovObj->GetAbstainCount(VOTE_SIGNAL_FUNDING)));
661 
662  // REPORT VALIDITY AND CACHING FLAGS FOR VARIOUS SETTINGS
663  std::string strError = "";
664  bObj.push_back(Pair("fBlockchainValidity", pGovObj->IsValidLocally(strError, false)));
665  bObj.push_back(Pair("IsValidReason", strError.c_str()));
666  bObj.push_back(Pair("fCachedValid", pGovObj->IsSetCachedValid()));
667  bObj.push_back(Pair("fCachedFunding", pGovObj->IsSetCachedFunding()));
668  bObj.push_back(Pair("fCachedDelete", pGovObj->IsSetCachedDelete()));
669  bObj.push_back(Pair("fCachedEndorsed", pGovObj->IsSetCachedEndorsed()));
670 
671  objResult.push_back(Pair(pGovObj->GetHash().ToString(), bObj));
672  }
673 
674  return objResult;
675  }
676 
677  // GET SPECIFIC GOVERNANCE ENTRY
678  if(strCommand == "get")
679  {
680  if (params.size() != 2)
681  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject get <governance-hash>'");
682 
683  // COLLECT VARIABLES FROM OUR USER
684  uint256 hash = ParseHashV(params[1], "GovObj hash");
685 
687 
688  // FIND THE GOVERNANCE OBJECT THE USER IS LOOKING FOR
690 
691  if(pGovObj == NULL)
692  throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown governance object");
693 
694  // REPORT BASIC OBJECT STATS
695 
696  UniValue objResult(UniValue::VOBJ);
697  objResult.push_back(Pair("DataHex", pGovObj->GetDataAsHex()));
698  objResult.push_back(Pair("DataString", pGovObj->GetDataAsString()));
699  objResult.push_back(Pair("Hash", pGovObj->GetHash().ToString()));
700  objResult.push_back(Pair("CollateralHash", pGovObj->GetCollateralHash().ToString()));
701  objResult.push_back(Pair("ObjectType", pGovObj->GetObjectType()));
702  objResult.push_back(Pair("CreationTime", pGovObj->GetCreationTime()));
703  const CTxIn& masternodeVin = pGovObj->GetMasternodeVin();
704  if(masternodeVin != CTxIn()) {
705  objResult.push_back(Pair("SigningMasternode", masternodeVin.prevout.ToStringShort()));
706  }
707 
708  // SHOW (MUCH MORE) INFORMATION ABOUT VOTES FOR GOVERNANCE OBJECT (THAN LIST/DIFF ABOVE)
709  // -- FUNDING VOTING RESULTS
710 
711  UniValue objFundingResult(UniValue::VOBJ);
712  objFundingResult.push_back(Pair("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(VOTE_SIGNAL_FUNDING)));
713  objFundingResult.push_back(Pair("YesCount", pGovObj->GetYesCount(VOTE_SIGNAL_FUNDING)));
714  objFundingResult.push_back(Pair("NoCount", pGovObj->GetNoCount(VOTE_SIGNAL_FUNDING)));
715  objFundingResult.push_back(Pair("AbstainCount", pGovObj->GetAbstainCount(VOTE_SIGNAL_FUNDING)));
716  objResult.push_back(Pair("FundingResult", objFundingResult));
717 
718  // -- VALIDITY VOTING RESULTS
719  UniValue objValid(UniValue::VOBJ);
720  objValid.push_back(Pair("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(VOTE_SIGNAL_VALID)));
721  objValid.push_back(Pair("YesCount", pGovObj->GetYesCount(VOTE_SIGNAL_VALID)));
722  objValid.push_back(Pair("NoCount", pGovObj->GetNoCount(VOTE_SIGNAL_VALID)));
723  objValid.push_back(Pair("AbstainCount", pGovObj->GetAbstainCount(VOTE_SIGNAL_VALID)));
724  objResult.push_back(Pair("ValidResult", objValid));
725 
726  // -- DELETION CRITERION VOTING RESULTS
727  UniValue objDelete(UniValue::VOBJ);
728  objDelete.push_back(Pair("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(VOTE_SIGNAL_DELETE)));
729  objDelete.push_back(Pair("YesCount", pGovObj->GetYesCount(VOTE_SIGNAL_DELETE)));
730  objDelete.push_back(Pair("NoCount", pGovObj->GetNoCount(VOTE_SIGNAL_DELETE)));
731  objDelete.push_back(Pair("AbstainCount", pGovObj->GetAbstainCount(VOTE_SIGNAL_DELETE)));
732  objResult.push_back(Pair("DeleteResult", objDelete));
733 
734  // -- ENDORSED VIA MASTERNODE-ELECTED BOARD
735  UniValue objEndorsed(UniValue::VOBJ);
736  objEndorsed.push_back(Pair("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(VOTE_SIGNAL_ENDORSED)));
737  objEndorsed.push_back(Pair("YesCount", pGovObj->GetYesCount(VOTE_SIGNAL_ENDORSED)));
738  objEndorsed.push_back(Pair("NoCount", pGovObj->GetNoCount(VOTE_SIGNAL_ENDORSED)));
739  objEndorsed.push_back(Pair("AbstainCount", pGovObj->GetAbstainCount(VOTE_SIGNAL_ENDORSED)));
740  objResult.push_back(Pair("EndorsedResult", objEndorsed));
741 
742  // --
743  std::string strError = "";
744  objResult.push_back(Pair("fLocalValidity", pGovObj->IsValidLocally(strError, false)));
745  objResult.push_back(Pair("IsValidReason", strError.c_str()));
746  objResult.push_back(Pair("fCachedValid", pGovObj->IsSetCachedValid()));
747  objResult.push_back(Pair("fCachedFunding", pGovObj->IsSetCachedFunding()));
748  objResult.push_back(Pair("fCachedDelete", pGovObj->IsSetCachedDelete()));
749  objResult.push_back(Pair("fCachedEndorsed", pGovObj->IsSetCachedEndorsed()));
750  return objResult;
751  }
752 
753  // GETVOTES FOR SPECIFIC GOVERNANCE OBJECT
754  if(strCommand == "getvotes")
755  {
756  if (params.size() != 2)
757  throw std::runtime_error(
758  "Correct usage is 'gobject getvotes <governance-hash>'"
759  );
760 
761  // COLLECT PARAMETERS FROM USER
762 
763  uint256 hash = ParseHashV(params[1], "Governance hash");
764 
765  // FIND OBJECT USER IS LOOKING FOR
766 
767  LOCK(governance.cs);
768 
770 
771  if(pGovObj == NULL) {
772  throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown governance-hash");
773  }
774 
775  // REPORT RESULTS TO USER
776 
777  UniValue bResult(UniValue::VOBJ);
778 
779  // GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION
780 
781  std::vector<CGovernanceVote> vecVotes = governance.GetMatchingVotes(hash);
782  BOOST_FOREACH(CGovernanceVote vote, vecVotes) {
783  bResult.push_back(Pair(vote.GetHash().ToString(), vote.ToString()));
784  }
785 
786  return bResult;
787  }
788 
789  // GETVOTES FOR SPECIFIC GOVERNANCE OBJECT
790  if(strCommand == "getcurrentvotes")
791  {
792  if (params.size() != 2 && params.size() != 4)
793  throw std::runtime_error(
794  "Correct usage is 'gobject getcurrentvotes <governance-hash> [txid vout_index]'"
795  );
796 
797  // COLLECT PARAMETERS FROM USER
798 
799  uint256 hash = ParseHashV(params[1], "Governance hash");
800 
801  COutPoint mnCollateralOutpoint;
802  if (params.size() == 4) {
803  uint256 txid = ParseHashV(params[2], "Masternode Collateral hash");
804  std::string strVout = params[3].get_str();
805  uint32_t vout = boost::lexical_cast<uint32_t>(strVout);
806  mnCollateralOutpoint = COutPoint(txid, vout);
807  }
808 
809  // FIND OBJECT USER IS LOOKING FOR
810 
811  LOCK(governance.cs);
812 
814 
815  if(pGovObj == NULL) {
816  throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown governance-hash");
817  }
818 
819  // REPORT RESULTS TO USER
820 
821  UniValue bResult(UniValue::VOBJ);
822 
823  // GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION
824 
825  std::vector<CGovernanceVote> vecVotes = governance.GetCurrentVotes(hash, mnCollateralOutpoint);
826  BOOST_FOREACH(CGovernanceVote vote, vecVotes) {
827  bResult.push_back(Pair(vote.GetHash().ToString(), vote.ToString()));
828  }
829 
830  return bResult;
831  }
832 
833  return NullUniValue;
834 }
835 
836 UniValue voteraw(const UniValue& params, bool fHelp)
837 {
838  if (fHelp || params.size() != 7)
839  throw std::runtime_error(
840  "voteraw <masternode-tx-hash> <masternode-tx-index> <governance-hash> <vote-signal> [yes|no|abstain] <time> <vote-sig>\n"
841  "Compile and relay a governance vote with provided external signature instead of signing vote internally\n"
842  );
843 
844  uint256 hashMnTx = ParseHashV(params[0], "mn tx hash");
845  int nMnTxIndex = params[1].get_int();
846  COutPoint outpoint = COutPoint(hashMnTx, nMnTxIndex);
847 
848  uint256 hashGovObj = ParseHashV(params[2], "Governance hash");
849  std::string strVoteSignal = params[3].get_str();
850  std::string strVoteOutcome = params[4].get_str();
851 
852  vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
853  if(eVoteSignal == VOTE_SIGNAL_NONE) {
855  "Invalid vote signal. Please using one of the following: "
856  "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
857  }
858 
859  vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
860  if(eVoteOutcome == VOTE_OUTCOME_NONE) {
861  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain'");
862  }
863 
864  int64_t nTime = params[5].get_int64();
865  std::string strSig = params[6].get_str();
866  bool fInvalid = false;
867  std::vector<unsigned char> vchSig = DecodeBase64(strSig.c_str(), &fInvalid);
868 
869  if (fInvalid) {
870  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
871  }
872 
873  CMasternode mn;
874  bool fMnFound = mnodeman.Get(outpoint, mn);
875 
876  if(!fMnFound) {
877  throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to find masternode in list : " + outpoint.ToStringShort());
878  }
879 
880  CGovernanceVote vote(outpoint, hashGovObj, eVoteSignal, eVoteOutcome);
881  vote.SetTime(nTime);
882  vote.SetSignature(vchSig);
883 
884  if(!vote.IsValid(true)) {
885  throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to verify vote.");
886  }
887 
888  CGovernanceException exception;
889  if(governance.ProcessVoteAndRelay(vote, exception, *g_connman)) {
890  return "Voted successfully";
891  }
892  else {
893  throw JSONRPCError(RPC_INTERNAL_ERROR, "Error voting : " + exception.GetMessage());
894  }
895 }
896 
897 UniValue getgovernanceinfo(const UniValue& params, bool fHelp)
898 {
899  if (fHelp || params.size() != 0) {
900  throw std::runtime_error(
901  "getgovernanceinfo\n"
902  "Returns an object containing governance parameters.\n"
903  "\nResult:\n"
904  "{\n"
905  " \"governanceminquorum\": xxxxx, (numeric) the absolute minimum number of votes needed to trigger a governance action\n"
906  " \"masternodewatchdogmaxseconds\": xxxxx, (numeric) sentinel watchdog expiration time in seconds\n"
907  " \"proposalfee\": xxx.xx, (numeric) the collateral transaction fee which must be paid to create a proposal in " + CURRENCY_UNIT + "\n"
908  " \"superblockcycle\": xxxxx, (numeric) the number of blocks between superblocks\n"
909  " \"lastsuperblock\": xxxxx, (numeric) the block number of the last superblock\n"
910  " \"nextsuperblock\": xxxxx, (numeric) the block number of the next superblock\n"
911  "}\n"
912  "\nExamples:\n"
913  + HelpExampleCli("getgovernanceinfo", "")
914  + HelpExampleRpc("getgovernanceinfo", "")
915  );
916  }
917 
918  // Compute last/next superblock
919  int nLastSuperblock, nNextSuperblock;
920 
921  // Get current block height
922  int nBlockHeight = 0;
923  {
924  LOCK(cs_main);
925  nBlockHeight = (int)chainActive.Height();
926  }
927 
928  // Get chain parameters
929  int nSuperblockStartBlock = Params().GetConsensus().nSuperblockStartBlock;
930  int nSuperblockCycle = Params().GetConsensus().nSuperblockCycle;
931 
932  // Get first superblock
933  int nFirstSuperblockOffset = (nSuperblockCycle - nSuperblockStartBlock % nSuperblockCycle) % nSuperblockCycle;
934  int nFirstSuperblock = nSuperblockStartBlock + nFirstSuperblockOffset;
935 
936  if(nBlockHeight < nFirstSuperblock){
937  nLastSuperblock = 0;
938  nNextSuperblock = nFirstSuperblock;
939  } else {
940  nLastSuperblock = nBlockHeight - nBlockHeight % nSuperblockCycle;
941  nNextSuperblock = nLastSuperblock + nSuperblockCycle;
942  }
943 
945  obj.push_back(Pair("governanceminquorum", Params().GetConsensus().nGovernanceMinQuorum));
946  obj.push_back(Pair("masternodewatchdogmaxseconds", MASTERNODE_WATCHDOG_MAX_SECONDS));
948  obj.push_back(Pair("superblockcycle", Params().GetConsensus().nSuperblockCycle));
949  obj.push_back(Pair("lastsuperblock", nLastSuperblock));
950  obj.push_back(Pair("nextsuperblock", nNextSuperblock));
951 
952  return obj;
953 }
954 
955 UniValue getsuperblockbudget(const UniValue& params, bool fHelp)
956 {
957  if (fHelp || params.size() != 1) {
958  throw std::runtime_error(
959  "getsuperblockbudget index\n"
960  "\nReturns the absolute maximum sum of superblock payments allowed.\n"
961  "\nArguments:\n"
962  "1. index (numeric, required) The block index\n"
963  "\nResult:\n"
964  "n (numeric) The absolute maximum sum of superblock payments allowed, in " + CURRENCY_UNIT + "\n"
965  "\nExamples:\n"
966  + HelpExampleCli("getsuperblockbudget", "1000")
967  + HelpExampleRpc("getsuperblockbudget", "1000")
968  );
969  }
970 
971  int nBlockHeight = params[0].get_int();
972  if (nBlockHeight < 0) {
973  throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
974  }
975 
976  CAmount nBudget = CSuperblock::GetPaymentsLimit(nBlockHeight);
977  std::string strBudget = FormatMoney(nBudget);
978 
979  return strBudget;
980 }
981 
std::vector< CGovernanceObject * > GetAllNewerThan(int64_t nMoreThanTime)
Definition: governance.cpp:623
int nSuperblockCycle
Definition: params.h:55
CMasternodeMan mnodeman
CMasternodeSync masternodeSync
bool ProcessVoteAndRelay(const CGovernanceVote &vote, CGovernanceException &exception, CConnman &connman)
Definition: governance.h:402
int nSuperblockStartBlock
Definition: params.h:54
std::vector< CMasternodeEntry > & getEntries()
CMasternodeConfig masternodeConfig
CActiveMasternode activeMasternode
UniValue getgovernanceinfo(const UniValue &params, bool fHelp)
Definition: governance.cpp:897
#define strprintf
Definition: tinyformat.h:1011
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:150
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:55
const std::string & getOutputIndex() const
std::vector< CGovernanceVote > GetCurrentVotes(const uint256 &nParentHash, const COutPoint &mnCollateralOutpointFilter)
Definition: governance.cpp:583
bool Get(const COutPoint &outpoint, CMasternode &masternodeRet)
Versions of Find that are safe to use from outside the class.
#define DBG(x)
Definition: util.h:41
const std::string CURRENCY_UNIT
Definition: amount.cpp:10
UniValue gobject(const UniValue &params, bool fHelp)
Definition: governance.cpp:25
static const CAmount GOVERNANCE_PROPOSAL_FEE_TX
CCriticalSection cs_main
Definition: validation.cpp:62
CGovernanceObject * FindGovernanceObject(const uint256 &nHash)
Definition: governance.cpp:559
const std::string & GetErrorMessages()
std::vector< CGovernanceVote > GetMatchingVotes(const uint256 &nParentHash)
Definition: governance.cpp:569
const CTxIn & GetMasternodeVin() const
static vote_signal_enum_t ConvertVoteSignal(std::string strVoteSignal)
static const int GOVERNANCE_OBJECT_PROPOSAL
const char * TX
Definition: protocol.cpp:24
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:586
const std::string & getTxHash() const
CWallet * pwalletMain
UniValue getsuperblockbudget(const UniValue &params, bool fHelp)
Definition: governance.cpp:955
const std::string & GetMessage() const
static vote_outcome_enum_t ConvertVoteOutcome(std::string strVoteOutcome)
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, std::string strCommand="tx")
Definition: wallet.cpp:3527
void UpdateLastDiffTime(int64_t nTimeIn)
Definition: governance.h:371
bool push_back(const UniValue &val)
Definition: univalue.cpp:176
UniValue ValueFromAmount(const CAmount &amount)
Definition: server.cpp:122
Ran out of memory during operation.
Definition: protocol.h:46
uint256 GetHash() const
int64_t GetCreationTime() const
int64_t get_int64() const
Definition: univalue.cpp:327
static const int MASTERNODE_WATCHDOG_MAX_SECONDS
Definition: masternode.h:20
int64_t CAmount
Definition: amount.h:14
#define LOCK2(cs1, cs2)
Definition: sync.h:169
bool MasternodeRateCheck(const CGovernanceObject &govobj, bool fUpdateFailStatus=false)
Definition: governance.cpp:842
static bool GetKeysFromSecret(const std::string strSecret, CKey &keyRet, CPubKey &pubkeyRet)
Set the private/public key values, returns true if successful.
void SetTime(int64_t nTimeIn)
#define LogPrintf(...)
Definition: util.h:98
static const int GOVERNANCE_OBJECT_WATCHDOG
COutPoint prevout
Definition: transaction.h:61
bool ParseInt32(const std::string &str, int32_t *out)
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
void Relay(CConnman &connman)
#define LOCK(cs)
Definition: sync.h:168
std::string ToString() const
int GetYesCount(vote_signal_enum_t eVoteSignalIn) const
void AddPostponedObject(const CGovernanceObject &govobj)
Definition: governance.h:386
std::string GetDataAsHex()
int Height() const
Definition: chain.h:397
bool IsSetCachedEndorsed() const
static const int GOVERNANCE_OBJECT_TRIGGER
vector< unsigned char > ParseHex(const char *psz)
std::string GetDataAsString()
bool IsSetCachedValid() const
CChain chainActive
Definition: validation.cpp:65
std::string ToString() const
Definition: uint256.cpp:65
Unexpected type was passed as parameter.
Definition: protocol.h:44
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:581
static std::pair< std::string, UniValue > Pair(const char *cKey, const char *cVal)
Definition: univalue.h:166
static CAmount GetPaymentsLimit(int nBlockHeight)
bool IsValid() const
UniValue voteraw(const UniValue &params, bool fHelp)
Definition: governance.cpp:836
std::string FormatMoney(const CAmount &n)
uint256 ParseHashV(const UniValue &v, string strName)
Definition: server.cpp:132
const uint256 & GetCollateralHash() const
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
void SetSignature(const std::vector< unsigned char > &vchSigIn)
bool IsSetCachedDelete() const
bool IsValidLocally(std::string &strError, bool fCheckCollateral)
void SetMasternodeVin(const COutPoint &outpoint)
bool GetBudgetSystemCollateralTX(CTransaction &tx, uint256 hash, CAmount amount, bool fUseInstantSend)
Definition: wallet.cpp:3123
int GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const
bool IsSetCachedFunding() const
const CChainParams & Params()
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
const uint256 & GetHash() const
Definition: transaction.h:262
vote_outcome_enum_t
int GetAbsoluteYesCount(vote_signal_enum_t eVoteSignalIn) const
int64_t GetAdjustedTime()
Definition: timedata.cpp:33
bool IsBlockchainSynced()
vote_signal_enum_t
std::string GetHex() const
Definition: uint256.cpp:21
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:103
const UniValue NullUniValue
Definition: univalue.cpp:78
int get_int() const
Definition: univalue.cpp:317
const std::string & getAlias() const
bool Has(const COutPoint &outpoint)
Definition: pubkey.h:37
virtual uint256 GetHash()=0
int GetNoCount(vote_signal_enum_t eVoteSignalIn) const
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:20
CGovernanceManager governance
Definition: governance.cpp:17
Dash Core is not connected.
Definition: protocol.h:61
void AddGovernanceObject(CGovernanceObject &govobj, CConnman &connman, CNode *pfrom=NULL)
Definition: governance.cpp:301
void SetHex(const char *psz)
Definition: uint256.cpp:30
Definition: key.h:35
std::string ToStringShort() const
Definition: transaction.cpp:17
const std::string & getPrivKey() const
UniValue JSONRPCError(int code, const string &message)
Definition: protocol.cpp:57
CCriticalSection cs
Definition: governance.h:289
std::string ToString() const
size_t size() const
Definition: univalue.h:69
int GetObjectType() const
std::string get_str() const
Definition: univalue.cpp:310
int64_t GetLastDiffTime()
Definition: governance.h:370