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-05-19 20:34:43 +02:00
int ConvertVoteOutcome ( std : : string strVoteAction )
2016-04-26 20:27:22 +02:00
{
int nVote = - 1 ;
if ( strVoteAction = = " yes " ) nVote = VOTE_OUTCOME_YES ;
if ( strVoteAction = = " no " ) nVote = VOTE_OUTCOME_NO ;
if ( strVoteAction = = " abstain " ) nVote = VOTE_OUTCOME_ABSTAIN ;
if ( strVoteAction = = " none " ) nVote = VOTE_OUTCOME_NONE ;
return nVote ;
}
2016-05-19 20:34:43 +02:00
int ConvertVoteAction ( std : : string strVoteOutcome )
2016-04-26 20:27:22 +02:00
{
if ( strVoteOutcome = = " none " ) return 0 ;
if ( strVoteOutcome = = " funding " ) return 1 ;
if ( strVoteOutcome = = " valid " ) return 2 ;
if ( strVoteOutcome = = " delete " ) return 3 ;
if ( strVoteOutcome = = " clear_registers " ) return 4 ;
if ( strVoteOutcome = = " endorsed " ) return 5 ;
if ( strVoteOutcome = = " release_bounty1 " ) return 6 ;
if ( strVoteOutcome = = " release_bounty2 " ) return 7 ;
if ( strVoteOutcome = = " release_bounty3 " ) return 8 ;
// convert custom sentinel outcomes to integer and store
try {
2016-05-07 00:36:11 +02:00
int i = boost : : lexical_cast < int > ( strVoteOutcome ) ;
2016-04-26 20:27:22 +02:00
if ( i < VOTE_ACTION_CUSTOM_START | | i > VOTE_ACTION_CUSTOM_END ) return - 1 ;
return i ;
}
catch ( std : : exception const & e )
{
cout < < " error : " < < e . what ( ) < < endl ;
}
return - 1 ;
}
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 :
*
2016-04-19 18:51:15 +02:00
* For instructions on creating registers , see dashbrain
*
*
* governance prepare new nTypeIn nParentID " name " epoch - start epoch - end register1 register2 register3
2016-04-17 02:29:41 +02:00
* > > fee transaction hash
*
2016-04-19 18:51:15 +02:00
* governance submit fee - hash nTypeIn nParentID , " name " , epoch - start , epoch - end , fee - hash , register1 , register2 , register3
2016-04-17 02:29:41 +02:00
* > > governance object hash
2016-04-19 18:51:15 +02:00
*
* governance vote ( - alias | many ) type hash yes | no | abstain
* > > success | failure
*
* governance list
* > > flat data representation of the governance system
* > > NOTE : this shouldn ' t be altered , we ' ll analyze the system outside of this project
2016-04-17 02:29:41 +02:00
*
2016-04-19 18:51:15 +02:00
* governance get hash
* > > show one proposal
2016-04-17 02:29:41 +02:00
*
2016-04-16 23:42:27 +02:00
*/
2016-04-19 18:51:15 +02:00
UniValue mngovernance ( 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-19 18:51:15 +02:00
strCommand ! = " vote " & & strCommand ! = " get " & & strCommand ! = " list " & & strCommand ! = " diff " ) )
2015-04-22 16:33:44 +02:00
throw runtime_error (
2016-04-19 18:51:15 +02:00
" mngovernance \" command \" ... \n "
2015-09-15 18:56:08 +02:00
" Manage proposals \n "
2015-04-22 16:33:44 +02:00
" \n Available commands: \n "
2015-09-15 18:56:08 +02:00
" prepare - Prepare proposal by signing and creating tx \n "
" submit - Submit proposal to network \n "
2016-04-19 18:51:15 +02:00
" get - Get proposal hash(es) by proposal name \n "
2015-09-15 18:56:08 +02:00
" list - List all proposals \n "
2016-04-19 18:51:15 +02:00
" diff - List differences since last diff \n "
2016-05-19 20:34:43 +02:00
" vote-alias - Vote on a governance object by masternode 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
{
2016-05-09 17:32:47 +02:00
if ( params . size ( ) ! = 6 )
2016-04-26 06:08:36 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mngovernance prepare <parent-hash> <revision> <time> <name> <registers-hex>' " ) ;
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-05-09 17:32:47 +02:00
uint256 hashParent ;
if ( params [ 1 ] . get_str ( ) = = " 0 " ) { // attach to root node (root node doesn't really exist, but has a hash of zero)
hashParent = uint256 ( ) ;
} else {
hashParent = ParseHashV ( params [ 1 ] , " fee-tx hash, parameter 1 " ) ;
}
2015-04-22 16:33:44 +02:00
2016-05-09 17:32:47 +02:00
std : : string strRevision = params [ 2 ] . get_str ( ) ;
std : : string strTime = params [ 3 ] . get_str ( ) ;
int nRevision = boost : : lexical_cast < int > ( strRevision ) ;
int nTime = boost : : lexical_cast < int > ( strTime ) ;
std : : string strName = SanitizeString ( params [ 4 ] . get_str ( ) ) ;
std : : string strRegisters = params [ 5 ] . get_str ( ) ;
2016-04-26 06:08:36 +02:00
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-26 13:42:34 +02:00
CGovernanceObject budgetProposalBroadcast ( hashParent , nRevision , strName , nTime , 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-05-09 17:32:47 +02:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Governance object 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
{
2016-05-19 20:34:43 +02:00
printf ( " %d \n " , ( int ) params . size ( ) ) ;
2016-05-09 17:32:47 +02:00
if ( params . size ( ) ! = 7 )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mngovernance submit <fee-tx> <parent-hash> <revision> <time> <name> <registers-hex>' " ) ;
2015-09-15 18:56:08 +02:00
2016-04-26 06:08:36 +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-05-09 17:32:47 +02:00
uint256 fee_tx = ParseHashV ( params [ 1 ] , " fee-tx hash, parameter 1 " ) ;
2016-05-13 18:03:01 +02:00
uint256 hashParent ;
if ( params [ 2 ] . get_str ( ) = = " 0 " ) { // attach to root node (root node doesn't really exist, but has a hash of zero)
hashParent = uint256 ( ) ;
} else {
hashParent = ParseHashV ( params [ 2 ] , " parent object hash, parameter 2 " ) ;
}
2015-06-16 19:04:35 +02:00
2016-05-09 17:32:47 +02:00
std : : string strRevision = params [ 3 ] . get_str ( ) ;
std : : string strTime = params [ 4 ] . get_str ( ) ;
int nRevision = boost : : lexical_cast < int > ( strRevision ) ;
int nTime = boost : : lexical_cast < int > ( strTime ) ;
std : : string strName = SanitizeString ( params [ 5 ] . get_str ( ) ) ;
std : : string strRegisters = params [ 6 ] . get_str ( ) ;
2015-04-22 16:33:44 +02:00
2016-05-13 18:03:01 +02:00
CGovernanceObject budgetProposalBroadcast ( hashParent , nRevision , strName , nTime , fee_tx ) ;
2015-07-10 00:08:26 +02:00
std : : string strError = " " ;
2016-03-02 22:20:04 +01:00
if ( ! budgetProposalBroadcast . IsValid ( pindex , strError ) ) {
2016-05-09 17:32:47 +02:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Governance object is not valid - " + budgetProposalBroadcast . GetHash ( ) . ToString ( ) + " - " + strError ) ;
2015-09-15 18:56:08 +02:00
}
2016-04-26 13:44:48 +02:00
// int nConf = 0;
// if(!IsCollateralValid(hash, budgetProposalBroadcast.GetHash(), strError, budgetProposalBroadcast.nTime, nConf, GOVERNANCE_FEE_TX)){
// throw JSONRPCError(RPC_INTERNAL_ERROR, "Proposal FeeTX is not valid - " + hash.ToString() + " - " + strError);
// }
2015-07-10 00:08:26 +02:00
2016-05-13 18:03:01 +02:00
governance . mapSeenMasternodeBudgetProposals . insert ( make_pair ( budgetProposalBroadcast . GetHash ( ) , SEEN_OBJECT_IS_VALID ) ) ;
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
}
2016-02-01 01:44:18 +01:00
if ( strCommand = = " vote-alias " )
{
2016-05-19 20:34:43 +02:00
if ( params . size ( ) ! = 5 )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mngovernance vote-alias <governance-hash> [funding|valid|delete] [yes|no|abstain] <alias-name>' " ) ;
2016-02-01 01:44:18 +01:00
uint256 hash ;
std : : string strVote ;
2016-04-26 06:08:36 +02:00
hash = ParseHashV ( params [ 1 ] , " Object hash " ) ;
2016-05-19 20:34:43 +02:00
std : : string strVoteAction = params [ 2 ] . get_str ( ) ;
std : : string strVoteOutcome = params [ 3 ] . get_str ( ) ;
std : : string strAlias = params [ 4 ] . get_str ( ) ;
2016-04-26 20:27:22 +02:00
int nVoteAction = ConvertVoteAction ( strVoteAction ) ;
if ( nVoteAction = = VOTE_OUTCOME_NONE | | nVoteAction = = - 1 )
2016-04-26 20:36:07 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain' " ) ;
2016-04-26 20:27:22 +02:00
int nVoteOutcome = ConvertVoteOutcome ( strVoteOutcome ) ;
if ( nVoteOutcome = = VOTE_OUTCOME_NONE | | nVoteAction = = - 1 )
2016-04-26 20:36:07 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid vote action. Please using one of the following: (funding|valid|delete|clear_registers|endorsed|release_bounty1|release_bounty2|release_bounty3) OR ` custom sentinel code ` " ) ;
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-26 06:08:36 +02:00
CBudgetVote vote ( pmn - > vin , hash , nVoteOutcome , nVoteAction ) ;
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 ) ) {
2016-05-13 18:03:01 +02:00
governance . mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , SEEN_OBJECT_IS_VALID ) ) ;
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
}
2016-04-19 18:51:15 +02:00
if ( strCommand = = " list " | | strCommand = = " diff " )
2015-07-03 19:54:10 +02:00
{
2015-09-15 18:56:08 +02:00
if ( params . size ( ) > 2 )
2016-04-19 18:51:15 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mngovernance 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-05-13 18:03:01 +02:00
int nStartTime = 0 ; //list
if ( strCommand = = " diff " ) nStartTime = governance . GetLastDiffTime ( ) ;
std : : vector < CGovernanceObject * > winningProps = governance . GetAllProposals ( nStartTime ) ;
2016-04-19 18:51:15 +02:00
governance . UpdateLastDiffTime ( GetTime ( ) ) ;
2016-05-13 18:03:01 +02:00
2016-04-16 19:19:17 +02:00
BOOST_FOREACH ( CGovernanceObject * pbudgetProposal , winningProps )
2015-07-03 19:54:10 +02:00
{
2016-05-13 18:03:01 +02:00
if ( strShow = = " valid " & & ! pbudgetProposal - > fCachedValid ) continue ;
2015-07-15 00:52:07 +02:00
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-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-26 06:08:36 +02:00
// vote data for funding
bObj . push_back ( Pair ( " AbsoluteYesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( VOTE_ACTION_FUNDING ) - ( int64_t ) pbudgetProposal - > GetNoCount ( VOTE_ACTION_FUNDING ) ) ) ;
bObj . push_back ( Pair ( " YesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( VOTE_ACTION_FUNDING ) ) ) ;
bObj . push_back ( Pair ( " NoCount " , ( int64_t ) pbudgetProposal - > GetNoCount ( VOTE_ACTION_FUNDING ) ) ) ;
bObj . push_back ( Pair ( " AbstainCount " , ( int64_t ) pbudgetProposal - > GetAbstainCount ( VOTE_ACTION_FUNDING ) ) ) ;
2016-05-13 18:03:01 +02:00
//bObj.push_back(Pair("IsEstablished", pbudgetProposal->IsEstablished(VOTE_ACTION_FUNDING)));
2015-07-28 17:55:11 +02:00
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 ( ) ) ) ;
2016-05-13 18:03:01 +02:00
bObj . push_back ( Pair ( " fCachedValid " , pbudgetProposal - > fCachedValid ) ) ;
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-04-19 18:51:15 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'mngovernance 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 ( ) ) ) ;
2016-04-26 20:27:22 +02:00
obj . push_back ( Pair ( " AbsoluteYesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( VOTE_ACTION_FUNDING ) - ( int64_t ) pbudgetProposal - > GetNoCount ( VOTE_ACTION_FUNDING ) ) ) ;
obj . push_back ( Pair ( " YesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( VOTE_ACTION_FUNDING ) ) ) ;
obj . push_back ( Pair ( " NoCount " , ( int64_t ) pbudgetProposal - > GetNoCount ( VOTE_ACTION_FUNDING ) ) ) ;
obj . push_back ( Pair ( " AbstainCount " , ( int64_t ) pbudgetProposal - > GetAbstainCount ( VOTE_ACTION_FUNDING ) ) ) ;
2015-07-28 17:55:11 +02:00
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 ) ) ) ;
2016-05-13 18:03:01 +02:00
obj . push_back ( Pair ( " fValid " , pbudgetProposal - > fCachedValid ) ) ;
2015-07-07 00:06:09 +02:00
2015-04-22 16:33:44 +02:00
return obj ;
}
if ( strCommand = = " getvotes " )
{
2016-04-26 20:27:22 +02:00
if ( params . size ( ) ! = 3 )
throw runtime_error (
2016-04-26 20:34:53 +02:00
" Correct usage is 'mngovernance getvotes <governance-hash> <vote-outcome>' "
2016-04-26 20:27:22 +02:00
) ;
2015-04-22 16:33:44 +02:00
2016-04-26 20:27:22 +02:00
uint256 hash = ParseHashV ( params [ 1 ] , " Governance hash " ) ;
std : : string strVoteOutcome = params [ 2 ] . get_str ( ) ;
int nVoteOutcome = ConvertVoteOutcome ( strVoteOutcome ) ;
if ( nVoteOutcome = = - 1 )
{
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid vote outcome. Please using one of the following: (funding|valid|delete|clear_registers|endorsed|release_bounty1|release_bounty2|release_bounty3) OR ` custom sentinel code ` " ) ;
}
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 )
2016-04-26 20:27:22 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Unknown governance-hash " ) ;
2015-07-17 16:38:35 +02:00
2016-04-26 20:27:22 +02:00
UniValue bObj ( UniValue : : VOBJ ) ;
bObj . push_back ( Pair ( " AbsoluteYesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( nVoteOutcome ) - ( int64_t ) pbudgetProposal - > GetNoCount ( nVoteOutcome ) ) ) ;
bObj . push_back ( Pair ( " YesCount " , ( int64_t ) pbudgetProposal - > GetYesCount ( nVoteOutcome ) ) ) ;
bObj . push_back ( Pair ( " NoCount " , ( int64_t ) pbudgetProposal - > GetNoCount ( nVoteOutcome ) ) ) ;
bObj . push_back ( Pair ( " AbstainCount " , ( int64_t ) pbudgetProposal - > GetAbstainCount ( nVoteOutcome ) ) ) ;
2015-07-17 16:38:35 +02:00
2016-04-26 20:27:22 +02:00
return bObj ;
2015-04-22 16:33:44 +02:00
}
2016-02-02 16:28:56 +01:00
return NullUniValue ;
2015-04-22 16:33:44 +02:00
}
2016-05-05 19:44:46 +02:00
UniValue voteraw ( const UniValue & params , bool fHelp )
2015-09-23 02:15:23 +02:00
{
if ( fHelp | | params . size ( ) ! = 6 )
throw runtime_error (
2016-05-05 19:44:46 +02:00
" voteraw <masternode-tx-hash> <masternode-tx-index> <governance-hash> <vote-outcome> [yes|no|abstain] <time> <vote-sig> \n "
2016-04-26 20:27:22 +02:00
" Compile and relay a governance vote with provided external signature instead of signing vote internally \n "
2015-09-23 02:15:23 +02:00
) ;
uint256 hashMnTx = ParseHashV ( params [ 0 ] , " mn tx hash " ) ;
int nMnTxIndex = params [ 1 ] . get_int ( ) ;
CTxIn vin = CTxIn ( hashMnTx , nMnTxIndex ) ;
2016-04-26 20:34:53 +02:00
uint256 hashProposal = ParseHashV ( params [ 2 ] , " Governance hash " ) ;
std : : string strVoteAction = params [ 3 ] . get_str ( ) ;
std : : string strVoteOutcome = params [ 4 ] . get_str ( ) ;
int nVoteAction = ConvertVoteAction ( strVoteAction ) ;
if ( nVoteAction = = VOTE_OUTCOME_NONE | | nVoteAction = = - 1 )
2016-04-26 20:36:07 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain' " ) ;
2016-04-26 20:34:53 +02:00
int nVoteOutcome = ConvertVoteOutcome ( strVoteOutcome ) ;
if ( nVoteOutcome = = VOTE_OUTCOME_NONE | | nVoteAction = = - 1 )
2016-04-26 20:36:07 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid vote action. Please using one of the following: (funding|valid|delete|clear_registers|endorsed|release_bounty1|release_bounty2|release_bounty3) OR ` custom sentinel code ` " ) ;
2015-09-23 02:15:23 +02:00
2016-04-15 04:14:27 +02:00
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-26 20:34:53 +02:00
CBudgetVote vote ( vin , hashProposal , nVoteOutcome , VOTE_ACTION_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 ) ) {
2016-05-13 18:03:01 +02:00
governance . mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , SEEN_OBJECT_IS_VALID ) ) ;
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-05-07 00:36:11 +02:00
}