2014-12-09 02:17:57 +01:00
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// 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"
2014-12-06 20:41:53 +01:00
# include "masternodeconfig.h"
2016-01-24 20:05:31 +01:00
# include "masternodeman.h"
2014-12-09 02:17:57 +01:00
# include "rpcserver.h"
2015-04-03 00:51:08 +02:00
# include "utilmoneystr.h"
2014-12-09 02:17:57 +01:00
# include <fstream>
2016-02-02 16:28:56 +01:00
# include <iomanip>
# include <univalue.h>
2014-12-09 02:17:57 +01:00
2016-05-25 07:25:16 +02:00
UniValue privatesend ( const UniValue & params , bool fHelp )
2014-12-09 02:17:57 +01:00
{
2016-02-01 18:22:00 +01:00
if ( fHelp | | params . size ( ) ! = 1 )
2014-12-09 02:17:57 +01:00
throw runtime_error (
2016-05-25 07:25:16 +02:00
" privatesend \" command \" \n "
2016-02-01 18:22:00 +01:00
" \n Arguments: \n "
" 1. \" command \" (string or set of strings, required) The command to execute \n "
" \n Available commands: \n "
" start - Start mixing \n "
" stop - Stop mixing \n "
" reset - Reset mixing \n "
" status - Print mixing status \n "
2014-12-09 02:17:57 +01:00
+ HelpRequiringPassphrase ( ) ) ;
2016-02-01 18:22:00 +01:00
if ( params [ 0 ] . get_str ( ) = = " start " ) {
if ( pwalletMain - > IsLocked ( ) )
throw JSONRPCError ( RPC_WALLET_UNLOCK_NEEDED , " Error: Please enter the wallet passphrase with walletpassphrase first. " ) ;
2014-12-09 02:17:57 +01:00
2014-12-30 01:09:34 +01:00
if ( fMasterNode )
2016-02-01 18:22:00 +01:00
return " Mixing is not supported from masternodes " ;
2014-12-30 01:09:34 +01:00
2016-05-25 07:25:16 +02:00
fEnablePrivateSend = true ;
2016-02-01 18:22:00 +01:00
bool result = darkSendPool . DoAutomaticDenominating ( ) ;
return " Mixing " + ( result ? " started successfully " : ( " start failed: " + darkSendPool . GetStatus ( ) + " , will retry " ) ) ;
}
if ( params [ 0 ] . get_str ( ) = = " stop " ) {
2016-05-25 07:25:16 +02:00
fEnablePrivateSend = false ;
2016-02-01 18:22:00 +01:00
return " Mixing was stopped " ;
2014-12-09 02:17:57 +01:00
}
if ( params [ 0 ] . get_str ( ) = = " reset " ) {
2015-07-26 00:43:40 +02:00
darkSendPool . Reset ( ) ;
2016-02-01 18:22:00 +01:00
return " Mixing was reset " ;
2014-12-09 02:17:57 +01:00
}
2016-02-01 18:22:00 +01:00
if ( params [ 0 ] . get_str ( ) = = " status " ) {
2016-06-15 21:13:04 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
obj . push_back ( Pair ( " status " , darkSendPool . GetStatus ( ) ) ) ;
obj . push_back ( Pair ( " keys_left " , pwalletMain - > nKeysLeftSinceAutoBackup ) ) ;
obj . push_back ( Pair ( " warnings " , ( pwalletMain - > nKeysLeftSinceAutoBackup < PS_KEYS_THRESHOLD_WARNING
? " WARNING: keypool is almost depleted! " : " " ) ) ) ;
return obj ;
2016-02-01 18:22:00 +01:00
}
2014-12-09 02:17:57 +01:00
2016-05-25 07:25:16 +02:00
return " Unknown command, please see \" help privatesend \" " ;
2014-12-09 02:17:57 +01:00
}
2016-02-02 16:28:56 +01:00
UniValue getpoolinfo ( const UniValue & params , bool fHelp )
2014-12-09 02:17:57 +01:00
{
if ( fHelp | | params . size ( ) ! = 0 )
throw runtime_error (
" getpoolinfo \n "
" Returns an object containing anonymous pool-related information. " ) ;
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2016-03-06 17:44:21 +01:00
if ( darkSendPool . pSubmittedToMasternode )
obj . push_back ( Pair ( " masternode " , darkSendPool . pSubmittedToMasternode - > addr . ToString ( ) ) ) ;
obj . push_back ( Pair ( " queue " , ( int64_t ) vecDarksendQueue . size ( ) ) ) ;
obj . push_back ( Pair ( " state " , darkSendPool . GetState ( ) ) ) ;
obj . push_back ( Pair ( " entries " , darkSendPool . GetEntriesCount ( ) ) ) ;
2014-12-09 02:17:57 +01:00
obj . push_back ( Pair ( " entries_accepted " , darkSendPool . GetCountEntriesAccepted ( ) ) ) ;
return obj ;
}
2014-12-06 20:41:53 +01:00
2016-02-02 16:28:56 +01:00
UniValue masternode ( const UniValue & params , bool fHelp )
2014-12-09 02:17:57 +01:00
{
string strCommand ;
if ( params . size ( ) > = 1 )
strCommand = params [ 0 ] . get_str ( ) ;
if ( fHelp | |
2015-08-26 22:15:37 +02:00
( strCommand ! = " start " & & strCommand ! = " start-alias " & & strCommand ! = " start-many " & & strCommand ! = " start-all " & & strCommand ! = " start-missing " & &
strCommand ! = " start-disabled " & & strCommand ! = " list " & & strCommand ! = " list-conf " & & strCommand ! = " count " & & strCommand ! = " enforce " & &
2015-06-24 01:44:31 +02:00
strCommand ! = " debug " & & strCommand ! = " current " & & strCommand ! = " winners " & & strCommand ! = " genkey " & & strCommand ! = " connect " & &
2015-07-24 17:21:02 +02:00
strCommand ! = " outputs " & & strCommand ! = " status " & & strCommand ! = " calcscore " ) )
2014-12-09 02:17:57 +01:00
throw runtime_error (
2015-02-26 02:35:33 +01:00
" masternode \" command \" ... ( \" passphrase \" ) \n "
" Set of commands to execute masternode related actions \n "
" \n Arguments: \n "
" 1. \" command \" (string or set of strings, required) The command to execute \n "
" 2. \" passphrase \" (string, optional) The wallet passphrase \n "
" \n Available commands: \n "
2016-05-27 08:25:00 +02:00
" count - Print number of all known masternodes (optional: 'ps', 'enabled', 'all', 'qualify') \n "
2015-02-26 02:35:33 +01:00
" current - Print info on current masternode winner \n "
" debug - Print masternode status \n "
" genkey - Generate new masternodeprivkey \n "
" enforce - Enforce masternode payments \n "
" outputs - Print masternode compatible outputs \n "
2015-09-09 05:38:45 +02:00
" start - Start local Hot masternode configured in dash.conf \n "
" start-alias - Start single remote masternode by assigned alias configured in masternode.conf \n "
" start-<mode> - Start remote masternodes configured in masternode.conf (<mode>: 'all', 'missing', 'disabled') \n "
2015-07-18 21:17:17 +02:00
" status - Print masternode status information \n "
2015-02-26 02:35:33 +01:00
" list - Print list of all known masternodes (see masternodelist for more info) \n "
" list-conf - Print masternode.conf in JSON format \n "
" winners - Print list of masternode winners \n "
) ;
2014-12-09 02:17:57 +01:00
if ( strCommand = = " list " )
{
2016-02-02 16:28:56 +01:00
UniValue newParams ( UniValue : : VARR ) ;
// forward params but skip "list"
for ( unsigned int i = 1 ; i < params . size ( ) ; i + + )
newParams . push_back ( params [ i ] ) ;
2015-02-23 21:26:23 +01:00
return masternodelist ( newParams , fHelp ) ;
}
2014-12-09 02:17:57 +01:00
2015-07-18 21:17:17 +02:00
if ( strCommand = = " connect " )
{
std : : string strAddress = " " ;
if ( params . size ( ) = = 2 ) {
strAddress = params [ 1 ] . get_str ( ) ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Masternode address required " ) ;
2015-07-18 21:17:17 +02:00
}
CService addr = CService ( strAddress ) ;
2016-03-02 11:53:39 +01:00
CNode * pnode = ConnectNode ( ( CAddress ) addr , NULL , false ) ;
if ( pnode ) {
pnode - > Release ( ) ;
2015-07-18 21:17:17 +02:00
return " successfully connected " ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Error connecting " ) ;
2015-07-18 21:17:17 +02:00
}
}
2015-02-23 21:26:23 +01:00
if ( strCommand = = " count " )
{
if ( params . size ( ) > 2 ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Too many parameters " ) ;
2014-12-09 02:17:57 +01:00
}
2015-02-26 02:35:33 +01:00
if ( params . size ( ) = = 2 )
{
2015-08-20 17:36:44 +02:00
int nCount = 0 ;
2016-03-02 21:57:24 +01:00
{
LOCK ( cs_main ) ;
if ( chainActive . Tip ( ) )
mnodeman . GetNextMasternodeInQueueForPayment ( chainActive . Tip ( ) - > nHeight , true , nCount ) ;
}
2015-08-20 17:36:44 +02:00
2016-05-27 00:05:05 +02:00
if ( params [ 1 ] . get_str ( ) = = " ps " ) return mnodeman . CountEnabled ( MIN_POOL_PEER_PROTO_VERSION ) ;
2016-02-02 16:28:56 +01:00
if ( params [ 1 ] . get_str ( ) = = " enabled " ) return mnodeman . CountEnabled ( ) ;
if ( params [ 1 ] . get_str ( ) = = " qualify " ) return nCount ;
2016-05-27 00:05:05 +02:00
if ( params [ 1 ] . get_str ( ) = = " all " ) return strprintf ( " Total: %d (PS Compatible: %d / Enabled: %d / Qualify: %d) " ,
2015-07-25 10:18:22 +02:00
mnodeman . size ( ) ,
2015-07-19 01:20:48 +02:00
mnodeman . CountEnabled ( MIN_POOL_PEER_PROTO_VERSION ) ,
2015-08-20 17:36:44 +02:00
mnodeman . CountEnabled ( ) ,
nCount ) ;
2015-02-26 02:35:33 +01:00
}
2015-02-23 21:26:23 +01:00
return mnodeman . size ( ) ;
2014-12-09 02:17:57 +01:00
}
2015-07-18 21:17:17 +02:00
if ( strCommand = = " current " )
{
2016-03-06 17:44:21 +01:00
int nCount = 0 ;
2016-03-02 21:57:24 +01:00
LOCK ( cs_main ) ;
CMasternode * winner = NULL ;
if ( chainActive . Tip ( ) )
2016-03-06 17:44:21 +01:00
winner = mnodeman . GetNextMasternodeInQueueForPayment ( chainActive . Height ( ) - 100 , true , nCount ) ;
2015-07-18 21:17:17 +02:00
if ( winner ) {
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2015-07-18 21:17:17 +02:00
obj . push_back ( Pair ( " IP:port " , winner - > addr . ToString ( ) ) ) ;
obj . push_back ( Pair ( " protocol " , ( int64_t ) winner - > protocolVersion ) ) ;
2016-03-06 17:44:21 +01:00
obj . push_back ( Pair ( " vin " , winner - > vin . prevout . ToStringShort ( ) ) ) ;
2015-08-28 22:04:14 +02:00
obj . push_back ( Pair ( " pubkey " , CBitcoinAddress ( winner - > pubkey . GetID ( ) ) . ToString ( ) ) ) ;
2015-07-18 21:17:17 +02:00
obj . push_back ( Pair ( " lastseen " , ( winner - > lastPing = = CMasternodePing ( ) ) ? winner - > sigTime :
2016-03-06 17:44:21 +01:00
winner - > lastPing . sigTime ) ) ;
2015-07-18 21:17:17 +02:00
obj . push_back ( Pair ( " activeseconds " , ( winner - > lastPing = = CMasternodePing ( ) ) ? 0 :
2016-03-06 17:44:21 +01:00
( winner - > lastPing . sigTime - winner - > sigTime ) ) ) ;
2015-07-18 21:17:17 +02:00
return obj ;
}
return " unknown " ;
}
if ( strCommand = = " debug " )
{
2016-03-06 17:44:21 +01:00
if ( activeMasternode . status ! = ACTIVE_MASTERNODE_INITIAL | | ! masternodeSync . IsBlockchainSynced ( ) )
2015-07-23 04:11:39 +02:00
return activeMasternode . GetStatus ( ) ;
2015-07-18 21:17:17 +02:00
CTxIn vin = CTxIn ( ) ;
2016-02-02 16:28:56 +01:00
CPubKey pubkey = CPubKey ( ) ;
2015-07-18 21:17:17 +02:00
CKey key ;
2016-07-15 08:33:16 +02:00
if ( ! pwalletMain | | ! pwalletMain - > GetMasternodeVinAndKeys ( vin , pubkey , key ) )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Missing masternode input, please look at the documentation for instructions on masternode creation " ) ;
2016-07-15 08:33:16 +02:00
return activeMasternode . GetStatus ( ) ;
2015-07-18 21:17:17 +02:00
}
if ( strCommand = = " enforce " )
{
return ( uint64_t ) enforceMasternodePaymentsTime ;
}
2014-12-09 02:17:57 +01:00
if ( strCommand = = " start " )
{
2016-03-15 01:52:49 +01:00
if ( ! fMasterNode )
throw JSONRPCError ( RPC_INTERNAL_ERROR , " You must set masternode=1 in the configuration " ) ;
2014-12-09 02:17:57 +01:00
if ( pwalletMain - > IsLocked ( ) ) {
SecureString strWalletPass ;
strWalletPass . reserve ( 100 ) ;
if ( params . size ( ) = = 2 ) {
strWalletPass = params [ 1 ] . get_str ( ) . c_str ( ) ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_WALLET_UNLOCK_NEEDED , " Your wallet is locked, passphrase is required " ) ;
2014-12-09 02:17:57 +01:00
}
if ( ! pwalletMain - > Unlock ( strWalletPass ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_WALLET_PASSPHRASE_INCORRECT , " The wallet passphrase entered was incorrect " ) ;
2014-12-09 02:17:57 +01:00
}
}
2015-07-17 12:26:24 +02:00
if ( activeMasternode . status ! = ACTIVE_MASTERNODE_STARTED ) {
activeMasternode . status = ACTIVE_MASTERNODE_INITIAL ; // TODO: consider better way
2015-01-21 22:57:02 +01:00
activeMasternode . ManageStatus ( ) ;
pwalletMain - > Lock ( ) ;
}
2014-12-26 21:00:56 +01:00
2015-07-14 07:25:07 +02:00
return activeMasternode . GetStatus ( ) ;
2014-12-09 02:17:57 +01:00
}
2014-12-06 20:41:53 +01:00
if ( strCommand = = " start-alias " )
2014-12-09 02:17:57 +01:00
{
2015-07-18 03:23:52 +02:00
if ( params . size ( ) < 2 ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Command needs at least 2 parameters " ) ;
2014-12-09 02:17:57 +01:00
}
2015-07-18 19:31:28 +02:00
std : : string alias = params [ 1 ] . get_str ( ) ;
2015-07-18 03:23:52 +02:00
if ( pwalletMain - > IsLocked ( ) ) {
SecureString strWalletPass ;
strWalletPass . reserve ( 100 ) ;
if ( params . size ( ) = = 3 ) {
strWalletPass = params [ 2 ] . get_str ( ) . c_str ( ) ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_WALLET_UNLOCK_NEEDED , " Your wallet is locked, passphrase is required " ) ;
2015-07-18 03:23:52 +02:00
}
if ( ! pwalletMain - > Unlock ( strWalletPass ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_WALLET_PASSPHRASE_INCORRECT , " The wallet passphrase entered was incorrect " ) ;
2015-07-18 03:23:52 +02:00
}
}
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
bool found = false ;
2014-12-06 20:41:53 +01:00
2016-02-02 16:28:56 +01:00
UniValue statusObj ( UniValue : : VOBJ ) ;
2015-07-18 03:23:52 +02:00
statusObj . push_back ( Pair ( " alias " , alias ) ) ;
2015-03-21 20:49:21 +01:00
2015-07-18 03:23:52 +02:00
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
if ( mne . getAlias ( ) = = alias ) {
found = true ;
std : : string errorMessage ;
2016-03-16 16:30:22 +01:00
CMasternodeBroadcast mnb ;
2014-12-06 20:41:53 +01:00
2016-07-29 07:32:08 +02:00
bool result = CMasternodeBroadcast : : Create ( mne . getIp ( ) , mne . getPrivKey ( ) , mne . getTxHash ( ) , mne . getOutputIndex ( ) , errorMessage , mnb ) ;
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
statusObj . push_back ( Pair ( " result " , result ? " successful " : " failed " ) ) ;
2016-03-16 16:30:22 +01:00
if ( result ) {
mnodeman . UpdateMasternodeList ( mnb ) ;
mnb . Relay ( ) ;
} else {
2015-07-18 03:23:52 +02:00
statusObj . push_back ( Pair ( " errorMessage " , errorMessage ) ) ;
}
break ;
}
}
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
if ( ! found ) {
statusObj . push_back ( Pair ( " result " , " failed " ) ) ;
2016-03-15 01:52:49 +01:00
statusObj . push_back ( Pair ( " errorMessage " , " Could not find alias in config. Verify with list-conf. " ) ) ;
2015-07-18 03:23:52 +02:00
}
pwalletMain - > Lock ( ) ;
return statusObj ;
2014-12-09 02:17:57 +01:00
}
2014-12-26 21:00:56 +01:00
2015-08-26 22:15:37 +02:00
if ( strCommand = = " start-many " | | strCommand = = " start-all " | | strCommand = = " start-missing " | | strCommand = = " start-disabled " )
2014-12-26 21:00:56 +01:00
{
2015-07-18 03:23:52 +02:00
if ( pwalletMain - > IsLocked ( ) ) {
SecureString strWalletPass ;
strWalletPass . reserve ( 100 ) ;
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
if ( params . size ( ) = = 2 ) {
strWalletPass = params [ 1 ] . get_str ( ) . c_str ( ) ;
} else {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_WALLET_UNLOCK_NEEDED , " Your wallet is locked, passphrase is required " ) ;
2015-07-18 03:23:52 +02:00
}
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
if ( ! pwalletMain - > Unlock ( strWalletPass ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_WALLET_PASSPHRASE_INCORRECT , " The wallet passphrase entered was incorrect " ) ;
2015-07-18 03:23:52 +02:00
}
}
2014-12-06 20:41:53 +01:00
2015-08-31 06:20:38 +02:00
if ( ( strCommand = = " start-missing " | | strCommand = = " start-disabled " ) & &
( masternodeSync . RequestedMasternodeAssets < = MASTERNODE_SYNC_LIST | |
masternodeSync . RequestedMasternodeAssets = = MASTERNODE_SYNC_FAILED ) ) {
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_CLIENT_IN_INITIAL_DOWNLOAD , " You can't use this command until masternode list is synced " ) ;
2015-08-31 06:20:38 +02:00
}
2015-07-18 03:23:52 +02:00
int successful = 0 ;
2015-07-18 19:31:28 +02:00
int failed = 0 ;
2014-12-06 20:41:53 +01:00
2016-02-02 16:28:56 +01:00
UniValue resultsObj ( UniValue : : VOBJ ) ;
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
std : : string errorMessage ;
2015-03-21 20:49:21 +01:00
2016-02-02 16:28:56 +01:00
CTxIn vin = CTxIn ( uint256S ( mne . getTxHash ( ) ) , uint32_t ( atoi ( mne . getOutputIndex ( ) . c_str ( ) ) ) ) ;
2015-08-26 22:15:37 +02:00
CMasternode * pmn = mnodeman . Find ( vin ) ;
2016-03-16 16:30:22 +01:00
CMasternodeBroadcast mnb ;
2015-08-26 22:15:37 +02:00
if ( strCommand = = " start-missing " & & pmn ) continue ;
if ( strCommand = = " start-disabled " & & pmn & & pmn - > IsEnabled ( ) ) continue ;
2016-07-29 07:32:08 +02:00
bool result = CMasternodeBroadcast : : Create ( mne . getIp ( ) , mne . getPrivKey ( ) , mne . getTxHash ( ) , mne . getOutputIndex ( ) , errorMessage , mnb ) ;
2014-12-06 20:41:53 +01:00
2016-02-02 16:28:56 +01:00
UniValue statusObj ( UniValue : : VOBJ ) ;
2015-07-18 03:23:52 +02:00
statusObj . push_back ( Pair ( " alias " , mne . getAlias ( ) ) ) ;
2015-02-17 11:27:47 +01:00
statusObj . push_back ( Pair ( " result " , result ? " successful " : " failed " ) ) ;
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
if ( result ) {
successful + + ;
2016-03-16 16:30:22 +01:00
mnodeman . UpdateMasternodeList ( mnb ) ;
mnb . Relay ( ) ;
2015-07-18 03:23:52 +02:00
} else {
2015-07-18 19:31:28 +02:00
failed + + ;
2015-07-18 03:23:52 +02:00
statusObj . push_back ( Pair ( " errorMessage " , errorMessage ) ) ;
}
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
resultsObj . push_back ( Pair ( " status " , statusObj ) ) ;
}
pwalletMain - > Lock ( ) ;
2014-12-06 20:41:53 +01:00
2016-02-02 16:28:56 +01:00
UniValue returnObj ( UniValue : : VOBJ ) ;
2015-07-18 19:31:28 +02:00
returnObj . push_back ( Pair ( " overall " , strprintf ( " Successfully started %d masternodes, failed to start %d, total %d " , successful , failed , successful + failed ) ) ) ;
2015-07-18 03:23:52 +02:00
returnObj . push_back ( Pair ( " detail " , resultsObj ) ) ;
2014-12-06 20:41:53 +01:00
2015-07-18 03:23:52 +02:00
return returnObj ;
2014-12-06 20:41:53 +01:00
}
2014-12-09 02:17:57 +01:00
if ( strCommand = = " genkey " )
{
CKey secret ;
secret . MakeNewKey ( false ) ;
return CBitcoinSecret ( secret ) . ToString ( ) ;
}
2014-12-06 20:41:53 +01:00
if ( strCommand = = " list-conf " )
{
2016-02-02 16:28:56 +01:00
UniValue resultObj ( UniValue : : VOBJ ) ;
2014-12-06 20:41:53 +01:00
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
2016-02-02 16:28:56 +01:00
CTxIn vin = CTxIn ( uint256S ( mne . getTxHash ( ) ) , uint32_t ( atoi ( mne . getOutputIndex ( ) . c_str ( ) ) ) ) ;
2015-08-31 06:20:38 +02:00
CMasternode * pmn = mnodeman . Find ( vin ) ;
std : : string strStatus = pmn ? pmn - > Status ( ) : " MISSING " ;
2016-02-02 16:28:56 +01:00
UniValue mnObj ( UniValue : : VOBJ ) ;
2015-03-16 20:44:16 +01:00
mnObj . push_back ( Pair ( " alias " , mne . getAlias ( ) ) ) ;
mnObj . push_back ( Pair ( " address " , mne . getIp ( ) ) ) ;
mnObj . push_back ( Pair ( " privateKey " , mne . getPrivKey ( ) ) ) ;
mnObj . push_back ( Pair ( " txHash " , mne . getTxHash ( ) ) ) ;
mnObj . push_back ( Pair ( " outputIndex " , mne . getOutputIndex ( ) ) ) ;
2015-08-31 06:20:38 +02:00
mnObj . push_back ( Pair ( " status " , strStatus ) ) ;
2015-03-16 20:44:16 +01:00
resultObj . push_back ( Pair ( " masternode " , mnObj ) ) ;
}
2014-12-06 20:41:53 +01:00
2015-03-16 20:44:16 +01:00
return resultObj ;
2014-12-06 20:41:53 +01:00
}
2014-12-26 21:00:56 +01:00
if ( strCommand = = " outputs " ) {
// Find possible candidates
2016-07-15 08:33:16 +02:00
std : : vector < COutput > vPossibleCoins ;
pwalletMain - > AvailableCoins ( vPossibleCoins , true , NULL , false , ONLY_1000 ) ;
2014-12-26 21:00:56 +01:00
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2016-07-15 08:33:16 +02:00
BOOST_FOREACH ( COutput & out , vPossibleCoins )
2015-07-18 19:31:28 +02:00
obj . push_back ( Pair ( out . tx - > GetHash ( ) . ToString ( ) , strprintf ( " %d " , out . i ) ) ) ;
2014-12-26 21:00:56 +01:00
return obj ;
}
2015-06-24 18:41:03 +02:00
if ( strCommand = = " status " )
{
2016-03-15 01:52:49 +01:00
if ( ! fMasterNode )
throw JSONRPCError ( RPC_INTERNAL_ERROR , " This is not a masternode " ) ;
2015-06-24 18:41:03 +02:00
2016-02-02 16:28:56 +01:00
UniValue mnObj ( UniValue : : VOBJ ) ;
2015-08-28 22:18:55 +02:00
CMasternode * pmn = mnodeman . Find ( activeMasternode . vin ) ;
2015-07-18 19:31:28 +02:00
mnObj . push_back ( Pair ( " vin " , activeMasternode . vin . ToString ( ) ) ) ;
mnObj . push_back ( Pair ( " service " , activeMasternode . service . ToString ( ) ) ) ;
2015-08-28 22:18:55 +02:00
if ( pmn ) mnObj . push_back ( Pair ( " pubkey " , CBitcoinAddress ( pmn - > pubkey . GetID ( ) ) . ToString ( ) ) ) ;
2015-08-15 16:09:13 +02:00
mnObj . push_back ( Pair ( " status " , activeMasternode . GetStatus ( ) ) ) ;
2015-06-24 18:41:03 +02:00
return mnObj ;
}
2015-07-18 21:17:17 +02:00
if ( strCommand = = " winners " )
{
2016-03-02 21:57:24 +01:00
int nHeight ;
{
LOCK ( cs_main ) ;
CBlockIndex * pindex = chainActive . Tip ( ) ;
if ( ! pindex ) return NullUniValue ;
nHeight = pindex - > nHeight ;
}
2015-07-21 00:09:42 +02:00
int nLast = 10 ;
2016-03-06 17:44:21 +01:00
std : : string strFilter = " " ;
2015-07-21 00:09:42 +02:00
if ( params . size ( ) > = 2 ) {
2015-07-22 00:14:54 +02:00
nLast = atoi ( params [ 1 ] . get_str ( ) ) ;
2015-07-21 00:09:42 +02:00
}
2016-03-06 17:44:21 +01:00
if ( params . size ( ) = = 3 ) {
strFilter = params [ 2 ] . get_str ( ) ;
}
if ( params . size ( ) > 3 )
2016-03-15 01:52:49 +01:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'masternode winners ( \" count \" \" filter \" ) ' " ) ;
2016-03-06 17:44:21 +01:00
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2015-07-18 21:17:17 +02:00
2016-03-02 22:20:04 +01:00
for ( int i = nHeight - nLast ; i < nHeight + 20 ; i + + )
2015-07-18 21:17:17 +02:00
{
2016-03-06 17:44:21 +01:00
std : : string strPayment = GetRequiredPaymentsString ( i ) ;
if ( strFilter ! = " " & & strPayment . find ( strFilter ) = = string : : npos ) continue ;
obj . push_back ( Pair ( strprintf ( " %d " , i ) , strPayment ) ) ;
2015-07-18 21:17:17 +02:00
}
return obj ;
}
2016-05-24 22:17:03 +02:00
// 12.1 -- remove?
// /*
// Shows which masternode wins by score each block
// */
// if (strCommand == "calcscore")
// {
// int nHeight;
// {
// LOCK(cs_main);
// CBlockIndex* pindex = chainActive.Tip();
// if(!pindex) return NullUniValue;
// nHeight = pindex->nHeight;
// }
// int nLast = 10;
// if (params.size() >= 2){
// nLast = atoi(params[1].get_str());
// }
// UniValue obj(UniValue::VOBJ);
// std::vector<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();
// for(int i = nHeight - nLast; i < nHeight + 20; i++){
// arith_uint256 nHigh = 0;
// CMasternode *pBestMasternode = NULL;
// BOOST_FOREACH(CMasternode& mn, vMasternodes) {
// arith_uint256 n = UintToArith256(mn.CalculateScore(1, i - 100));
// if(n > nHigh){
// nHigh = n;
// pBestMasternode = &mn;
// }
// }
// if(pBestMasternode)
// obj.push_back(Pair(strprintf("%d", i), pBestMasternode->vin.prevout.ToStringShort().c_str()));
// }
// return obj;
// }
2015-07-24 17:21:02 +02:00
2016-02-02 16:28:56 +01:00
return NullUniValue ;
2014-12-09 02:17:57 +01:00
}
2016-02-02 16:28:56 +01:00
UniValue masternodelist ( const UniValue & params , bool fHelp )
2015-02-23 21:26:23 +01:00
{
2015-03-31 03:14:44 +02:00
std : : string strMode = " status " ;
2015-02-23 21:26:23 +01:00
std : : string strFilter = " " ;
if ( params . size ( ) > = 1 ) strMode = params [ 0 ] . get_str ( ) ;
if ( params . size ( ) = = 2 ) strFilter = params [ 1 ] . get_str ( ) ;
if ( fHelp | |
2015-05-04 17:04:09 +02:00
( strMode ! = " status " & & strMode ! = " vin " & & strMode ! = " pubkey " & & strMode ! = " lastseen " & & strMode ! = " activeseconds " & & strMode ! = " rank " & & strMode ! = " addr "
2015-07-26 16:01:49 +02:00
& & strMode ! = " protocol " & & strMode ! = " full " & & strMode ! = " lastpaid " ) )
2015-02-23 21:26:23 +01:00
{
throw runtime_error (
" masternodelist ( \" mode \" \" filter \" ) \n "
" Get a list of masternodes in different modes \n "
" \n Arguments: \n "
2015-03-31 03:14:44 +02:00
" 1. \" mode \" (string, optional/required to use filter, defaults = status) The mode to run list in \n "
2015-04-05 23:59:25 +02:00
" 2. \" filter \" (string, optional) Filter results. Partial match by IP by default in all modes, \n "
" additional matches in some modes are also available \n "
2015-02-26 02:35:33 +01:00
" \n Available modes: \n "
2015-02-23 21:26:23 +01:00
" activeseconds - Print number of seconds masternode recognized by the network as enabled \n "
2015-07-14 07:25:07 +02:00
" (since latest issued \" masternode start/start-many/start-alias \" ) \n "
2015-07-18 19:31:28 +02:00
" addr - Print ip address associated with a masternode (can be additionally filtered, partial match) \n "
2015-06-23 22:44:20 +02:00
" full - Print info in format 'status protocol pubkey IP lastseen activeseconds lastpaid' \n "
2015-04-05 23:59:25 +02:00
" (can be additionally filtered, partial match) \n "
2015-02-23 21:26:23 +01:00
" lastseen - Print timestamp of when a masternode was last seen on the network \n "
2015-07-18 19:31:28 +02:00
" lastpaid - The last time a node was paid on the network \n "
2015-03-01 18:39:18 +01:00
" protocol - Print protocol of a masternode (can be additionally filtered, exact match)) \n "
2015-04-05 23:59:25 +02:00
" pubkey - Print public key associated with a masternode (can be additionally filtered, \n "
" partial match) \n "
2015-02-23 21:26:23 +01:00
" rank - Print rank of a masternode based on current block \n "
2015-04-05 23:59:25 +02:00
" status - Print masternode status: ENABLED / EXPIRED / VIN_SPENT / REMOVE / POS_ERROR \n "
" (can be additionally filtered, partial match) \n "
2015-02-23 21:26:23 +01:00
) ;
}
2016-02-02 16:28:56 +01:00
UniValue obj ( UniValue : : VOBJ ) ;
2015-03-14 19:34:51 +01:00
if ( strMode = = " rank " ) {
std : : vector < pair < int , CMasternode > > vMasternodeRanks = mnodeman . GetMasternodeRanks ( chainActive . Tip ( ) - > nHeight ) ;
BOOST_FOREACH ( PAIRTYPE ( int , CMasternode ) & s , vMasternodeRanks ) {
2015-04-16 16:08:06 +02:00
std : : string strVin = s . second . vin . prevout . ToStringShort ( ) ;
if ( strFilter ! = " " & & strVin . find ( strFilter ) = = string : : npos ) continue ;
obj . push_back ( Pair ( strVin , s . first ) ) ;
2015-03-14 19:34:51 +01:00
}
} else {
std : : vector < CMasternode > vMasternodes = mnodeman . GetFullMasternodeVector ( ) ;
BOOST_FOREACH ( CMasternode & mn , vMasternodes ) {
2015-04-16 16:08:06 +02:00
std : : string strVin = mn . vin . prevout . ToStringShort ( ) ;
2015-03-31 03:14:44 +02:00
if ( strMode = = " activeseconds " ) {
2015-04-16 16:08:06 +02:00
if ( strFilter ! = " " & & strVin . find ( strFilter ) = = string : : npos ) continue ;
2015-07-14 07:25:07 +02:00
obj . push_back ( Pair ( strVin , ( int64_t ) ( mn . lastPing . sigTime - mn . sigTime ) ) ) ;
2015-07-18 19:31:28 +02:00
} else if ( strMode = = " addr " ) {
if ( strFilter ! = " " & & mn . vin . prevout . hash . ToString ( ) . find ( strFilter ) = = string : : npos & &
strVin . find ( strFilter ) = = string : : npos ) continue ;
obj . push_back ( Pair ( strVin , mn . addr . ToString ( ) ) ) ;
2015-03-14 19:34:51 +01:00
} else if ( strMode = = " full " ) {
std : : ostringstream addrStream ;
2015-04-16 16:08:06 +02:00
addrStream < < setw ( 21 ) < < strVin ;
2015-03-14 19:34:51 +01:00
std : : ostringstream stringStream ;
2015-07-18 19:31:28 +02:00
stringStream < < setw ( 9 ) < <
2015-03-31 03:14:44 +02:00
mn . Status ( ) < < " " < <
2015-03-14 19:34:51 +01:00
mn . protocolVersion < < " " < <
2015-08-28 22:04:14 +02:00
CBitcoinAddress ( mn . pubkey . GetID ( ) ) . ToString ( ) < < " " < < setw ( 21 ) < <
2015-04-16 16:08:06 +02:00
mn . addr . ToString ( ) < < " " < <
2015-07-23 04:11:39 +02:00
( int64_t ) mn . lastPing . sigTime < < " " < < setw ( 8 ) < <
( int64_t ) ( mn . lastPing . sigTime - mn . sigTime ) < < " " < <
( int64_t ) mn . GetLastPaid ( ) ;
2015-03-14 19:34:51 +01:00
std : : string output = stringStream . str ( ) ;
2015-04-16 16:08:06 +02:00
stringStream < < " " < < strVin ;
2015-03-14 19:34:51 +01:00
if ( strFilter ! = " " & & stringStream . str ( ) . find ( strFilter ) = = string : : npos & &
2015-04-16 16:08:06 +02:00
strVin . find ( strFilter ) = = string : : npos ) continue ;
2015-03-14 19:34:51 +01:00
obj . push_back ( Pair ( addrStream . str ( ) , output ) ) ;
} else if ( strMode = = " lastseen " ) {
2015-04-16 16:08:06 +02:00
if ( strFilter ! = " " & & strVin . find ( strFilter ) = = string : : npos ) continue ;
2015-07-14 07:25:07 +02:00
obj . push_back ( Pair ( strVin , ( int64_t ) mn . lastPing . sigTime ) ) ;
2015-07-18 19:31:28 +02:00
} else if ( strMode = = " lastpaid " ) {
if ( strFilter ! = " " & & mn . vin . prevout . hash . ToString ( ) . find ( strFilter ) = = string : : npos & &
strVin . find ( strFilter ) = = string : : npos ) continue ;
obj . push_back ( Pair ( strVin , ( int64_t ) mn . GetLastPaid ( ) ) ) ;
2015-03-14 19:34:51 +01:00
} else if ( strMode = = " protocol " ) {
2015-07-18 19:31:28 +02:00
if ( strFilter ! = " " & & strFilter ! = strprintf ( " %d " , mn . protocolVersion ) & &
2015-04-16 16:08:06 +02:00
strVin . find ( strFilter ) = = string : : npos ) continue ;
obj . push_back ( Pair ( strVin , ( int64_t ) mn . protocolVersion ) ) ;
2015-03-14 19:34:51 +01:00
} else if ( strMode = = " pubkey " ) {
2015-08-28 22:04:14 +02:00
CBitcoinAddress address ( mn . pubkey . GetID ( ) ) ;
2015-03-01 18:39:18 +01:00
2015-08-28 22:04:14 +02:00
if ( strFilter ! = " " & & address . ToString ( ) . find ( strFilter ) = = string : : npos & &
2015-04-16 16:08:06 +02:00
strVin . find ( strFilter ) = = string : : npos ) continue ;
2015-08-28 22:04:14 +02:00
obj . push_back ( Pair ( strVin , address . ToString ( ) ) ) ;
2015-03-31 03:14:44 +02:00
} else if ( strMode = = " status " ) {
std : : string strStatus = mn . Status ( ) ;
2015-04-16 16:08:06 +02:00
if ( strFilter ! = " " & & strVin . find ( strFilter ) = = string : : npos & & strStatus . find ( strFilter ) = = string : : npos ) continue ;
2015-07-18 19:31:28 +02:00
obj . push_back ( Pair ( strVin , strStatus ) ) ;
2015-03-14 19:34:51 +01:00
}
2015-02-24 00:48:11 +01:00
}
}
return obj ;
2016-03-16 16:30:22 +01:00
}
2016-03-17 18:39:17 +01:00
bool DecodeHexVecMnb ( std : : vector < CMasternodeBroadcast > & vecMnb , std : : string strHexMnb ) {
2016-03-16 16:30:22 +01:00
if ( ! IsHex ( strHexMnb ) )
return false ;
vector < unsigned char > mnbData ( ParseHex ( strHexMnb ) ) ;
CDataStream ssData ( mnbData , SER_NETWORK , PROTOCOL_VERSION ) ;
try {
2016-03-17 18:39:17 +01:00
ssData > > vecMnb ;
2016-03-16 16:30:22 +01:00
}
catch ( const std : : exception & ) {
return false ;
}
return true ;
}
UniValue masternodebroadcast ( const UniValue & params , bool fHelp )
{
string strCommand ;
if ( params . size ( ) > = 1 )
strCommand = params [ 0 ] . get_str ( ) ;
if ( fHelp | |
( strCommand ! = " create-alias " & & strCommand ! = " create-all " & & strCommand ! = " decode " & & strCommand ! = " relay " ) )
throw runtime_error (
" masternodebroadcast \" command \" ... ( \" passphrase \" ) \n "
" Set of commands to create and relay masternode broadcast messages \n "
" \n Arguments: \n "
" 1. \" command \" (string or set of strings, required) The command to execute \n "
" 2. \" passphrase \" (string, optional) The wallet passphrase \n "
" \n Available commands: \n "
" create-alias - Create single remote masternode broadcast message by assigned alias configured in masternode.conf \n "
" create-all - Create remote masternode broadcast messages for all masternodes configured in masternode.conf \n "
" decode - Decode masternode broadcast message \n "
" relay - Relay masternode broadcast message to the network \n "
+ HelpRequiringPassphrase ( ) ) ;
if ( strCommand = = " create-alias " )
{
// wait for reindex and/or import to finish
if ( fImporting | | fReindex )
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Wait for reindex and/or import to finish " ) ;
if ( params . size ( ) < 2 )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Command needs at least 2 parameters " ) ;
std : : string alias = params [ 1 ] . get_str ( ) ;
if ( pwalletMain - > IsLocked ( ) ) {
SecureString strWalletPass ;
strWalletPass . reserve ( 100 ) ;
if ( params . size ( ) = = 3 ) {
strWalletPass = params [ 2 ] . get_str ( ) . c_str ( ) ;
} else {
throw JSONRPCError ( RPC_WALLET_UNLOCK_NEEDED , " Your wallet is locked, passphrase is required " ) ;
}
2015-02-24 00:48:11 +01:00
2016-03-16 16:30:22 +01:00
if ( ! pwalletMain - > Unlock ( strWalletPass ) ) {
throw JSONRPCError ( RPC_WALLET_PASSPHRASE_INCORRECT , " The wallet passphrase entered was incorrect " ) ;
}
}
bool found = false ;
UniValue statusObj ( UniValue : : VOBJ ) ;
2016-03-17 18:39:17 +01:00
std : : vector < CMasternodeBroadcast > vecMnb ;
2016-03-16 16:30:22 +01:00
statusObj . push_back ( Pair ( " alias " , alias ) ) ;
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
if ( mne . getAlias ( ) = = alias ) {
found = true ;
std : : string errorMessage ;
CMasternodeBroadcast mnb ;
2016-07-29 07:32:08 +02:00
bool result = CMasternodeBroadcast : : Create ( mne . getIp ( ) , mne . getPrivKey ( ) , mne . getTxHash ( ) , mne . getOutputIndex ( ) , errorMessage , mnb , true ) ;
2016-03-16 16:30:22 +01:00
statusObj . push_back ( Pair ( " result " , result ? " successful " : " failed " ) ) ;
if ( result ) {
2016-03-17 18:39:17 +01:00
vecMnb . push_back ( mnb ) ;
CDataStream ssVecMnb ( SER_NETWORK , PROTOCOL_VERSION ) ;
ssVecMnb < < vecMnb ;
statusObj . push_back ( Pair ( " hex " , HexStr ( ssVecMnb . begin ( ) , ssVecMnb . end ( ) ) ) ) ;
2016-03-16 16:30:22 +01:00
} else {
statusObj . push_back ( Pair ( " errorMessage " , errorMessage ) ) ;
}
break ;
}
}
if ( ! found ) {
2016-03-17 18:39:17 +01:00
statusObj . push_back ( Pair ( " result " , " not found " ) ) ;
2016-03-16 16:30:22 +01:00
statusObj . push_back ( Pair ( " errorMessage " , " Could not find alias in config. Verify with list-conf. " ) ) ;
}
pwalletMain - > Lock ( ) ;
return statusObj ;
}
if ( strCommand = = " create-all " )
{
// wait for reindex and/or import to finish
if ( fImporting | | fReindex )
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Wait for reindex and/or import to finish " ) ;
if ( pwalletMain - > IsLocked ( ) ) {
SecureString strWalletPass ;
strWalletPass . reserve ( 100 ) ;
if ( params . size ( ) = = 2 ) {
strWalletPass = params [ 1 ] . get_str ( ) . c_str ( ) ;
} else {
throw JSONRPCError ( RPC_WALLET_UNLOCK_NEEDED , " Your wallet is locked, passphrase is required " ) ;
}
if ( ! pwalletMain - > Unlock ( strWalletPass ) ) {
throw JSONRPCError ( RPC_WALLET_PASSPHRASE_INCORRECT , " The wallet passphrase entered was incorrect " ) ;
}
}
std : : vector < CMasternodeConfig : : CMasternodeEntry > mnEntries ;
mnEntries = masternodeConfig . getEntries ( ) ;
int successful = 0 ;
int failed = 0 ;
UniValue resultsObj ( UniValue : : VOBJ ) ;
2016-03-17 18:39:17 +01:00
std : : vector < CMasternodeBroadcast > vecMnb ;
2016-03-16 16:30:22 +01:00
BOOST_FOREACH ( CMasternodeConfig : : CMasternodeEntry mne , masternodeConfig . getEntries ( ) ) {
std : : string errorMessage ;
CTxIn vin = CTxIn ( uint256S ( mne . getTxHash ( ) ) , uint32_t ( atoi ( mne . getOutputIndex ( ) . c_str ( ) ) ) ) ;
CMasternodeBroadcast mnb ;
2016-07-29 07:32:08 +02:00
bool result = CMasternodeBroadcast : : Create ( mne . getIp ( ) , mne . getPrivKey ( ) , mne . getTxHash ( ) , mne . getOutputIndex ( ) , errorMessage , mnb , true ) ;
2016-03-16 16:30:22 +01:00
UniValue statusObj ( UniValue : : VOBJ ) ;
statusObj . push_back ( Pair ( " alias " , mne . getAlias ( ) ) ) ;
statusObj . push_back ( Pair ( " result " , result ? " successful " : " failed " ) ) ;
if ( result ) {
successful + + ;
2016-03-17 18:39:17 +01:00
vecMnb . push_back ( mnb ) ;
2016-03-16 16:30:22 +01:00
} else {
failed + + ;
statusObj . push_back ( Pair ( " errorMessage " , errorMessage ) ) ;
}
resultsObj . push_back ( Pair ( " status " , statusObj ) ) ;
}
pwalletMain - > Lock ( ) ;
2016-03-17 18:39:17 +01:00
CDataStream ssVecMnb ( SER_NETWORK , PROTOCOL_VERSION ) ;
ssVecMnb < < vecMnb ;
2016-03-16 16:30:22 +01:00
UniValue returnObj ( UniValue : : VOBJ ) ;
returnObj . push_back ( Pair ( " overall " , strprintf ( " Successfully created broadcast messages for %d masternodes, failed to create %d, total %d " , successful , failed , successful + failed ) ) ) ;
returnObj . push_back ( Pair ( " detail " , resultsObj ) ) ;
2016-03-17 18:39:17 +01:00
returnObj . push_back ( Pair ( " hex " , HexStr ( ssVecMnb . begin ( ) , ssVecMnb . end ( ) ) ) ) ;
2016-03-16 16:30:22 +01:00
return returnObj ;
}
if ( strCommand = = " decode " )
{
if ( params . size ( ) ! = 2 )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Correct usage is 'masternodebroadcast decode \" hexstring \" ' " ) ;
2016-03-17 18:39:17 +01:00
int successful = 0 ;
int failed = 0 ;
2016-06-03 06:59:19 +02:00
int nDos = 0 ;
2016-03-17 18:39:17 +01:00
std : : vector < CMasternodeBroadcast > vecMnb ;
UniValue returnObj ( UniValue : : VOBJ ) ;
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
if ( ! DecodeHexVecMnb ( vecMnb , params [ 1 ] . get_str ( ) ) )
2016-03-16 16:30:22 +01:00
throw JSONRPCError ( RPC_DESERIALIZATION_ERROR , " Masternode broadcast message decode failed " ) ;
2016-03-17 18:39:17 +01:00
BOOST_FOREACH ( CMasternodeBroadcast & mnb , vecMnb ) {
UniValue resultObj ( UniValue : : VOBJ ) ;
2016-03-16 16:30:22 +01:00
2016-06-03 06:59:19 +02:00
if ( mnb . VerifySignature ( nDos ) ) {
2016-03-17 18:39:17 +01:00
successful + + ;
resultObj . push_back ( Pair ( " vin " , mnb . vin . ToString ( ) ) ) ;
resultObj . push_back ( Pair ( " addr " , mnb . addr . ToString ( ) ) ) ;
resultObj . push_back ( Pair ( " pubkey " , CBitcoinAddress ( mnb . pubkey . GetID ( ) ) . ToString ( ) ) ) ;
resultObj . push_back ( Pair ( " pubkey2 " , CBitcoinAddress ( mnb . pubkey2 . GetID ( ) ) . ToString ( ) ) ) ;
resultObj . push_back ( Pair ( " vchSig " , EncodeBase64 ( & mnb . vchSig [ 0 ] , mnb . vchSig . size ( ) ) ) ) ;
resultObj . push_back ( Pair ( " sigTime " , mnb . sigTime ) ) ;
resultObj . push_back ( Pair ( " protocolVersion " , mnb . protocolVersion ) ) ;
resultObj . push_back ( Pair ( " nLastDsq " , mnb . nLastDsq ) ) ;
UniValue lastPingObj ( UniValue : : VOBJ ) ;
lastPingObj . push_back ( Pair ( " vin " , mnb . lastPing . vin . ToString ( ) ) ) ;
lastPingObj . push_back ( Pair ( " blockHash " , mnb . lastPing . blockHash . ToString ( ) ) ) ;
lastPingObj . push_back ( Pair ( " sigTime " , mnb . lastPing . sigTime ) ) ;
lastPingObj . push_back ( Pair ( " vchSig " , EncodeBase64 ( & mnb . lastPing . vchSig [ 0 ] , mnb . lastPing . vchSig . size ( ) ) ) ) ;
resultObj . push_back ( Pair ( " lastPing " , lastPingObj ) ) ;
} else {
failed + + ;
resultObj . push_back ( Pair ( " errorMessage " , " Masternode broadcast signature verification failed " ) ) ;
}
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
returnObj . push_back ( Pair ( mnb . GetHash ( ) . ToString ( ) , resultObj ) ) ;
}
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
returnObj . push_back ( Pair ( " overall " , strprintf ( " Successfully decoded broadcast messages for %d masternodes, failed to decode %d, total %d " , successful , failed , successful + failed ) ) ) ;
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
return returnObj ;
2016-03-16 16:30:22 +01:00
}
if ( strCommand = = " relay " )
{
2016-03-18 00:37:48 +01:00
if ( params . size ( ) < 2 | | params . size ( ) > 3 )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " masternodebroadcast relay \" hexstring \" ( fast ) \n "
" \n Arguments: \n "
" 1. \" hex \" (string, required) Broadcast messages hex string \n "
" 2. fast (string, optional) If none, using safe method \n " ) ;
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
int successful = 0 ;
int failed = 0 ;
2016-03-18 00:37:48 +01:00
bool fSafe = params . size ( ) = = 2 ;
2016-03-17 18:39:17 +01:00
std : : vector < CMasternodeBroadcast > vecMnb ;
UniValue returnObj ( UniValue : : VOBJ ) ;
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
if ( ! DecodeHexVecMnb ( vecMnb , params [ 1 ] . get_str ( ) ) )
2016-03-16 16:30:22 +01:00
throw JSONRPCError ( RPC_DESERIALIZATION_ERROR , " Masternode broadcast message decode failed " ) ;
2016-03-17 18:39:17 +01:00
// verify all signatures first, bailout if any of them broken
BOOST_FOREACH ( CMasternodeBroadcast & mnb , vecMnb ) {
UniValue resultObj ( UniValue : : VOBJ ) ;
2016-03-16 16:30:22 +01:00
2016-03-17 18:39:17 +01:00
resultObj . push_back ( Pair ( " vin " , mnb . vin . ToString ( ) ) ) ;
resultObj . push_back ( Pair ( " addr " , mnb . addr . ToString ( ) ) ) ;
2016-03-16 16:30:22 +01:00
2016-03-18 00:37:48 +01:00
int nDos = 0 ;
bool fResult ;
2016-06-03 06:59:19 +02:00
if ( mnb . VerifySignature ( nDos ) ) {
2016-03-18 00:37:48 +01:00
if ( fSafe ) {
fResult = mnodeman . CheckMnbAndUpdateMasternodeList ( mnb , nDos ) ;
} else {
mnodeman . UpdateMasternodeList ( mnb ) ;
mnb . Relay ( ) ;
fResult = true ;
}
} else fResult = false ;
if ( fResult ) {
2016-03-17 18:39:17 +01:00
successful + + ;
resultObj . push_back ( Pair ( mnb . GetHash ( ) . ToString ( ) , " successful " ) ) ;
} else {
failed + + ;
resultObj . push_back ( Pair ( " errorMessage " , " Masternode broadcast signature verification failed " ) ) ;
}
returnObj . push_back ( Pair ( mnb . GetHash ( ) . ToString ( ) , resultObj ) ) ;
}
returnObj . push_back ( Pair ( " overall " , strprintf ( " Successfully relayed broadcast messages for %d masternodes, failed to relay %d, total %d " , successful , failed , successful + failed ) ) ) ;
return returnObj ;
2016-03-16 16:30:22 +01:00
}
return NullUniValue ;
2015-02-23 21:26:23 +01:00
}