2016-02-02 16:28:56 +01:00
// Copyright (c) 2014-2016 The Dash Core developers
2015-04-22 16:33:44 +02:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include "main.h"
# include "db.h"
# include "init.h"
# include "activemasternode.h"
2016-04-15 04:54:11 +02:00
# include "governance.h"
2016-01-24 20:05:31 +01:00
# include "masternode-payments.h"
# include "masternode-sync.h"
2015-04-22 16:33:44 +02:00
# include "masternodeconfig.h"
2016-01-24 20:05:31 +01:00
# include "masternodeman.h"
2015-04-22 16:33:44 +02:00
# include "rpcserver.h"
# include "utilmoneystr.h"
2016-01-28 20:33:10 +01:00
# include <boost/lexical_cast.hpp>
2015-04-22 16:33:44 +02:00
# include <fstream>
2016-02-02 16:28:56 +01:00
# include <univalue.h>
2016-02-04 20:29:09 +01:00
# include <iostream>
# include <sstream>
2016-02-02 16:28:56 +01:00
2015-04-22 16:33:44 +02:00
using namespace std ;
2016-04-17 02:29:41 +02:00
/**
* NOTE : 12.1 - code needs to be rewritten , much of it ' s in the incorrect context
*
* Governance Object Creation and Voting
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* This code allows users to create new types of objects . To correctly use the system
* please see the governance wiki and code - as - law implementation . Any conflicting entries will be
* automatically downvoted and deleted , requiring resubmission to correct .
*
* command structure :
*
* governance prepare new nTypeIn nParentID " name " epoch - start epoch - end parameter1 parameter2 parameter3
* > > fee transaction hash
*
* governance submit fee - hash nTypeIn nParentID , " name " , epoch - start , epoch - end , fee - hash , parameter1 , parameter2 , parameter3
* > > governance object hash
*
*
2016-04-16 23:42:27 +02:00
*/
2016-02-02 16:28:56 +01:00
UniValue mnbudget ( const UniValue & params , bool fHelp )
2015-04-22 16:33:44 +02:00
{
string strCommand ;
if ( params . size ( ) > = 1 )
strCommand = params [ 0 ] . get_str ( ) ;
if ( fHelp | |
2016-02-01 01:44:18 +01:00
( strCommand ! = " vote-many " & & strCommand ! = " vote-alias " & & strCommand ! = " prepare " & & strCommand ! = " submit " & &
2016-04-16 23:42:27 +02:00
strCommand ! = " vote " & & strCommand ! = " getvotes " & & strCommand ! = " getproposal " & &
strCommand ! = " list " & & strCommand ! = " projection " & & strCommand ! = " check " ) )
2015-04-22 16:33:44 +02:00
throw runtime_error (
2015-09-15 18:56:08 +02:00
" mnbudget \" command \" ... \n "
" Manage proposals \n "
2015-04-22 16:33:44 +02:00
" \n Available commands: \n "
2015-09-15 18:56:08 +02:00
" check - Scan proposals and remove invalid from proposals list \n "
" prepare - Prepare proposal by signing and creating tx \n "
" submit - Submit proposal to network \n "
" getproposalhash - Get proposal hash(es) by proposal name \n "
" getproposal - Show proposal \n "
" getvotes - Show detailed votes list for proposal \n "
" list - List all proposals \n "
2015-07-03 19:54:10 +02:00
" projection - Show the projection of which proposals will be paid the next cycle \n "
2015-09-15 18:56:08 +02:00
" vote - Vote on a proposal by single masternode (using dash.conf setup) \n "
" vote-many - Vote on a proposal by all masternodes (using masternode.conf setup) \n "
2016-02-01 01:44:18 +01:00
" vote-alias - Vote on a proposal by alias \n "
2015-04-22 16:33:44 +02:00
) ;
2015-07-10 00:08:26 +02:00
if ( strCommand = = " prepare " )
2015-04-22 16:33:44 +02:00
{
2015-09-15 18:56:08 +02:00
if ( params . size ( ) ! = 7 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget prepare <proposal-name> <url> <payment-count> <block-start> <dash-address> <monthly-payment-dash>' " ) ;
2015-09-15 18:56:08 +02:00
2015-05-04 17:04:09 +02:00
int nBlockMin = 0 ;
2016-03-02 21:57:24 +01:00
LOCK ( cs_main ) ;
CBlockIndex * pindex = chainActive . Tip ( ) ;
2015-05-04 17:04:09 +02:00
2015-05-04 11:31:31 +02:00
std : : vector < CMasternodeConfig : : CMasternodeEntry > mnEntries ;
2015-04-22 16:33:44 +02:00
mnEntries = masternodeConfig . getEntries ( ) ;
2016-04-15 18:39:33 +02:00
std : : string strName = SanitizeString ( params [ 1 ] . get_str ( ) ) ;
2015-09-04 05:44:02 +02:00
std : : string strURL = SanitizeString ( params [ 2 ] . get_str ( ) ) ;
2015-05-04 17:04:09 +02:00
int nBlockStart = params [ 4 ] . get_int ( ) ;
2015-06-16 19:04:35 +02:00
2015-09-15 18:56:08 +02:00
//set block min
2016-03-02 21:57:24 +01:00
if ( pindex ! = NULL ) nBlockMin = pindex - > nHeight ;
2015-06-16 19:04:35 +02:00
2015-05-04 17:04:09 +02:00
if ( nBlockStart < nBlockMin )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid block start, must be more than current height. " ) ;
2015-05-04 17:04:09 +02:00
CBitcoinAddress address ( params [ 5 ] . get_str ( ) ) ;
2015-04-22 16:33:44 +02:00
if ( ! address . IsValid ( ) )
throw JSONRPCError ( RPC_INVALID_ADDRESS_OR_KEY , " Invalid Dash address " ) ;
2015-07-10 00:08:26 +02:00
//*************************************************************************
2015-04-22 16:33:44 +02:00
2015-07-28 17:55:11 +02:00
// create transaction 15 minutes into the future, to allow for confirmation time
2016-04-16 23:42:27 +02:00
CGovernanceObject budgetProposalBroadcast ( strName , strURL , GetTime ( ) , 253370764800 , uint256 ( ) ) ;
2015-07-14 16:05:33 +02:00
std : : string strError = " " ;
2016-03-02 22:20:04 +01:00
if ( ! budgetProposalBroadcast . IsValid ( pindex , strError , false ) )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Proposal is not valid - " + budgetProposalBroadcast . GetHash ( ) . ToString ( ) + " - " + strError ) ;
2015-07-14 16:05:33 +02:00
2015-07-10 00:08:26 +02:00
CWalletTx wtx ;
2016-04-16 23:42:27 +02:00
if ( ! pwalletMain - > GetBudgetSystemCollateralTX ( wtx , budgetProposalBroadcast . GetHash ( ) , false ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Error making collateral transaction for proposal. Please check your wallet balance and make sure your wallet is unlocked. " ) ;
2015-08-04 18:31:05 +02:00
}
2015-04-22 16:33:44 +02:00
2015-07-10 00:08:26 +02:00
// make our change address
CReserveKey reservekey ( pwalletMain ) ;
//send the tx to the network
2016-04-16 23:42:27 +02:00
pwalletMain - > CommitTransaction ( wtx , reservekey , NetMsgType : : TX ) ;
2015-05-04 17:04:09 +02:00
2015-07-30 03:26:21 +02:00
return wtx . GetHash ( ) . ToString ( ) ;
2015-04-22 16:33:44 +02:00
}
2015-07-10 00:08:26 +02:00
if ( strCommand = = " submit " )
2015-04-22 16:33:44 +02:00
{
2015-09-15 18:56:08 +02:00
if ( params . size ( ) ! = 8 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget submit <proposal-name> <url> <payment-count> <block-start> <dash-address> <monthly-payment-dash> <fee-tx>' " ) ;
2015-09-15 18:56:08 +02:00
if ( ! masternodeSync . IsBlockchainSynced ( ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_CLIENT_IN_INITIAL_DOWNLOAD , " Must wait for client to sync with masternode network. Try again in a minute or so. " ) ;
2015-09-15 18:56:08 +02:00
}
2015-05-04 17:04:09 +02:00
int nBlockMin = 0 ;
2016-03-02 21:57:24 +01:00
LOCK ( cs_main ) ;
2016-03-02 22:20:04 +01:00
CBlockIndex * pindex = chainActive . Tip ( ) ;
2015-05-04 17:04:09 +02:00
2015-05-04 11:31:31 +02:00
std : : vector < CMasternodeConfig : : CMasternodeEntry > mnEntries ;
2015-04-22 16:33:44 +02:00
mnEntries = masternodeConfig . getEntries ( ) ;
2016-04-15 18:39:33 +02:00
std : : string strName = SanitizeString ( params [ 1 ] . get_str ( ) ) ;
2015-09-04 05:44:02 +02:00
std : : string strURL = SanitizeString ( params [ 2 ] . get_str ( ) ) ;
2015-06-16 19:04:35 +02:00
2015-09-15 18:56:08 +02:00
//set block min
2016-03-02 22:20:04 +01:00
if ( pindex ! = NULL ) nBlockMin = pindex - > nHeight ;
2015-06-16 19:04:35 +02:00
2016-04-16 23:42:27 +02:00
// create new governance object
2015-04-22 16:33:44 +02:00
2015-09-15 18:56:08 +02:00
uint256 hash = ParseHashV ( params [ 7 ] , " Proposal hash " ) ;
2016-04-16 23:42:27 +02:00
CGovernanceObject budgetProposalBroadcast ( strName , strURL , GetTime ( ) , 253370764800 , uint256 ( ) ) ;
2015-07-10 00:08:26 +02:00
std : : string strError = " " ;
2015-09-15 18:56:08 +02:00
2016-03-02 22:20:04 +01:00
if ( ! budgetProposalBroadcast . IsValid ( pindex , strError ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Proposal is not valid - " + budgetProposalBroadcast . GetHash ( ) . ToString ( ) + " - " + strError ) ;
2015-09-15 18:56:08 +02:00
}
2015-08-06 20:12:35 +02:00
int nConf = 0 ;
2016-04-10 02:43:15 +02:00
if ( ! IsCollateralValid ( hash , budgetProposalBroadcast . GetHash ( ) , strError , budgetProposalBroadcast . nTime , nConf , GOVERNANCE_FEE_TX ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Proposal FeeTX is not valid - " + hash . ToString ( ) + " - " + strError ) ;
2015-07-10 00:08:26 +02:00
}
2016-04-10 16:46:19 +02:00
governance . mapSeenMasternodeBudgetProposals . insert ( make_pair ( budgetProposalBroadcast . GetHash ( ) , budgetProposalBroadcast ) ) ;
2015-07-08 04:35:58 +02:00
budgetProposalBroadcast . Relay ( ) ;
2016-04-10 16:46:19 +02:00
governance . AddProposal ( budgetProposalBroadcast ) ;
2015-05-04 17:04:09 +02:00
2015-07-17 17:52:55 +02:00
return budgetProposalBroadcast . GetHash ( ) . ToString ( ) ;
2015-07-10 00:08:26 +02:00
}
if ( strCommand = = " vote-many " )
{
2015-09-15 18:56:08 +02:00
if ( params . size ( ) ! = 3 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget vote-many <proposal-hash> [yes|no]' " ) ;
2015-07-10 00:08:26 +02:00
2015-09-15 18:56:08 +02:00
uint256 hash ;
std : : string strVote ;
2015-07-10 00:08:26 +02:00
2015-09-15 18:56:08 +02:00
hash = ParseHashV ( params [ 1 ] , " Proposal hash " ) ;
strVote = params [ 2 ] . get_str ( ) ;
2015-07-10 00:08:26 +02:00
2016-04-15 04:14:27 +02:00
int nVote = VOTE_OUTCOME_NONE ;
if ( strVote = = " yes " ) nVote = VOTE_OUTCOME_YES ;
if ( strVote = = " no " ) nVote = VOTE_OUTCOME_NO ;
if ( strVote = = " abstain " ) nVote = VOTE_OUTCOME_ABSTAIN ;
if ( nVote = = VOTE_OUTCOME_NONE )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " You can only vote 'yes', 'no' or 'abstain' " ) ;
2015-07-10 00:08:26 +02:00
int success = 0 ;
int failed = 0 ;
2015-09-15 18:56:08 +02:00
std : : vector < CMasternodeConfig : : CMasternodeEntry > mnEntries ;
mnEntries = masternodeConfig . getEntries ( ) ;
2016-02-02 16:28:56 +01:00
UniValue resultsObj ( UniValue : : VOBJ ) ;
2015-07-10 00:08:26 +02:00
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
std : : string errorMessage ;
std : : vector < unsigned char > vchMasterNodeSignature ;
std : : string strMasterNodeSignMessage ;
CPubKey pubKeyCollateralAddress ;
CKey keyCollateralAddress ;
CPubKey pubKeyMasternode ;
CKey keyMasternode ;
2016-02-02 16:28:56 +01:00
UniValue statusObj ( UniValue : : VOBJ ) ;
2015-07-17 17:52:55 +02:00
2015-07-10 00:08:26 +02:00
if ( ! darkSendSigner . SetKey ( mne . getPrivKey ( ) , errorMessage , keyMasternode , pubKeyMasternode ) ) {
failed + + ;
2015-07-17 17:52:55 +02:00
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
statusObj . push_back ( Pair ( " errorMessage " , " Masternode signing error, could not set key correctly: " + errorMessage ) ) ;
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
2015-07-10 00:08:26 +02:00
continue ;
}
CMasternode * pmn = mnodeman . Find ( pubKeyMasternode ) ;
if ( pmn = = NULL )
{
failed + + ;
2015-07-17 17:52:55 +02:00
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
statusObj . push_back ( Pair ( " errorMessage " , " Can't find masternode by pubkey " ) ) ;
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
2015-07-10 00:08:26 +02:00
continue ;
}
2016-04-15 04:14:27 +02:00
CBudgetVote vote ( pmn - > vin , hash , nVote , VOTE_TYPE_NONE ) ;
2015-07-10 00:08:26 +02:00
if ( ! vote . Sign ( keyMasternode , pubKeyMasternode ) ) {
2015-07-17 17:52:55 +02:00
failed + + ;
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
statusObj . push_back ( Pair ( " errorMessage " , " Failure to sign. " ) ) ;
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
continue ;
2015-07-10 00:08:26 +02:00
}
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
2016-04-10 16:46:19 +02:00
if ( governance . UpdateProposal ( vote , NULL , strError ) ) {
governance . mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
2015-07-26 16:01:49 +02:00
vote . Relay ( ) ;
success + + ;
statusObj . push_back ( Pair ( " result " , " success " ) ) ;
} else {
failed + + ;
statusObj . push_back ( Pair ( " result " , strError . c_str ( ) ) ) ;
}
2015-07-17 17:52:55 +02:00
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
2015-07-10 00:08:26 +02:00
}
2016-02-02 16:28:56 +01:00
UniValue returnObj ( UniValue : : VOBJ ) ;
2015-07-17 17:52:55 +02:00
returnObj . push_back ( Pair ( " overall " , strprintf ( " Voted successfully %d time(s) and failed %d time(s). " , success , failed ) ) ) ;
returnObj . push_back ( Pair ( " detail " , resultsObj ) ) ;
return returnObj ;
2015-07-10 00:08:26 +02:00
}
2016-02-01 01:44:18 +01:00
if ( strCommand = = " vote-alias " )
{
if ( params . size ( ) ! = 4 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget vote-alias <proposal-hash> [yes|no] <alias-name>' " ) ;
2016-02-01 01:44:18 +01:00
uint256 hash ;
std : : string strVote ;
hash = ParseHashV ( params [ 1 ] , " Proposal hash " ) ;
strVote = params [ 2 ] . get_str ( ) ;
std : : string strAlias = params [ 3 ] . get_str ( ) ;
2016-04-15 04:14:27 +02:00
int nVote = VOTE_OUTCOME_NONE ;
if ( strVote = = " yes " ) nVote = VOTE_OUTCOME_YES ;
if ( strVote = = " no " ) nVote = VOTE_OUTCOME_NO ;
if ( strVote = = " abstain " ) nVote = VOTE_OUTCOME_ABSTAIN ;
if ( nVote = = VOTE_OUTCOME_NONE )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " You can only vote 'yes', 'no' or 'abstain' " ) ;
2016-02-01 01:44:18 +01:00
int success = 0 ;
int failed = 0 ;
std : : vector < CMasternodeConfig : : CMasternodeEntry > mnEntries ;
mnEntries = masternodeConfig . getEntries ( ) ;
2016-02-16 01:09:59 +01:00
UniValue resultsObj ( UniValue : : VOBJ ) ;
2016-02-01 01:44:18 +01:00
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
if ( strAlias ! = mne . getAlias ( ) ) continue ;
std : : string errorMessage ;
std : : vector < unsigned char > vchMasterNodeSignature ;
std : : string strMasterNodeSignMessage ;
CPubKey pubKeyCollateralAddress ;
CKey keyCollateralAddress ;
CPubKey pubKeyMasternode ;
CKey keyMasternode ;
2016-02-16 01:09:59 +01:00
UniValue statusObj ( UniValue : : VOBJ ) ;
2016-02-01 01:44:18 +01:00
if ( ! darkSendSigner . SetKey ( mne . getPrivKey ( ) , errorMessage , keyMasternode , pubKeyMasternode ) ) {
failed + + ;
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
statusObj . push_back ( Pair ( " errorMessage " , " Masternode signing error, could not set key correctly: " + errorMessage ) ) ;
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
2015-07-10 00:08:26 +02:00
continue ;
}
CMasternode * pmn = mnodeman . Find ( pubKeyMasternode ) ;
if ( pmn = = NULL )
{
failed + + ;
2015-07-17 17:52:55 +02:00
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
statusObj . push_back ( Pair ( " errorMessage " , " Can't find masternode by pubkey " ) ) ;
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
2015-07-10 00:08:26 +02:00
continue ;
}
2016-04-15 04:14:27 +02:00
CBudgetVote vote ( pmn - > vin , hash , nVote , VOTE_TYPE_NONE ) ;
2015-07-10 00:08:26 +02:00
if ( ! vote . Sign ( keyMasternode , pubKeyMasternode ) ) {
2015-07-17 17:52:55 +02:00
failed + + ;
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
statusObj . push_back ( Pair ( " errorMessage " , " Failure to sign. " ) ) ;
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
continue ;
2015-07-10 00:08:26 +02:00
}
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
2016-04-10 16:46:19 +02:00
if ( governance . UpdateProposal ( vote , NULL , strError ) ) {
governance . mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
2015-07-26 16:01:49 +02:00
vote . Relay ( ) ;
success + + ;
statusObj . push_back ( Pair ( " result " , " success " ) ) ;
} else {
failed + + ;
statusObj . push_back ( Pair ( " result " , strError . c_str ( ) ) ) ;
}
2015-07-17 17:52:55 +02:00
resultsObj . push_back ( Pair ( mne . getAlias ( ) , statusObj ) ) ;
2015-07-10 00:08:26 +02:00
}
2016-02-16 01:09:59 +01:00
UniValue returnObj ( UniValue : : VOBJ ) ;
2015-07-17 17:52:55 +02:00
returnObj . push_back ( Pair ( " overall " , strprintf ( " Voted successfully %d time(s) and failed %d time(s). " , success , failed ) ) ) ;
returnObj . push_back ( Pair ( " detail " , resultsObj ) ) ;
return returnObj ;
2015-07-10 00:08:26 +02:00
}
if ( strCommand = = " vote " )
{
if ( params . size ( ) ! = 3 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget vote <proposal-hash> [yes|no]' " ) ;
2015-07-10 00:08:26 +02:00
2015-09-15 18:56:08 +02:00
uint256 hash = ParseHashV ( params [ 1 ] , " Proposal hash " ) ;
2015-07-17 17:52:55 +02:00
std : : string strVote = params [ 2 ] . get_str ( ) ;
2015-07-10 00:08:26 +02:00
2016-04-15 04:14:27 +02:00
int nVote = VOTE_OUTCOME_NONE ;
if ( strVote = = " yes " ) nVote = VOTE_OUTCOME_YES ;
if ( strVote = = " no " ) nVote = VOTE_OUTCOME_NO ;
if ( strVote = = " abstain " ) nVote = VOTE_OUTCOME_ABSTAIN ;
if ( nVote = = VOTE_OUTCOME_NONE )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " You can only vote 'yes', 'no' or 'abstain' " ) ;
2015-07-10 00:08:26 +02:00
CPubKey pubKeyMasternode ;
CKey keyMasternode ;
std : : string errorMessage ;
if ( ! darkSendSigner . SetKey ( strMasterNodePrivKey , errorMessage , keyMasternode , pubKeyMasternode ) )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Error upon calling SetKey " ) ;
2015-07-10 00:08:26 +02:00
2015-08-04 18:31:05 +02:00
CMasternode * pmn = mnodeman . Find ( activeMasternode . vin ) ;
if ( pmn = = NULL )
{
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Failure to find masternode in list : " + activeMasternode . vin . ToString ( ) ) ;
2015-08-04 18:31:05 +02:00
}
2016-04-15 04:14:27 +02:00
CBudgetVote vote ( activeMasternode . vin , hash , nVote , VOTE_TYPE_NONE ) ;
2015-04-22 16:33:44 +02:00
if ( ! vote . Sign ( keyMasternode , pubKeyMasternode ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Failure to sign. " ) ;
2015-04-22 16:33:44 +02:00
}
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
2016-04-10 16:46:19 +02:00
if ( governance . UpdateProposal ( vote , NULL , strError ) ) {
governance . mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
2015-07-26 16:01:49 +02:00
vote . Relay ( ) ;
return " Voted successfully " ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Error voting : " + strError ) ;
2015-07-26 16:01:49 +02:00
}
2015-04-22 16:33:44 +02:00
}
2015-09-15 18:56:08 +02:00
if ( strCommand = = " list " )
2015-07-03 19:54:10 +02:00
{
2015-09-15 18:56:08 +02:00
if ( params . size ( ) > 2 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget list [valid]' " ) ;
2015-09-15 18:56:08 +02:00
2015-07-15 00:52:07 +02:00
std : : string strShow = " valid " ;
2015-09-15 18:56:08 +02:00
if ( params . size ( ) = = 2 ) strShow = params [ 1 ] . get_str ( ) ;
2016-04-15 04:14:27 +02:00
UniValue resultObj ( UniValue : : VOBJ ) ;
2016-03-02 22:20:04 +01:00
CBlockIndex * pindex ;
{
LOCK ( cs_main ) ;
pindex = chainActive . Tip ( ) ;
}
2016-04-16 19:19:17 +02:00
std : : vector < CGovernanceObject * > winningProps = governance . GetAllProposals ( ) ;
BOOST_FOREACH ( CGovernanceObject * pbudgetProposal , winningProps )
2015-07-03 19:54:10 +02:00
{
2015-07-15 00:52:07 +02:00
if ( strShow = = " valid " & & ! pbudgetProposal - > fValid ) continue ;
2016-02-02 16:28:56 +01:00
UniValue bObj ( UniValue : : VOBJ ) ;
2015-08-29 08:01:12 +02:00
bObj . push_back ( Pair ( " Name " , pbudgetProposal - > GetName ( ) ) ) ;
2015-07-08 04:35:58 +02:00
bObj . push_back ( Pair ( " URL " , pbudgetProposal - > GetURL ( ) ) ) ;
2015-07-17 17:52:55 +02:00
bObj . push_back ( Pair ( " Hash " , pbudgetProposal - > GetHash ( ) . ToString ( ) ) ) ;
2016-03-15 01:52:49 +01:00
bObj . push_back ( Pair ( " FeeTXHash " , pbudgetProposal - > nFeeTXHash . ToString ( ) ) ) ;
2016-04-15 04:14:27 +02:00
bObj . push_back ( Pair ( " StartTime " , ( int64_t ) pbudgetProposal - > GetStartTime ( ) ) ) ;
bObj . push_back ( Pair ( " EndTime " , ( int64_t ) pbudgetProposal - > GetEndTime ( ) ) ) ;
2016-01-29 21:41:04 +01:00
bObj . push_back ( Pair ( " AbsoluteYesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( ) - ( int64_t ) pbudgetProposal - > GetNoCount ( ) ) ) ;
bObj . push_back ( Pair ( " YesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( ) ) ) ;
bObj . push_back ( Pair ( " NoCount " , ( int64_t ) pbudgetProposal - > GetNoCount ( ) ) ) ;
bObj . push_back ( Pair ( " AbstainCount " , ( int64_t ) pbudgetProposal - > GetAbstainCount ( ) ) ) ;
2015-07-28 17:55:11 +02:00
bObj . push_back ( Pair ( " IsEstablished " , pbudgetProposal - > IsEstablished ( ) ) ) ;
2015-07-04 16:49:49 +02:00
std : : string strError = " " ;
2016-03-02 22:20:04 +01:00
bObj . push_back ( Pair ( " IsValid " , pbudgetProposal - > IsValid ( pindex , strError ) ) ) ;
2015-07-28 17:55:11 +02:00
bObj . push_back ( Pair ( " IsValidReason " , strError . c_str ( ) ) ) ;
2015-07-17 17:52:55 +02:00
bObj . push_back ( Pair ( " fValid " , pbudgetProposal - > fValid ) ) ;
2015-07-04 16:49:49 +02:00
2015-07-17 17:52:55 +02:00
resultObj . push_back ( Pair ( pbudgetProposal - > GetName ( ) , bObj ) ) ;
2015-07-03 19:54:10 +02:00
}
return resultObj ;
}
2015-09-15 18:56:08 +02:00
if ( strCommand = = " getproposal " )
{
if ( params . size ( ) ! = 2 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget getproposal <proposal-hash>' " ) ;
2015-09-15 18:56:08 +02:00
uint256 hash = ParseHashV ( params [ 1 ] , " Proposal hash " ) ;
2016-04-16 19:19:17 +02:00
CGovernanceObject * pbudgetProposal = governance . FindProposal ( hash ) ;
2015-09-15 18:56:08 +02:00
2016-03-15 01:52:49 +01:00
if ( pbudgetProposal = = NULL )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Unknown proposal " ) ;
2015-04-22 16:33:44 +02:00
2016-03-08 18:09:43 +01:00
CBlockIndex * pindex ;
{
LOCK ( cs_main ) ;
pindex = chainActive . Tip ( ) ;
}
2016-03-02 22:20:04 +01:00
LOCK ( cs_main ) ;
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2015-07-17 17:52:55 +02:00
obj . push_back ( Pair ( " Name " , pbudgetProposal - > GetName ( ) ) ) ;
obj . push_back ( Pair ( " Hash " , pbudgetProposal - > GetHash ( ) . ToString ( ) ) ) ;
2016-03-15 01:52:49 +01:00
obj . push_back ( Pair ( " FeeTXHash " , pbudgetProposal - > nFeeTXHash . ToString ( ) ) ) ;
2015-07-17 17:52:55 +02:00
obj . push_back ( Pair ( " URL " , pbudgetProposal - > GetURL ( ) ) ) ;
2016-04-15 04:14:27 +02:00
obj . push_back ( Pair ( " StartTime " , ( int64_t ) pbudgetProposal - > GetStartTime ( ) ) ) ;
obj . push_back ( Pair ( " EndTime " , ( int64_t ) pbudgetProposal - > GetEndTime ( ) ) ) ;
2016-01-29 21:41:04 +01:00
obj . push_back ( Pair ( " AbsoluteYesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( ) - ( int64_t ) pbudgetProposal - > GetNoCount ( ) ) ) ;
obj . push_back ( Pair ( " YesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( ) ) ) ;
obj . push_back ( Pair ( " NoCount " , ( int64_t ) pbudgetProposal - > GetNoCount ( ) ) ) ;
2016-04-16 23:42:27 +02:00
obj . push_back ( Pair ( " AbstainCount " , ( int64_t ) pbudgetProposal - > GetAbstainCount ( ) ) ) ;
2015-07-28 17:55:11 +02:00
obj . push_back ( Pair ( " IsEstablished " , pbudgetProposal - > IsEstablished ( ) ) ) ;
2015-07-07 00:06:09 +02:00
std : : string strError = " " ;
2016-03-02 22:20:04 +01:00
obj . push_back ( Pair ( " IsValid " , pbudgetProposal - > IsValid ( chainActive . Tip ( ) , strError ) ) ) ;
2015-07-17 17:52:55 +02:00
obj . push_back ( Pair ( " fValid " , pbudgetProposal - > fValid ) ) ;
2015-07-07 00:06:09 +02:00
2015-04-22 16:33:44 +02:00
return obj ;
}
if ( strCommand = = " getvotes " )
{
if ( params . size ( ) ! = 2 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mnbudget getvotes <proposal-hash>' " ) ;
2015-04-22 16:33:44 +02:00
2015-09-15 18:56:08 +02:00
uint256 hash = ParseHashV ( params [ 1 ] , " Proposal hash " ) ;
2015-04-22 16:33:44 +02:00
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2015-07-06 22:23:09 +02:00
2016-04-16 19:19:17 +02:00
CGovernanceObject * pbudgetProposal = governance . FindProposal ( hash ) ;
2015-04-22 16:33:44 +02:00
2016-03-15 01:52:49 +01:00
if ( pbudgetProposal = = NULL )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Unknown proposal " ) ;
2015-04-22 16:33:44 +02:00
2016-04-15 04:14:27 +02:00
// 12.1 - rewrite
// std::map<uint256, CBudgetVote>::iterator it = pbudgetProposal->mapVotes.begin();
// while(it != pbudgetProposal->mapVotes.end()){
2015-07-17 16:38:35 +02:00
2016-04-15 04:14:27 +02:00
// UniValue bObj(UniValue::VOBJ);
// bObj.push_back(Pair("nHash", (*it).first.ToString().c_str()));
// bObj.push_back(Pair("Vote", (*it).second.GetVoteString()));
// bObj.push_back(Pair("nTime", (int64_t)(*it).second.nTime));
// bObj.push_back(Pair("fValid", (*it).second.fValid));
2015-07-17 16:38:35 +02:00
2016-04-15 04:14:27 +02:00
// obj.push_back(Pair((*it).second.vin.prevout.ToStringShort(), bObj));
2015-07-17 16:38:35 +02:00
2016-04-15 04:14:27 +02:00
// it++;
// }
2015-07-06 22:23:09 +02:00
2015-04-22 16:33:44 +02:00
return obj ;
}
2016-02-02 16:28:56 +01:00
return NullUniValue ;
2015-04-22 16:33:44 +02:00
}
2016-02-02 16:28:56 +01:00
UniValue mnbudgetvoteraw ( const UniValue & params , bool fHelp )
2015-09-23 02:15:23 +02:00
{
if ( fHelp | | params . size ( ) ! = 6 )
throw runtime_error (
2016-03-15 01:52:49 +01:00
" mnbudgetvoteraw <masternode-tx-hash> <masternode-tx-index> <proposal-hash> [yes|no] <time> <vote-sig> \n "
2015-09-23 02:15:23 +02:00
" Compile and relay a proposal vote with provided external signature instead of signing vote internally \n "
) ;
uint256 hashMnTx = ParseHashV ( params [ 0 ] , " mn tx hash " ) ;
int nMnTxIndex = params [ 1 ] . get_int ( ) ;
CTxIn vin = CTxIn ( hashMnTx , nMnTxIndex ) ;
uint256 hashProposal = ParseHashV ( params [ 2 ] , " Proposal hash " ) ;
std : : string strVote = params [ 3 ] . get_str ( ) ;
2016-04-15 04:14:27 +02:00
int nVote = VOTE_OUTCOME_NONE ;
if ( strVote = = " yes " ) nVote = VOTE_OUTCOME_YES ;
if ( strVote = = " no " ) nVote = VOTE_OUTCOME_NO ;
if ( strVote = = " abstain " ) nVote = VOTE_OUTCOME_ABSTAIN ;
if ( nVote = = VOTE_OUTCOME_NONE )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " You can only vote 'yes', 'no' or 'abstain' " ) ;
2015-09-23 02:15:23 +02:00
int64_t nTime = params [ 4 ] . get_int64 ( ) ;
std : : string strSig = params [ 5 ] . get_str ( ) ;
bool fInvalid = false ;
vector < unsigned char > vchSig = DecodeBase64 ( strSig . c_str ( ) , & fInvalid ) ;
if ( fInvalid )
throw JSONRPCError ( RPC_INVALID_ADDRESS_OR_KEY , " Malformed base64 encoding " ) ;
CMasternode * pmn = mnodeman . Find ( vin ) ;
if ( pmn = = NULL )
{
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Failure to find masternode in list : " + vin . ToString ( ) ) ;
2015-09-23 02:15:23 +02:00
}
2016-04-15 04:14:27 +02:00
CBudgetVote vote ( vin , hashProposal , nVote , VOTE_TYPE_NONE ) ;
2015-09-23 02:15:23 +02:00
vote . nTime = nTime ;
vote . vchSig = vchSig ;
2016-03-06 16:44:58 +01:00
if ( ! vote . IsValid ( true ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Failure to verify vote. " ) ;
2015-09-23 02:15:23 +02:00
}
std : : string strError = " " ;
2016-04-10 16:46:19 +02:00
if ( governance . UpdateProposal ( vote , NULL , strError ) ) {
governance . mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
2015-09-23 02:15:23 +02:00
vote . Relay ( ) ;
return " Voted successfully " ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Error voting : " + strError ) ;
2015-09-23 02:15:23 +02:00
}
2016-04-14 23:28:33 +02:00
}