48 std::string strError =
"";
50 bObj.
push_back(Pair(
"IsValidReason", strError.c_str()));
59 if (fHelp || params.
size() != 6)
60 throw std::runtime_error(
61 "preparebudget \"proposal-name\" \"url\" payment-count block-start \"prcycoin-address\" monthly-payment\n"
62 "\nPrepare proposal for network by signing and creating tx\n"
65 "1. \"proposal-name\": (string, required) Desired proposal name (20 character limit)\n"
66 "2. \"url\": (string, required) URL of proposal details (64 character limit)\n"
67 "3. payment-count: (numeric, required) Total number of monthly payments\n"
68 "4. block-start: (numeric, required) Starting super block height\n"
69 "5. \"prcycoin-address\": (string, required) PRCY address to send payments to\n"
70 "6. monthly-payment: (numeric, required) Monthly payment amount\n"
73 "\"xxxx\" (string) proposal fee hash (if successful) or error message (if failed)\n"
75 HelpExampleCli(
"preparebudget",
"\"test-proposal\" \"https://forum.prcycoin.com/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500") +
76 HelpExampleRpc(
"preparebudget",
"\"test-proposal\" \"https://forum.prcycoin.com/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500"));
83 if (strProposalName.size() > 20)
84 throw std::runtime_error(
"Invalid proposal name, limit of 20 characters.");
87 if (strURL.size() > 64)
88 throw std::runtime_error(
"Invalid url, limit of 64 characters.");
90 int nPaymentCount = params[2].
get_int();
91 if (nPaymentCount < 1)
92 throw std::runtime_error(
"Invalid payment count, must be more than zero.");
97 int nBlockStart = params[3].
get_int();
100 throw std::runtime_error(
strprintf(
"Invalid block start - must be a budget cycle block. Next valid block: %d", nNext));
105 if (nBlockStart < nBlockMin)
106 throw std::runtime_error(
"Invalid block start, must be more than current height.");
108 if (nBlockEnd < pindexPrev->nHeight)
109 throw std::runtime_error(
"Invalid ending block, starting block + (payment_cycle*payments) must be more than current height.");
124 std::string strError =
"";
125 if (!budgetProposalBroadcast.
IsValid(strError,
false))
126 throw std::runtime_error(
"Proposal is not valid - " + budgetProposalBroadcast.
GetHash().
ToString() +
" - " + strError);
132 throw std::runtime_error(
"Error making collateral transaction for proposal. Please check your wallet balance.");
148 if (fHelp || params.
size() != 7)
149 throw std::runtime_error(
150 "submitbudget \"proposal-name\" \"url\" payment-count block-start \"prcycoin-address\" monthly-payment \"fee-tx\"\n"
151 "\nSubmit proposal to the network\n"
154 "1. \"proposal-name\": (string, required) Desired proposal name (20 character limit)\n"
155 "2. \"url\": (string, required) URL of proposal details (64 character limit)\n"
156 "3. payment-count: (numeric, required) Total number of monthly payments\n"
157 "4. block-start: (numeric, required) Starting super block height\n"
158 "5. \"prcycoin-address\": (string, required) PRCY address to send payments to\n"
159 "6. monthly-payment: (numeric, required) Monthly payment amount\n"
160 "7. \"fee-tx\": (string, required) Transaction hash from preparebudget command\n"
163 "\"xxxx\" (string) proposal hash (if successful) or error message (if failed)\n"
165 HelpExampleCli(
"submitbudget",
"\"test-proposal\" \"https://forum.prcycoin.com/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500") +
166 HelpExampleRpc(
"submitbudget",
"\"test-proposal\" \"https://forum.prcycoin.com/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500"));
171 std::string strProposalName =
SanitizeString(params[0].get_str());
172 if (strProposalName.size() > 20)
173 throw std::runtime_error(
"Invalid proposal name, limit of 20 characters.");
176 if (strURL.size() > 64)
177 throw std::runtime_error(
"Invalid url, limit of 64 characters.");
179 int nPaymentCount = params[2].
get_int();
180 if (nPaymentCount < 1)
181 throw std::runtime_error(
"Invalid payment count, must be more than zero.");
186 int nBlockStart = params[3].
get_int();
189 throw std::runtime_error(
strprintf(
"Invalid block start - must be a budget cycle block. Next valid block: %d", nNext));
194 if (nBlockStart < nBlockMin)
195 throw std::runtime_error(
"Invalid block start, must be more than current height.");
197 if (nBlockEnd < pindexPrev->nHeight)
198 throw std::runtime_error(
"Invalid ending block, starting block + (payment_cycle*payments) must be more than current height.");
210 CBudgetProposalBroadcast budgetProposalBroadcast(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, hash);
212 std::string strError =
"";
215 throw std::runtime_error(
"Proposal FeeTX is not valid - " + hash.
ToString() +
" - " + strError);
219 throw std::runtime_error(
"Must wait for client to sync with masternode network. Try again in a minute or so.");
223 budgetProposalBroadcast.
Relay();
227 throw std::runtime_error(
"Invalid proposal, see debug.log for details.");
232 std::string strCommand;
233 if (params.
size() >= 1) {
234 strCommand = params[0].
get_str();
237 if (strCommand ==
"vote") strCommand =
"local";
238 if (strCommand ==
"vote-many") strCommand =
"many";
239 if (strCommand ==
"vote-alias") strCommand =
"alias";
242 if (fHelp || (params.
size() == 3 && (strCommand !=
"local" && strCommand !=
"many")) || (params.
size() == 4 && strCommand !=
"alias") ||
243 params.
size() > 4 || params.
size() < 3)
244 throw std::runtime_error(
245 "mnbudgetvote \"local|many|alias\" \"votehash\" \"yes|no\" ( \"alias\" )\n"
246 "\nVote on a budget proposal\n"
249 "1. \"mode\" (string, required) The voting mode. 'local' for voting directly from a masternode, 'many' for voting with a MN controller and casting the same vote for each MN, 'alias' for voting with a MN controller and casting a vote for a single MN\n"
250 "2. \"votehash\" (string, required) The vote hash for the proposal\n"
251 "3. \"votecast\" (string, required) Your vote. 'yes' to vote for the proposal, 'no' to vote against\n"
252 "4. \"alias\" (string, required for 'alias' mode) The MN alias to cast a vote for.\n"
256 " \"overall\": \"xxxx\", (string) The overall status message for the vote cast\n"
259 " \"node\": \"xxxx\", (string) 'local' or the MN alias\n"
260 " \"result\": \"xxxx\", (string) Either 'Success' or 'Failed'\n"
261 " \"error\": \"xxxx\", (string) Error message, if vote failed\n"
268 HelpExampleCli(
"mnbudgetvote",
"\"local\" \"ed2f83cedee59a91406f5f47ec4d60bf5a7f9ee6293913c82976bd2d3a658041\" \"yes\"") +
269 HelpExampleRpc(
"mnbudgetvote",
"\"local\" \"ed2f83cedee59a91406f5f47ec4d60bf5a7f9ee6293913c82976bd2d3a658041\" \"yes\""));
272 std::string strVote = params[2].
get_str();
274 if (strVote !=
"yes" && strVote !=
"no")
return "You can only vote 'yes' or 'no'";
276 if (strVote ==
"yes") nVote =
VOTE_YES;
277 if (strVote ==
"no") nVote =
VOTE_NO;
284 if (strCommand ==
"local") {
293 statusObj.
push_back(Pair(
"node",
"local"));
294 statusObj.
push_back(Pair(
"result",
"failed"));
295 statusObj.
push_back(Pair(
"error",
"Masternode signing error, could not set key correctly."));
303 statusObj.
push_back(Pair(
"node",
"local"));
304 statusObj.
push_back(Pair(
"result",
"failed"));
311 if (!vote.
Sign(keyMasternode, pubKeyMasternode)) {
313 statusObj.
push_back(Pair(
"node",
"local"));
314 statusObj.
push_back(Pair(
"result",
"failed"));
315 statusObj.
push_back(Pair(
"error",
"Failure to sign."));
320 std::string strError =
"";
325 statusObj.
push_back(Pair(
"node",
"local"));
326 statusObj.
push_back(Pair(
"result",
"success"));
330 statusObj.
push_back(Pair(
"node",
"local"));
331 statusObj.
push_back(Pair(
"result",
"failed"));
332 statusObj.
push_back(Pair(
"error",
"Error voting : " + strError));
339 returnObj.
push_back(Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", success, failed)));
340 returnObj.
push_back(Pair(
"detail", resultsObj));
345 if (strCommand ==
"many") {
347 std::vector<unsigned char> vchMasterNodeSignature;
348 std::string strMasterNodeSignMessage;
350 CPubKey pubKeyCollateralAddress;
351 CKey keyCollateralAddress;
359 statusObj.
push_back(Pair(
"node", mne.getAlias()));
360 statusObj.
push_back(Pair(
"result",
"failed"));
361 statusObj.
push_back(Pair(
"error",
"Masternode signing error, could not set key correctly."));
369 statusObj.
push_back(Pair(
"node", mne.getAlias()));
370 statusObj.
push_back(Pair(
"result",
"failed"));
371 statusObj.
push_back(Pair(
"error",
"Can't find masternode by pubkey"));
377 if (!vote.
Sign(keyMasternode, pubKeyMasternode)) {
379 statusObj.
push_back(Pair(
"node", mne.getAlias()));
380 statusObj.
push_back(Pair(
"result",
"failed"));
381 statusObj.
push_back(Pair(
"error",
"Failure to sign."));
386 std::string strError =
"";
391 statusObj.
push_back(Pair(
"node", mne.getAlias()));
392 statusObj.
push_back(Pair(
"result",
"success"));
396 statusObj.
push_back(Pair(
"node", mne.getAlias()));
397 statusObj.
push_back(Pair(
"result",
"failed"));
398 statusObj.
push_back(Pair(
"error", strError.c_str()));
405 returnObj.
push_back(Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", success, failed)));
406 returnObj.
push_back(Pair(
"detail", resultsObj));
411 if (strCommand ==
"alias") {
412 std::string strAlias = params[3].
get_str();
413 std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
418 if( strAlias != mne.getAlias())
continue;
420 std::vector<unsigned char> vchMasterNodeSignature;
421 std::string strMasterNodeSignMessage;
423 CPubKey pubKeyCollateralAddress;
424 CKey keyCollateralAddress;
432 statusObj.
push_back(Pair(
"node", mne.getAlias()));
433 statusObj.
push_back(Pair(
"result",
"failed"));
434 statusObj.
push_back(Pair(
"error",
"Masternode signing error, could not set key correctly."));
443 statusObj.
push_back(Pair(
"node", mne.getAlias()));
444 statusObj.
push_back(Pair(
"result",
"failed"));
445 statusObj.
push_back(Pair(
"error",
"Can't find masternode by pubkey"));
451 if(!vote.
Sign(keyMasternode, pubKeyMasternode)){
453 statusObj.
push_back(Pair(
"node", mne.getAlias()));
454 statusObj.
push_back(Pair(
"result",
"failed"));
455 statusObj.
push_back(Pair(
"error",
"Failure to sign."));
460 std::string strError =
"";
465 statusObj.
push_back(Pair(
"node", mne.getAlias()));
466 statusObj.
push_back(Pair(
"result",
"success"));
470 statusObj.
push_back(Pair(
"node", mne.getAlias()));
471 statusObj.
push_back(Pair(
"result",
"failed"));
472 statusObj.
push_back(Pair(
"error", strError.c_str()));
479 returnObj.
push_back(Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", success, failed)));
480 returnObj.
push_back(Pair(
"detail", resultsObj));
490 if (params.
size() != 1)
491 throw std::runtime_error(
492 "getbudgetvotes \"proposal-name\"\n"
493 "\nPrint vote information for a budget proposal\n"
496 "1. \"proposal-name\": (string, required) Name of the proposal\n"
501 " \"mnId\": \"xxxx\", (string) Hash of the masternode's collateral transaction\n"
502 " \"nHash\": \"xxxx\", (string) Hash of the vote\n"
503 " \"Vote\": \"YES|NO\", (string) Vote cast ('YES' or 'NO')\n"
504 " \"nTime\": xxxx, (numeric) Time in seconds since epoch the vote was cast\n"
505 " \"fValid\": true|false, (boolean) 'true' if the vote is valid, 'false' otherwise\n"
512 std::string strProposalName =
SanitizeString(params[0].get_str());
518 if (pbudgetProposal == NULL)
throw std::runtime_error(
"Unknown proposal name");
520 std::map<uint256, CBudgetVote>::iterator it = pbudgetProposal->
mapVotes.begin();
521 while (it != pbudgetProposal->
mapVotes.end()) {
523 bObj.
push_back(Pair(
"mnId", (*it).second.vin.prevout.hash.ToString()));
524 bObj.
push_back(Pair(
"nHash", (*it).first.ToString().c_str()));
525 bObj.
push_back(Pair(
"Vote", (*it).second.GetVoteString()));
526 bObj.
push_back(Pair(
"nTime", (int64_t)(*it).second.nTime));
527 bObj.
push_back(Pair(
"fValid", (*it).second.fValid));
539 if (fHelp || params.
size() != 0)
540 throw std::runtime_error(
541 "getnextsuperblock\n"
542 "\nPrint the next super block height\n"
545 "n (numeric) Block height of the next super block\n"
550 if (!pindexPrev)
return "unknown";
558 if (fHelp || params.
size() != 0)
559 throw std::runtime_error(
560 "getbudgetprojection\n"
561 "\nShow the projection of which proposals will be paid the next cycle\n"
566 " \"Name\": \"xxxx\", (string) Proposal Name\n"
567 " \"URL\": \"xxxx\", (string) Proposal URL\n"
568 " \"Hash\": \"xxxx\", (string) Proposal vote hash\n"
569 " \"FeeHash\": \"xxxx\", (string) Proposal fee hash\n"
570 " \"BlockStart\": n, (numeric) Proposal starting block\n"
571 " \"BlockEnd\": n, (numeric) Proposal ending block\n"
572 " \"TotalPaymentCount\": n, (numeric) Number of payments\n"
573 " \"RemainingPaymentCount\": n, (numeric) Number of remaining payments\n"
574 " \"PaymentAddress\": \"xxxx\", (string) PRCY address of payment\n"
575 " \"Ratio\": x.xxx, (numeric) Ratio of yeas vs nays\n"
576 " \"Yeas\": n, (numeric) Number of yea votes\n"
577 " \"Nays\": n, (numeric) Number of nay votes\n"
578 " \"Abstains\": n, (numeric) Number of abstains\n"
579 " \"TotalPayment\": xxx.xxx, (numeric) Total payment amount\n"
580 " \"MonthlyPayment\": xxx.xxx, (numeric) Monthly payment amount\n"
581 " \"IsEstablished\": true|false, (boolean) Established (true) or (false)\n"
582 " \"IsValid\": true|false, (boolean) Valid (true) or Invalid (false)\n"
583 " \"IsValidReason\": \"xxxx\", (string) Error message, if any\n"
584 " \"fValid\": true|false, (boolean) Valid (true) or Invalid (false)\n"
585 " \"Alloted\": xxx.xxx, (numeric) Amount alloted in current period\n"
586 " \"TotalBudgetAlloted\": xxx.xxx (numeric) Total alloted\n"
599 nTotalAllotted += pbudgetProposal->GetAllotted();
618 if (fHelp || params.
size() > 1)
619 throw std::runtime_error(
620 "getbudgetinfo ( \"proposal\" )\n"
621 "\nShow current masternode budgets\n"
624 "1. \"proposal\" (string, optional) Proposal name\n"
629 " \"Name\": \"xxxx\", (string) Proposal Name\n"
630 " \"URL\": \"xxxx\", (string) Proposal URL\n"
631 " \"Hash\": \"xxxx\", (string) Proposal vote hash\n"
632 " \"FeeHash\": \"xxxx\", (string) Proposal fee hash\n"
633 " \"BlockStart\": n, (numeric) Proposal starting block\n"
634 " \"BlockEnd\": n, (numeric) Proposal ending block\n"
635 " \"TotalPaymentCount\": n, (numeric) Number of payments\n"
636 " \"RemainingPaymentCount\": n, (numeric) Number of remaining payments\n"
637 " \"PaymentAddress\": \"xxxx\", (string) PRCY address of payment\n"
638 " \"Ratio\": x.xxx, (numeric) Ratio of yeas vs nays\n"
639 " \"Yeas\": n, (numeric) Number of yea votes\n"
640 " \"Nays\": n, (numeric) Number of nay votes\n"
641 " \"Abstains\": n, (numeric) Number of abstains\n"
642 " \"TotalPayment\": xxx.xxx, (numeric) Total payment amount\n"
643 " \"MonthlyPayment\": xxx.xxx, (numeric) Monthly payment amount\n"
644 " \"IsEstablished\": true|false, (boolean) Established (true) or (false)\n"
645 " \"IsValid\": true|false, (boolean) Valid (true) or Invalid (false)\n"
646 " \"IsValidReason\": \"xxxx\", (string) Error message, if any\n"
647 " \"fValid\": true|false, (boolean) Valid (true) or Invalid (false)\n"
656 std::string strShow =
"valid";
657 if (params.
size() == 1) {
658 std::string strProposalName =
SanitizeString(params[0].get_str());
660 if (pbudgetProposal == NULL)
throw std::runtime_error(
"Unknown proposal name");
669 if (strShow ==
"valid" && !pbudgetProposal->fValid)
continue;
682 if (fHelp || params.
size() != 6)
683 throw std::runtime_error(
684 "mnbudgetrawvote \"masternode-tx-hash\" masternode-tx-index \"proposal-hash\" yes|no time \"vote-sig\"\n"
685 "\nCompile and relay a proposal vote with provided external signature instead of signing vote internally\n"
688 "1. \"masternode-tx-hash\" (string, required) Transaction hash for the masternode\n"
689 "2. masternode-tx-index (numeric, required) Output index for the masternode\n"
690 "3. \"proposal-hash\" (string, required) Proposal vote hash\n"
691 "4. yes|no (boolean, required) Vote to cast\n"
692 "5. time (numeric, required) Time since epoch in seconds\n"
693 "6. \"vote-sig\" (string, required) External signature\n"
696 "\"status\" (string) Vote status or error message\n"
701 int nMnTxIndex = params[1].
get_int();
705 std::string strVote = params[3].
get_str();
707 if (strVote !=
"yes" && strVote !=
"no")
return "You can only vote 'yes' or 'no'";
709 if (strVote ==
"yes") nVote =
VOTE_YES;
710 if (strVote ==
"no") nVote =
VOTE_NO;
713 std::string strSig = params[5].
get_str();
714 bool fInvalid =
false;
715 std::vector<unsigned char> vchSig =
DecodeBase64(strSig.c_str(), &fInvalid);
722 return "Failure to find masternode in list : " + vin.
ToString();
730 return "Failure to verify signature.";
733 std::string strError =
"";
737 return "Voted successfully";
739 return "Error voting : " + strError;
745 std::string strCommand;
746 if (params.
size() >= 1)
747 strCommand = params[0].
get_str();
750 (strCommand !=
"suggest" && strCommand !=
"vote-many" && strCommand !=
"vote" && strCommand !=
"show" && strCommand !=
"getvotes"))
751 throw std::runtime_error(
752 "mnfinalbudget \"command\"... ( \"passphrase\" )\n"
753 "Vote or show current budgets\n"
754 "\nAvailable commands:\n"
755 " vote-many - Vote on a finalized budget\n"
756 " vote - Vote on a finalized budget\n"
757 " show - Show existing finalized budgets\n"
758 " getvotes - Get vote information for each finalized budget\n");
760 if (strCommand ==
"vote-many") {
761 if (params.
size() != 2)
762 throw std::runtime_error(
"Correct usage is 'mnfinalbudget vote-many BUDGET_HASH'");
764 std::string strHash = params[1].
get_str();
773 std::vector<unsigned char> vchMasterNodeSignature;
774 std::string strMasterNodeSignMessage;
776 CPubKey pubKeyCollateralAddress;
777 CKey keyCollateralAddress;
785 statusObj.
push_back(Pair(
"result",
"failed"));
786 statusObj.
push_back(Pair(
"errorMessage",
"Masternode signing error, could not set key correctly."));
787 resultsObj.
push_back(Pair(mne.getAlias(), statusObj));
794 statusObj.
push_back(Pair(
"result",
"failed"));
795 statusObj.
push_back(Pair(
"errorMessage",
"Can't find masternode by pubkey"));
796 resultsObj.
push_back(Pair(mne.getAlias(), statusObj));
802 if (!vote.
Sign(keyMasternode, pubKeyMasternode)) {
804 statusObj.
push_back(Pair(
"result",
"failed"));
805 statusObj.
push_back(Pair(
"errorMessage",
"Failure to sign."));
806 resultsObj.
push_back(Pair(mne.getAlias(), statusObj));
810 std::string strError =
"";
815 statusObj.
push_back(Pair(
"result",
"success"));
818 statusObj.
push_back(Pair(
"result", strError.c_str()));
821 resultsObj.
push_back(Pair(mne.getAlias(), statusObj));
825 returnObj.
push_back(Pair(
"overall",
strprintf(
"Voted successfully %d time(s) and failed %d time(s).", success, failed)));
826 returnObj.
push_back(Pair(
"detail", resultsObj));
831 if (strCommand ==
"vote") {
832 if (params.
size() != 2)
833 throw std::runtime_error(
"Correct usage is 'mnfinalbudget vote BUDGET_HASH'");
835 std::string strHash = params[1].
get_str();
842 return "Error upon calling SetKey";
850 if (!vote.
Sign(keyMasternode, pubKeyMasternode)) {
851 return "Failure to sign.";
854 std::string strError =
"";
860 return "Error voting : " + strError;
864 if (strCommand ==
"show") {
870 bObj.
push_back(Pair(
"FeeTX", finalizedBudget->nFeeTXHash.ToString()));
871 bObj.
push_back(Pair(
"Hash", finalizedBudget->GetHash().ToString()));
872 bObj.
push_back(Pair(
"BlockStart", (int64_t)finalizedBudget->GetBlockStart()));
873 bObj.
push_back(Pair(
"BlockEnd", (int64_t)finalizedBudget->GetBlockEnd()));
874 bObj.
push_back(Pair(
"Proposals", finalizedBudget->GetProposals()));
875 bObj.
push_back(Pair(
"VoteCount", (int64_t)finalizedBudget->GetVoteCount()));
876 bObj.
push_back(Pair(
"Status", finalizedBudget->GetStatus()));
878 std::string strError =
"";
879 bObj.
push_back(Pair(
"IsValid", finalizedBudget->IsValid(strError)));
880 bObj.
push_back(Pair(
"IsValidReason", strError.c_str()));
882 resultObj.
push_back(Pair(finalizedBudget->GetName(), bObj));
888 if (strCommand ==
"getvotes") {
889 if (params.
size() != 2)
890 throw std::runtime_error(
"Correct usage is 'mnbudget getvotes budget-hash'");
892 std::string strHash = params[1].
get_str();
899 if (pfinalBudget == NULL)
return "Unknown budget hash";
901 std::map<uint256, CFinalizedBudgetVote>::iterator it = pfinalBudget->
mapVotes.begin();
902 while (it != pfinalBudget->
mapVotes.end()) {
904 bObj.
push_back(Pair(
"nHash", (*it).first.ToString().c_str()));
905 bObj.
push_back(Pair(
"nTime", (int64_t)(*it).second.nTime));
906 bObj.
push_back(Pair(
"fValid", (*it).second.fValid));
908 obj.
push_back(Pair((*it).second.vin.prevout.ToStringShort(), bObj));
921 if (fHelp || params.
size() != 0)
922 throw std::runtime_error(
924 "\nInitiates a budget check cycle manually\n"