10 #include "governance-classes.h" 13 #include "validation.h" 23 #include <boost/lexical_cast.hpp> 27 std::string strCommand;
28 if (params.
size() >= 1)
29 strCommand = params[0].get_str();
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" 55 if(strCommand ==
"count")
64 if(strCommand ==
"deserialize")
66 if (params.
size() != 2) {
70 std::string strHex = params[1].
get_str();
72 std::vector<unsigned char> v =
ParseHex(strHex);
73 std::string s(v.begin(), v.end());
78 return u.write().c_str();
82 if(strCommand ==
"check")
84 if (params.
size() != 2) {
95 std::string strData = params[1].
get_str();
117 if(strCommand ==
"prepare")
119 if (params.
size() != 5) {
128 if(params[1].get_str() ==
"0") {
131 hashParent =
ParseHashV(params[1],
"fee-txid, parameter 1");
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();
158 std::string strError =
"";
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.");
173 DBG( cout <<
"gobject: prepare " 183 if(strCommand ==
"submit")
185 if ((params.
size() < 5) || (params.
size() > 6)) {
197 <<
", params.size() = " << params.
size()
198 <<
", fMnFound = " << fMnFound << endl; );
204 if(params.
size() == 6) {
205 txidFee =
ParseHashV(params[5],
"fee-txid, parameter 6");
208 if(params[1].get_str() ==
"0") {
211 hashParent =
ParseHashV(params[1],
"parent object hash, parameter 2");
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();
224 DBG( cout <<
"gobject: submit " 227 <<
", txidFee = " << txidFee.GetHex()
245 LogPrintf(
"gobject(submit) -- Object submission rejected because node is not a masternode\n");
250 if(params.
size() != 6) {
251 LogPrintf(
"gobject(submit) -- Object submission rejected because fee tx not provided\n");
258 std::string strError =
"";
259 bool fMissingMasternode;
260 bool fMissingConfirmations;
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);
272 LogPrintf(
"gobject(submit) -- Object submission rejected because of rate check failure - hash = %s\n", strHash);
276 LogPrintf(
"gobject(submit) -- Adding locally created governance object - %s\n", strHash);
278 if(fMissingConfirmations) {
288 if(strCommand ==
"vote-conf")
290 if(params.
size() != 4)
297 std::string strVoteSignal = params[2].
get_str();
298 std::string strVoteOutcome = params[3].
get_str();
303 "Invalid vote signal. Please using one of the following: " 304 "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
317 std::vector<unsigned char> vchMasterNodeSignature;
318 std::string strMasterNodeSignMessage;
329 statusObj.
push_back(
Pair(
"errorMessage",
"Can't find masternode by collateral output"));
331 returnObj.
push_back(
Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
340 statusObj.
push_back(
Pair(
"errorMessage",
"Failure to sign."));
342 returnObj.
push_back(
Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
360 returnObj.
push_back(
Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
366 if(strCommand ==
"vote-many")
368 if(params.
size() != 4)
375 std::string strVoteSignal = params[2].
get_str();
376 std::string strVoteOutcome = params[3].
get_str();
382 "Invalid vote signal. Please using one of the following: " 383 "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
394 std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
400 std::string strError;
401 std::vector<unsigned char> vchMasterNodeSignature;
402 std::string strMasterNodeSignMessage;
404 CPubKey pubKeyCollateralAddress;
405 CKey keyCollateralAddress;
414 statusObj.
push_back(
Pair(
"errorMessage",
"Masternode signing error, could not set key correctly"));
422 int nOutputIndex = 0;
427 COutPoint outpoint(nTxHash, nOutputIndex);
435 statusObj.
push_back(
Pair(
"errorMessage",
"Can't find masternode by collateral output"));
441 if(!vote.
Sign(keyMasternode, pubKeyMasternode)){
444 statusObj.
push_back(
Pair(
"errorMessage",
"Failure to sign."));
464 returnObj.
push_back(
Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
472 if(strCommand ==
"vote-alias")
474 if(params.
size() != 5)
483 std::string strVoteSignal = params[2].
get_str();
484 std::string strVoteOutcome = params[3].
get_str();
485 std::string strAlias = params[4].
get_str();
492 "Invalid vote signal. Please using one of the following: " 493 "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
506 std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
514 if(strAlias != mne.
getAlias())
continue;
517 std::string strError;
518 std::vector<unsigned char> vchMasterNodeSignature;
519 std::string strMasterNodeSignMessage;
521 CPubKey pubKeyCollateralAddress;
522 CKey keyCollateralAddress;
543 int nOutputIndex = 0;
548 COutPoint outpoint(nTxHash, nOutputIndex);
556 statusObj.
push_back(
Pair(
"errorMessage",
"Masternode must be publically available on network to vote. Masternode not found."));
564 if(!vote.
Sign(keyMasternode, pubKeyMasternode)) {
567 statusObj.
push_back(
Pair(
"errorMessage",
"Failure to sign."));
591 returnObj.
push_back(
Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", nSuccessful, nFailed)));
598 if(strCommand ==
"list" || strCommand ==
"diff")
600 if (params.
size() > 3)
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'";
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'";
652 if(masternodeVin !=
CTxIn()) {
663 std::string strError =
"";
678 if(strCommand ==
"get")
680 if (params.
size() != 2)
704 if(masternodeVin !=
CTxIn()) {
716 objResult.
push_back(
Pair(
"FundingResult", objFundingResult));
743 std::string strError =
"";
745 objResult.
push_back(
Pair(
"IsValidReason", strError.c_str()));
754 if(strCommand ==
"getvotes")
756 if (params.
size() != 2)
757 throw std::runtime_error(
758 "Correct usage is 'gobject getvotes <governance-hash>'" 771 if(pGovObj == NULL) {
790 if(strCommand ==
"getcurrentvotes")
792 if (params.
size() != 2 && params.
size() != 4)
793 throw std::runtime_error(
794 "Correct usage is 'gobject getcurrentvotes <governance-hash> [txid vout_index]'" 802 if (params.
size() == 4) {
804 std::string strVout = params[3].
get_str();
805 uint32_t vout = boost::lexical_cast<uint32_t>(strVout);
806 mnCollateralOutpoint =
COutPoint(txid, vout);
815 if(pGovObj == NULL) {
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" 845 int nMnTxIndex = params[1].
get_int();
849 std::string strVoteSignal = params[3].
get_str();
850 std::string strVoteOutcome = params[4].
get_str();
855 "Invalid vote signal. Please using one of the following: " 856 "(funding|valid|delete|endorsed) OR `custom sentinel code` ");
865 std::string strSig = params[6].
get_str();
866 bool fInvalid =
false;
867 std::vector<unsigned char> vchSig =
DecodeBase64(strSig.c_str(), &fInvalid);
890 return "Voted successfully";
899 if (fHelp || params.
size() != 0) {
900 throw std::runtime_error(
901 "getgovernanceinfo\n" 902 "Returns an object containing governance parameters.\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" 919 int nLastSuperblock, nNextSuperblock;
922 int nBlockHeight = 0;
933 int nFirstSuperblockOffset = (nSuperblockCycle - nSuperblockStartBlock % nSuperblockCycle) % nSuperblockCycle;
934 int nFirstSuperblock = nSuperblockStartBlock + nFirstSuperblockOffset;
936 if(nBlockHeight < nFirstSuperblock){
938 nNextSuperblock = nFirstSuperblock;
940 nLastSuperblock = nBlockHeight - nBlockHeight % nSuperblockCycle;
941 nNextSuperblock = nLastSuperblock + nSuperblockCycle;
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" 962 "1. index (numeric, required) The block index\n" 964 "n (numeric) The absolute maximum sum of superblock payments allowed, in " +
CURRENCY_UNIT +
"\n" 971 int nBlockHeight = params[0].
get_int();
972 if (nBlockHeight < 0) {
std::vector< CGovernanceObject * > GetAllNewerThan(int64_t nMoreThanTime)
CMasternodeSync masternodeSync
bool ProcessVoteAndRelay(const CGovernanceVote &vote, CGovernanceException &exception, CConnman &connman)
int nSuperblockStartBlock
std::vector< CMasternodeEntry > & getEntries()
CMasternodeConfig masternodeConfig
CActiveMasternode activeMasternode
UniValue getgovernanceinfo(const UniValue ¶ms, bool fHelp)
uint256 GetHash() const
Get the 256-bit hash of this public key.
const Consensus::Params & GetConsensus() const
const std::string & getOutputIndex() const
std::vector< CGovernanceVote > GetCurrentVotes(const uint256 &nParentHash, const COutPoint &mnCollateralOutpointFilter)
bool Get(const COutPoint &outpoint, CMasternode &masternodeRet)
Versions of Find that are safe to use from outside the class.
const std::string CURRENCY_UNIT
UniValue gobject(const UniValue ¶ms, bool fHelp)
static const CAmount GOVERNANCE_PROPOSAL_FEE_TX
CGovernanceObject * FindGovernanceObject(const uint256 &nHash)
const std::string & GetErrorMessages()
std::vector< CGovernanceVote > GetMatchingVotes(const uint256 &nParentHash)
const CTxIn & GetMasternodeVin() const
static vote_signal_enum_t ConvertVoteSignal(std::string strVoteSignal)
static const int GOVERNANCE_OBJECT_PROPOSAL
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
const std::string & getTxHash() const
UniValue getsuperblockbudget(const UniValue ¶ms, bool fHelp)
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")
void UpdateLastDiffTime(int64_t nTimeIn)
bool push_back(const UniValue &val)
UniValue ValueFromAmount(const CAmount &amount)
Ran out of memory during operation.
int64_t GetCreationTime() const
int64_t get_int64() const
static const int MASTERNODE_WATCHDOG_MAX_SECONDS
bool MasternodeRateCheck(const CGovernanceObject &govobj, bool fUpdateFailStatus=false)
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)
static const int GOVERNANCE_OBJECT_WATCHDOG
bool ParseInt32(const std::string &str, int32_t *out)
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
void Relay(CConnman &connman)
std::string ToString() const
int GetYesCount(vote_signal_enum_t eVoteSignalIn) const
void AddPostponedObject(const CGovernanceObject &govobj)
std::string GetDataAsHex()
bool IsSetCachedEndorsed() const
static const int GOVERNANCE_OBJECT_TRIGGER
vector< unsigned char > ParseHex(const char *psz)
std::string GetDataAsString()
bool IsSetCachedValid() const
std::string ToString() const
Unexpected type was passed as parameter.
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
static std::pair< std::string, UniValue > Pair(const char *cKey, const char *cVal)
static CAmount GetPaymentsLimit(int nBlockHeight)
UniValue voteraw(const UniValue ¶ms, bool fHelp)
std::string FormatMoney(const CAmount &n)
uint256 ParseHashV(const UniValue &v, string strName)
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)
int GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const
bool IsSetCachedFunding() const
const CChainParams & Params()
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
const uint256 & GetHash() const
int GetAbsoluteYesCount(vote_signal_enum_t eVoteSignalIn) const
int64_t GetAdjustedTime()
bool IsBlockchainSynced()
std::string GetHex() const
std::unique_ptr< CConnman > g_connman
const UniValue NullUniValue
const std::string & getAlias() const
bool Has(const COutPoint &outpoint)
virtual uint256 GetHash()=0
int GetNoCount(vote_signal_enum_t eVoteSignalIn) const
int64_t GetTime()
For unit testing.
CGovernanceManager governance
Dash Core is not connected.
void AddGovernanceObject(CGovernanceObject &govobj, CConnman &connman, CNode *pfrom=NULL)
void SetHex(const char *psz)
std::string ToStringShort() const
const std::string & getPrivKey() const
UniValue JSONRPCError(int code, const string &message)
std::string ToString() const
int GetObjectType() const
CAmount GetMinCollateralFee()
std::string get_str() const
int64_t GetLastDiffTime()