2018-01-02 18:12:05 +01:00
// Copyright (c) 2009-2017 The Bitcoin Core developers
2014-11-20 03:19:29 +01:00
// Distributed under the MIT software license, see the accompanying
2012-06-29 05:18:38 +02:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2013-11-18 01:25:17 +01:00
2017-11-10 01:57:53 +01:00
# include <rpc/server.h>
2013-11-18 01:25:17 +01:00
2017-11-10 01:57:53 +01:00
# include <chainparams.h>
# include <clientversion.h>
# include <core_io.h>
# include <validation.h>
# include <net.h>
# include <net_processing.h>
# include <netbase.h>
# include <policy/policy.h>
# include <rpc/protocol.h>
# include <sync.h>
# include <timedata.h>
# include <ui_interface.h>
# include <util.h>
# include <utilstrencodings.h>
# include <version.h>
# include <warnings.h>
2014-09-14 12:43:56 +02:00
2015-09-04 16:11:34 +02:00
# include <univalue.h>
2012-06-29 05:18:38 +02:00
2018-05-02 17:14:48 +02:00
static UniValue getconnectioncount ( const JSONRPCRequest & request )
2012-06-29 05:18:38 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) ! = 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2012-06-29 05:18:38 +02:00
" getconnectioncount \n "
2013-10-29 12:29:44 +01:00
" \n Returns the number of connections to other nodes. \n "
2015-10-22 17:00:36 +02:00
" \n Result: \n "
2013-10-29 12:29:44 +01:00
" n (numeric) The connection count \n "
" \n Examples: \n "
+ HelpExampleCli ( " getconnectioncount " , " " )
+ HelpExampleRpc ( " getconnectioncount " , " " )
) ;
2012-06-29 05:18:38 +02:00
2016-04-17 00:30:03 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2014-10-19 10:46:17 +02:00
2016-04-17 00:30:03 +02:00
return ( int ) g_connman - > GetNodeCount ( CConnman : : CONNECTIONS_ALL ) ;
2012-06-29 05:18:38 +02:00
}
2018-05-02 17:14:48 +02:00
static UniValue ping ( const JSONRPCRequest & request )
2013-08-22 13:34:33 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) ! = 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2013-08-22 13:34:33 +02:00
" ping \n "
2013-10-29 12:29:44 +01:00
" \n Requests that a ping be sent to all other nodes, to measure ping time. \n "
2013-08-22 13:34:33 +02:00
" Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds. \n "
2014-01-30 14:13:30 +01:00
" Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping. \n "
2013-10-29 12:29:44 +01:00
" \n Examples: \n "
+ HelpExampleCli ( " ping " , " " )
+ HelpExampleRpc ( " ping " , " " )
) ;
2013-10-23 16:19:49 +02:00
2016-04-17 01:13:12 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2013-08-22 13:34:33 +02:00
2016-04-17 01:13:12 +02:00
// Request that each node send a ping during next message processing pass
g_connman - > ForEachNode ( [ ] ( CNode * pnode ) {
pnode - > fPingQueued = true ;
} ) ;
2014-08-20 21:15:16 +02:00
return NullUniValue ;
2013-08-22 13:34:33 +02:00
}
2018-05-02 17:14:48 +02:00
static UniValue getpeerinfo ( const JSONRPCRequest & request )
2012-06-29 23:24:53 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) ! = 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2012-06-29 23:24:53 +02:00
" getpeerinfo \n "
2013-10-29 12:29:44 +01:00
" \n Returns data about each connected network node as a json array of objects. \n "
2015-10-22 17:00:36 +02:00
" \n Result: \n "
2013-10-29 12:29:44 +01:00
" [ \n "
" { \n "
2014-07-15 16:13:10 +02:00
" \" id \" : n, (numeric) Peer index \n "
2017-06-20 00:57:31 +02:00
" \" addr \" : \" host:port \" , (string) The IP address and port of the peer \n "
2017-05-30 11:59:42 +02:00
" \" addrbind \" : \" ip:port \" , (string) Bind address of the connection to the peer \n "
" \" addrlocal \" : \" ip:port \" , (string) Local address as reported by the peer \n "
2014-06-06 09:15:55 +02:00
" \" services \" : \" xxxxxxxxxxxxxxxx \" , (string) The services offered \n "
2015-11-21 00:51:44 +01:00
" \" relaytxes \" :true|false, (boolean) Whether peer has asked us to relay transactions to it \n "
2013-10-29 12:29:44 +01:00
" \" lastsend \" : ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send \n "
" \" lastrecv \" : ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive \n "
" \" bytessent \" : n, (numeric) The total bytes sent \n "
" \" bytesrecv \" : n, (numeric) The total bytes received \n "
" \" conntime \" : ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT) \n "
2014-12-15 11:06:15 +01:00
" \" timeoffset \" : ttt, (numeric) The time offset in seconds \n "
2016-04-08 18:52:59 +02:00
" \" pingtime \" : n, (numeric) ping time (if available) \n "
" \" minping \" : n, (numeric) minimum observed ping time (if any at all) \n "
" \" pingwait \" : n, (numeric) ping wait (if non-zero) \n "
2018-02-27 11:43:46 +01:00
" \" version \" : v, (numeric) The peer version, such as 70001 \n "
2013-10-29 12:29:44 +01:00
" \" subver \" : \" /Satoshi:0.8.5/ \" , (string) The string version \n "
" \" inbound \" : true|false, (boolean) Inbound (true) or Outbound (false) \n "
2017-10-05 17:49:16 +02:00
" \" addnode \" : true|false, (boolean) Whether connection was due to addnode/-connect or if it was an automatic/inbound connection \n "
2013-10-29 12:29:44 +01:00
" \" startingheight \" : n, (numeric) The starting height (block) of the peer \n "
2014-09-16 09:00:36 +02:00
" \" banscore \" : n, (numeric) The ban score \n "
2014-07-12 00:03:10 +02:00
" \" synced_headers \" : n, (numeric) The last header we have in common with this peer \n "
" \" synced_blocks \" : n, (numeric) The last block we have in common with this peer \n "
" \" inflight \" : [ \n "
" n, (numeric) The heights of blocks we're currently asking from this peer \n "
" ... \n "
2017-01-11 14:29:46 +01:00
" ], \n "
2017-01-04 05:22:19 +01:00
" \" whitelisted \" : true|false, (boolean) Whether the peer is whitelisted \n "
2015-08-25 16:30:31 +02:00
" \" bytessent_per_msg \" : { \n "
2017-01-11 14:29:46 +01:00
" \" addr \" : n, (numeric) The total bytes sent aggregated by message type \n "
2015-08-25 16:30:31 +02:00
" ... \n "
2017-01-11 14:29:46 +01:00
" }, \n "
2015-08-25 16:30:31 +02:00
" \" bytesrecv_per_msg \" : { \n "
2017-01-11 14:29:46 +01:00
" \" addr \" : n, (numeric) The total bytes received aggregated by message type \n "
2015-08-25 16:30:31 +02:00
" ... \n "
" } \n "
2013-10-29 12:29:44 +01:00
" } \n "
" ,... \n "
2014-07-17 15:09:03 +02:00
" ] \n "
2013-10-29 12:29:44 +01:00
" \n Examples: \n "
+ HelpExampleCli ( " getpeerinfo " , " " )
+ HelpExampleRpc ( " getpeerinfo " , " " )
) ;
2012-06-29 23:24:53 +02:00
2016-04-17 00:30:03 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2014-10-19 10:46:17 +02:00
2017-01-04 05:22:19 +01:00
std : : vector < CNodeStats > vstats ;
2016-04-17 00:30:03 +02:00
g_connman - > GetNodeStats ( vstats ) ;
2012-06-29 23:24:53 +02:00
2015-05-10 14:48:35 +02:00
UniValue ret ( UniValue : : VARR ) ;
2012-06-29 23:24:53 +02:00
2017-06-02 03:18:57 +02:00
for ( const CNodeStats & stats : vstats ) {
2015-05-10 14:48:35 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
2013-11-18 01:25:17 +01:00
CNodeStateStats statestats ;
bool fStateStats = GetNodeStateStats ( stats . nodeid , statestats ) ;
2017-09-22 20:04:07 +02:00
obj . pushKV ( " id " , stats . nodeid ) ;
obj . pushKV ( " addr " , stats . addrName ) ;
2013-08-22 07:50:19 +02:00
if ( ! ( stats . addrLocal . empty ( ) ) )
2017-09-22 20:04:07 +02:00
obj . pushKV ( " addrlocal " , stats . addrLocal ) ;
2017-05-30 11:59:42 +02:00
if ( stats . addrBind . IsValid ( ) )
2017-09-22 20:04:07 +02:00
obj . pushKV ( " addrbind " , stats . addrBind . ToString ( ) ) ;
obj . pushKV ( " services " , strprintf ( " %016x " , stats . nServices ) ) ;
obj . pushKV ( " relaytxes " , stats . fRelayTxes ) ;
obj . pushKV ( " lastsend " , stats . nLastSend ) ;
obj . pushKV ( " lastrecv " , stats . nLastRecv ) ;
obj . pushKV ( " bytessent " , stats . nSendBytes ) ;
obj . pushKV ( " bytesrecv " , stats . nRecvBytes ) ;
obj . pushKV ( " conntime " , stats . nTimeConnected ) ;
obj . pushKV ( " timeoffset " , stats . nTimeOffset ) ;
2016-04-08 18:52:59 +02:00
if ( stats . dPingTime > 0.0 )
2017-09-22 20:04:07 +02:00
obj . pushKV ( " pingtime " , stats . dPingTime ) ;
2017-09-11 21:43:49 +02:00
if ( stats . dMinPing < static_cast < double > ( std : : numeric_limits < int64_t > : : max ( ) ) / 1e6 )
2017-09-22 20:04:07 +02:00
obj . pushKV ( " minping " , stats . dMinPing ) ;
2013-08-22 13:34:33 +02:00
if ( stats . dPingWait > 0.0 )
2017-09-22 20:04:07 +02:00
obj . pushKV ( " pingwait " , stats . dPingWait ) ;
obj . pushKV ( " version " , stats . nVersion ) ;
2013-11-26 12:52:21 +01:00
// Use the sanitized form of subver here, to avoid tricksy remote peers from
2017-01-18 16:15:37 +01:00
// corrupting or modifying the JSON output by putting special characters in
2013-11-26 12:52:21 +01:00
// their ver message.
2017-09-22 20:04:07 +02:00
obj . pushKV ( " subver " , stats . cleanSubVer ) ;
obj . pushKV ( " inbound " , stats . fInbound ) ;
obj . pushKV ( " addnode " , stats . m_manual_connection ) ;
obj . pushKV ( " startingheight " , stats . nStartingHeight ) ;
2013-11-18 01:25:17 +01:00
if ( fStateStats ) {
2017-09-22 20:04:07 +02:00
obj . pushKV ( " banscore " , statestats . nMisbehavior ) ;
obj . pushKV ( " synced_headers " , statestats . nSyncHeight ) ;
obj . pushKV ( " synced_blocks " , statestats . nCommonHeight ) ;
2015-05-10 14:48:35 +02:00
UniValue heights ( UniValue : : VARR ) ;
2017-06-02 03:18:57 +02:00
for ( int height : statestats . vHeightInFlight ) {
2014-07-12 00:03:10 +02:00
heights . push_back ( height ) ;
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " inflight " , heights ) ;
2013-11-18 01:25:17 +01:00
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " whitelisted " , stats . fWhitelisted ) ;
2012-06-29 23:24:53 +02:00
2015-08-25 16:30:31 +02:00
UniValue sendPerMsgCmd ( UniValue : : VOBJ ) ;
2017-06-02 03:18:57 +02:00
for ( const mapMsgCmdSize : : value_type & i : stats . mapSendBytesPerMsgCmd ) {
2015-08-25 16:30:31 +02:00
if ( i . second > 0 )
2017-09-22 20:04:07 +02:00
sendPerMsgCmd . pushKV ( i . first , i . second ) ;
2015-08-25 16:30:31 +02:00
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " bytessent_per_msg " , sendPerMsgCmd ) ;
2015-08-25 16:30:31 +02:00
UniValue recvPerMsgCmd ( UniValue : : VOBJ ) ;
2017-06-02 03:18:57 +02:00
for ( const mapMsgCmdSize : : value_type & i : stats . mapRecvBytesPerMsgCmd ) {
2015-08-25 16:30:31 +02:00
if ( i . second > 0 )
2017-09-22 20:04:07 +02:00
recvPerMsgCmd . pushKV ( i . first , i . second ) ;
2015-08-25 16:30:31 +02:00
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " bytesrecv_per_msg " , recvPerMsgCmd ) ;
2015-08-25 16:30:31 +02:00
2012-06-29 23:24:53 +02:00
ret . push_back ( obj ) ;
}
2012-09-18 21:07:58 +02:00
2012-06-29 23:24:53 +02:00
return ret ;
}
2012-06-29 05:18:38 +02:00
2018-05-02 17:14:48 +02:00
static UniValue addnode ( const JSONRPCRequest & request )
2013-01-23 17:45:00 +01:00
{
2017-01-04 05:22:19 +01:00
std : : string strCommand ;
2017-08-15 01:44:02 +02:00
if ( ! request . params [ 1 ] . isNull ( ) )
2016-09-22 09:46:41 +02:00
strCommand = request . params [ 1 ] . get_str ( ) ;
if ( request . fHelp | | request . params . size ( ) ! = 2 | |
2013-01-23 17:45:00 +01:00
( strCommand ! = " onetry " & & strCommand ! = " add " & & strCommand ! = " remove " ) )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2013-10-29 12:29:44 +01:00
" addnode \" node \" \" add|remove|onetry \" \n "
2017-06-20 00:57:31 +02:00
" \n Attempts to add or remove a node from the addnode list. \n "
2013-10-29 12:29:44 +01:00
" Or try a connection to a node once. \n "
2017-10-06 23:27:04 +02:00
" Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be \n "
" full nodes/support SegWit as other outbound peers are (though such peers will not be synced from). \n "
2013-10-29 12:29:44 +01:00
" \n Arguments: \n "
" 1. \" node \" (string, required) The node (see getpeerinfo for nodes) \n "
" 2. \" command \" (string, required) 'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once \n "
" \n Examples: \n "
+ HelpExampleCli ( " addnode " , " \" 192.168.0.6:8333 \" \" onetry \" " )
+ HelpExampleRpc ( " addnode " , " \" 192.168.0.6:8333 \" , \" onetry \" " )
) ;
2013-01-23 17:45:00 +01:00
2016-04-16 21:59:10 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2017-01-04 05:22:19 +01:00
std : : string strNode = request . params [ 0 ] . get_str ( ) ;
2013-01-23 17:45:00 +01:00
if ( strCommand = = " onetry " )
{
CAddress addr ;
2017-10-04 23:59:30 +02:00
g_connman - > OpenNetworkConnection ( addr , false , nullptr , strNode . c_str ( ) , false , false , true ) ;
2014-08-20 21:15:16 +02:00
return NullUniValue ;
2013-01-23 17:45:00 +01:00
}
if ( strCommand = = " add " )
{
2016-04-17 00:12:58 +02:00
if ( ! g_connman - > AddNode ( strNode ) )
2013-10-23 16:19:49 +02:00
throw JSONRPCError ( RPC_CLIENT_NODE_ALREADY_ADDED , " Error: Node already added " ) ;
2013-01-23 17:45:00 +01:00
}
else if ( strCommand = = " remove " )
{
2016-04-17 00:12:58 +02:00
if ( ! g_connman - > RemoveAddedNode ( strNode ) )
2013-10-23 16:19:49 +02:00
throw JSONRPCError ( RPC_CLIENT_NODE_NOT_ADDED , " Error: Node has not been added. " ) ;
2013-01-23 17:45:00 +01:00
}
2014-08-20 21:15:16 +02:00
return NullUniValue ;
2013-01-23 17:45:00 +01:00
}
2018-05-02 17:14:48 +02:00
static UniValue disconnectnode ( const JSONRPCRequest & request )
2015-06-12 05:20:54 +02:00
{
2017-04-03 16:03:00 +02:00
if ( request . fHelp | | request . params . size ( ) = = 0 | | request . params . size ( ) > = 3 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2017-04-03 16:03:00 +02:00
" disconnectnode \" [address] \" [nodeid] \n "
" \n Immediately disconnects from the specified peer node. \n "
" \n Strictly one out of 'address' and 'nodeid' can be provided to identify the node. \n "
" \n To disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only. \n "
2015-06-12 05:20:54 +02:00
" \n Arguments: \n "
2017-04-03 16:03:00 +02:00
" 1. \" address \" (string, optional) The IP address/port of the node \n "
" 2. \" nodeid \" (number, optional) The node ID (see getpeerinfo for node IDs) \n "
2015-06-12 05:20:54 +02:00
" \n Examples: \n "
+ HelpExampleCli ( " disconnectnode " , " \" 192.168.0.6:8333 \" " )
2017-04-03 16:03:00 +02:00
+ HelpExampleCli ( " disconnectnode " , " \" \" 1 " )
2015-06-12 05:20:54 +02:00
+ HelpExampleRpc ( " disconnectnode " , " \" 192.168.0.6:8333 \" " )
2017-04-03 16:03:00 +02:00
+ HelpExampleRpc ( " disconnectnode " , " \" \" , 1 " )
2015-06-12 05:20:54 +02:00
) ;
2016-04-17 00:30:03 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2015-06-12 05:20:54 +02:00
2017-04-03 16:03:00 +02:00
bool success ;
const UniValue & address_arg = request . params [ 0 ] ;
2017-08-15 01:38:18 +02:00
const UniValue & id_arg = request . params [ 1 ] ;
2017-04-03 16:03:00 +02:00
if ( ! address_arg . isNull ( ) & & id_arg . isNull ( ) ) {
/* handle disconnect-by-address */
success = g_connman - > DisconnectNode ( address_arg . get_str ( ) ) ;
} else if ( ! id_arg . isNull ( ) & & ( address_arg . isNull ( ) | | ( address_arg . isStr ( ) & & address_arg . get_str ( ) . empty ( ) ) ) ) {
/* handle disconnect-by-id */
NodeId nodeid = ( NodeId ) id_arg . get_int64 ( ) ;
success = g_connman - > DisconnectNode ( nodeid ) ;
} else {
throw JSONRPCError ( RPC_INVALID_PARAMS , " Only one of address and nodeid should be provided. " ) ;
}
if ( ! success ) {
2016-04-17 00:30:03 +02:00
throw JSONRPCError ( RPC_CLIENT_NODE_NOT_CONNECTED , " Node not found in connected nodes " ) ;
2017-04-03 16:03:00 +02:00
}
2015-06-12 05:20:54 +02:00
return NullUniValue ;
}
2018-05-02 17:14:48 +02:00
static UniValue getaddednodeinfo ( const JSONRPCRequest & request )
2013-01-23 17:48:17 +01:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) > 1 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2016-06-26 20:32:37 +02:00
" getaddednodeinfo ( \" node \" ) \n "
2013-10-29 12:29:44 +01:00
" \n Returns information about the given added node, or all added nodes \n "
2013-01-23 17:48:17 +01:00
" (note that onetry addnodes are not listed here) \n "
2013-10-29 12:29:44 +01:00
" \n Arguments: \n "
2016-06-26 20:32:37 +02:00
" 1. \" node \" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned. \n "
2013-10-29 12:29:44 +01:00
" \n Result: \n "
" [ \n "
" { \n "
2017-06-20 00:57:31 +02:00
" \" addednode \" : \" 192.168.0.201 \" , (string) The node IP address or name (as provided to addnode) \n "
2013-10-29 12:29:44 +01:00
" \" connected \" : true|false, (boolean) If connected \n "
2016-05-28 15:32:30 +02:00
" \" addresses \" : [ (list of objects) Only when connected = true \n "
2013-10-29 12:29:44 +01:00
" { \n "
2016-05-28 15:32:30 +02:00
" \" address \" : \" 192.168.0.201:8333 \" , (string) The bitcoin server IP and port we're connected to \n "
2013-10-29 12:29:44 +01:00
" \" connected \" : \" outbound \" (string) connection, inbound or outbound \n "
" } \n "
" ] \n "
" } \n "
" ,... \n "
" ] \n "
" \n Examples: \n "
2017-06-08 23:25:53 +02:00
+ HelpExampleCli ( " getaddednodeinfo " , " \" 192.168.0.201 \" " )
+ HelpExampleRpc ( " getaddednodeinfo " , " \" 192.168.0.201 \" " )
2013-10-29 12:29:44 +01:00
) ;
2013-01-23 17:48:17 +01:00
2016-04-17 00:12:58 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
std : : vector < AddedNodeInfo > vInfo = g_connman - > GetAddedNodeInfo ( ) ;
2013-01-23 17:48:17 +01:00
2017-08-15 01:38:18 +02:00
if ( ! request . params [ 0 ] . isNull ( ) ) {
2016-05-28 15:32:30 +02:00
bool found = false ;
for ( const AddedNodeInfo & info : vInfo ) {
2016-09-22 09:46:41 +02:00
if ( info . strAddedNode = = request . params [ 0 ] . get_str ( ) ) {
2016-05-28 15:32:30 +02:00
vInfo . assign ( 1 , info ) ;
found = true ;
2013-01-23 17:48:17 +01:00
break ;
}
2015-05-31 15:36:44 +02:00
}
2016-05-28 15:32:30 +02:00
if ( ! found ) {
2013-10-23 16:19:49 +02:00
throw JSONRPCError ( RPC_CLIENT_NODE_NOT_ADDED , " Error: Node has not been added. " ) ;
2014-01-27 10:31:22 +01:00
}
2013-01-23 17:48:17 +01:00
}
2016-05-28 15:32:30 +02:00
UniValue ret ( UniValue : : VARR ) ;
2013-01-23 17:48:17 +01:00
2016-05-28 15:32:30 +02:00
for ( const AddedNodeInfo & info : vInfo ) {
2015-05-10 14:48:35 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
obj . pushKV ( " addednode " , info . strAddedNode ) ;
obj . pushKV ( " connected " , info . fConnected ) ;
2015-05-10 14:48:35 +02:00
UniValue addresses ( UniValue : : VARR ) ;
2016-05-28 15:32:30 +02:00
if ( info . fConnected ) {
UniValue address ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
address . pushKV ( " address " , info . resolvedAddress . ToString ( ) ) ;
address . pushKV ( " connected " , info . fInbound ? " inbound " : " outbound " ) ;
2016-05-28 15:32:30 +02:00
addresses . push_back ( address ) ;
2013-01-23 17:48:17 +01:00
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " addresses " , addresses ) ;
2013-01-23 17:48:17 +01:00
ret . push_back ( obj ) ;
}
return ret ;
}
2018-05-02 17:14:48 +02:00
static UniValue getnettotals ( const JSONRPCRequest & request )
2013-08-22 18:09:32 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) > 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2013-08-22 18:09:32 +02:00
" getnettotals \n "
2013-10-29 12:29:44 +01:00
" \n Returns information about network traffic, including bytes in, bytes out, \n "
" and current time. \n "
" \n Result: \n "
" { \n "
" \" totalbytesrecv \" : n, (numeric) Total bytes received \n "
2013-12-05 08:46:50 +01:00
" \" totalbytessent \" : n, (numeric) Total bytes sent \n "
2016-11-10 10:18:52 +01:00
" \" timemillis \" : t, (numeric) Current UNIX time in milliseconds \n "
2015-11-12 13:14:54 +01:00
" \" uploadtarget \" : \n "
" { \n "
" \" timeframe \" : n, (numeric) Length of the measuring timeframe in seconds \n "
" \" target \" : n, (numeric) Target in bytes \n "
" \" target_reached \" : true|false, (boolean) True if target is reached \n "
" \" serve_historical_blocks \" : true|false, (boolean) True if serving historical blocks \n "
" \" bytes_left_in_cycle \" : t, (numeric) Bytes left in current time cycle \n "
" \" time_left_in_cycle \" : t (numeric) Seconds left in current time cycle \n "
" } \n "
2013-10-29 12:29:44 +01:00
" } \n "
" \n Examples: \n "
+ HelpExampleCli ( " getnettotals " , " " )
+ HelpExampleRpc ( " getnettotals " , " " )
) ;
2016-04-19 03:44:42 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2013-08-22 18:09:32 +02:00
2015-05-10 14:48:35 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
obj . pushKV ( " totalbytesrecv " , g_connman - > GetTotalBytesRecv ( ) ) ;
obj . pushKV ( " totalbytessent " , g_connman - > GetTotalBytesSent ( ) ) ;
obj . pushKV ( " timemillis " , GetTimeMillis ( ) ) ;
2015-09-02 17:03:27 +02:00
UniValue outboundLimit ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
outboundLimit . pushKV ( " timeframe " , g_connman - > GetMaxOutboundTimeframe ( ) ) ;
outboundLimit . pushKV ( " target " , g_connman - > GetMaxOutboundTarget ( ) ) ;
outboundLimit . pushKV ( " target_reached " , g_connman - > OutboundTargetReached ( false ) ) ;
outboundLimit . pushKV ( " serve_historical_blocks " , ! g_connman - > OutboundTargetReached ( true ) ) ;
outboundLimit . pushKV ( " bytes_left_in_cycle " , g_connman - > GetOutboundTargetBytesLeft ( ) ) ;
outboundLimit . pushKV ( " time_left_in_cycle " , g_connman - > GetMaxOutboundTimeLeftInCycle ( ) ) ;
obj . pushKV ( " uploadtarget " , outboundLimit ) ;
2013-08-22 18:09:32 +02:00
return obj ;
}
2014-05-05 13:22:28 +02:00
2015-05-13 21:29:19 +02:00
static UniValue GetNetworksInfo ( )
2014-07-30 15:35:14 +02:00
{
2015-05-10 14:48:35 +02:00
UniValue networks ( UniValue : : VARR ) ;
2014-07-30 15:35:14 +02:00
for ( int n = 0 ; n < NET_MAX ; + + n )
{
enum Network network = static_cast < enum Network > ( n ) ;
2017-05-24 02:04:38 +02:00
if ( network = = NET_UNROUTABLE | | network = = NET_INTERNAL )
2014-07-30 15:35:14 +02:00
continue ;
proxyType proxy ;
2015-05-10 14:48:35 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
2014-07-30 15:35:14 +02:00
GetProxy ( network , proxy ) ;
2017-09-22 20:04:07 +02:00
obj . pushKV ( " name " , GetNetworkName ( network ) ) ;
obj . pushKV ( " limited " , IsLimited ( network ) ) ;
obj . pushKV ( " reachable " , IsReachable ( network ) ) ;
obj . pushKV ( " proxy " , proxy . IsValid ( ) ? proxy . proxy . ToStringIPPort ( ) : std : : string ( ) ) ;
obj . pushKV ( " proxy_randomize_credentials " , proxy . randomize_credentials ) ;
2014-07-30 15:35:14 +02:00
networks . push_back ( obj ) ;
}
return networks ;
}
2018-05-02 17:14:48 +02:00
static UniValue getnetworkinfo ( const JSONRPCRequest & request )
2014-05-05 13:22:28 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) ! = 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2014-05-05 13:22:28 +02:00
" getnetworkinfo \n "
" Returns an object containing various state info regarding P2P networking. \n "
" \n Result: \n "
" { \n "
2014-09-25 11:56:05 +02:00
" \" version \" : xxxxx, (numeric) the server version \n "
" \" subversion \" : \" /Satoshi:x.x.x/ \" , (string) the server subversion string \n "
" \" protocolversion \" : xxxxx, (numeric) the protocol version \n "
" \" localservices \" : \" xxxxxxxxxxxxxxxx \" , (string) the services we offer to the network \n "
2016-05-12 14:09:43 +02:00
" \" localrelay \" : true|false, (bool) true if transaction relay is requested from peers \n "
2014-09-25 11:56:05 +02:00
" \" timeoffset \" : xxxxx, (numeric) the time offset \n "
" \" connections \" : xxxxx, (numeric) the number of connections \n "
2016-10-23 07:35:52 +02:00
" \" networkactive \" : true|false, (bool) whether p2p networking is enabled \n "
2014-09-25 11:56:05 +02:00
" \" networks \" : [ (array) information per network \n "
" { \n "
" \" name \" : \" xxx \" , (string) network (ipv4, ipv6 or onion) \n "
" \" limited \" : true|false, (boolean) is the network limited using -onlynet? \n "
" \" reachable \" : true|false, (boolean) is the network reachable? \n "
" \" proxy \" : \" host:port \" (string) the proxy that is used for this network, or empty if none \n "
2017-01-11 14:29:46 +01:00
" \" proxy_randomize_credentials \" : true|false, (string) Whether randomized credentials are used \n "
2014-09-25 11:56:05 +02:00
" } \n "
" ,... \n "
2014-07-30 15:35:14 +02:00
" ], \n "
2017-01-20 04:07:56 +01:00
" \" relayfee \" : x.xxxxxxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + " /kB \n "
2017-01-20 03:18:46 +01:00
" \" incrementalfee \" : x.xxxxxxxx, (numeric) minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + " /kB \n "
2014-09-25 11:56:05 +02:00
" \" localaddresses \" : [ (array) list of local addresses \n "
" { \n "
" \" address \" : \" xxxx \" , (string) network address \n "
" \" port \" : xxx, (numeric) network port \n "
" \" score \" : xxx (numeric) relative score \n "
" } \n "
" ,... \n "
2014-05-05 13:22:28 +02:00
" ] \n "
2017-07-18 00:55:14 +02:00
" \" warnings \" : \" ... \" (string) any network and blockchain warnings \n "
2014-05-05 13:22:28 +02:00
" } \n "
" \n Examples: \n "
+ HelpExampleCli ( " getnetworkinfo " , " " )
+ HelpExampleRpc ( " getnetworkinfo " , " " )
) ;
2014-10-19 10:46:17 +02:00
LOCK ( cs_main ) ;
2015-05-10 14:48:35 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
obj . pushKV ( " version " , CLIENT_VERSION ) ;
obj . pushKV ( " subversion " , strSubVersion ) ;
obj . pushKV ( " protocolversion " , PROTOCOL_VERSION ) ;
2016-04-19 06:04:58 +02:00
if ( g_connman )
2017-09-22 20:04:07 +02:00
obj . pushKV ( " localservices " , strprintf ( " %016x " , g_connman - > GetLocalServices ( ) ) ) ;
obj . pushKV ( " localrelay " , fRelayTxes ) ;
obj . pushKV ( " timeoffset " , GetTimeOffset ( ) ) ;
2014-11-19 13:33:34 +01:00
if ( g_connman ) {
2017-09-22 20:04:07 +02:00
obj . pushKV ( " networkactive " , g_connman - > GetNetworkActive ( ) ) ;
obj . pushKV ( " connections " , ( int ) g_connman - > GetNodeCount ( CConnman : : CONNECTIONS_ALL ) ) ;
2014-11-19 13:33:34 +01:00
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " networks " , GetNetworksInfo ( ) ) ;
obj . pushKV ( " relayfee " , ValueFromAmount ( : : minRelayTxFee . GetFeePerK ( ) ) ) ;
obj . pushKV ( " incrementalfee " , ValueFromAmount ( : : incrementalRelayFee . GetFeePerK ( ) ) ) ;
2015-05-10 14:48:35 +02:00
UniValue localAddresses ( UniValue : : VARR ) ;
2014-05-05 13:22:28 +02:00
{
LOCK ( cs_mapLocalHost ) ;
2018-05-16 00:41:53 +02:00
for ( const std : : pair < const CNetAddr , LocalServiceInfo > & item : mapLocalHost )
2014-05-05 13:22:28 +02:00
{
2015-05-10 14:48:35 +02:00
UniValue rec ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
rec . pushKV ( " address " , item . first . ToString ( ) ) ;
rec . pushKV ( " port " , item . second . nPort ) ;
rec . pushKV ( " score " , item . second . nScore ) ;
2014-05-05 13:22:28 +02:00
localAddresses . push_back ( rec ) ;
}
}
2017-09-22 20:04:07 +02:00
obj . pushKV ( " localaddresses " , localAddresses ) ;
obj . pushKV ( " warnings " , GetWarnings ( " statusbar " ) ) ;
2014-05-05 13:22:28 +02:00
return obj ;
}
2015-05-19 10:07:46 +02:00
2018-05-02 17:14:48 +02:00
static UniValue setban ( const JSONRPCRequest & request )
2015-05-19 10:07:46 +02:00
{
2017-01-04 05:22:19 +01:00
std : : string strCommand ;
2017-08-15 01:44:02 +02:00
if ( ! request . params [ 1 ] . isNull ( ) )
2016-09-22 09:46:41 +02:00
strCommand = request . params [ 1 ] . get_str ( ) ;
if ( request . fHelp | | request . params . size ( ) < 2 | |
2015-05-19 10:07:46 +02:00
( strCommand ! = " add " & & strCommand ! = " remove " ) )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2016-11-21 13:55:35 +01:00
" setban \" subnet \" \" add|remove \" (bantime) (absolute) \n "
2017-06-20 00:57:31 +02:00
" \n Attempts to add or remove an IP/Subnet from the banned list. \n "
2015-05-19 10:07:46 +02:00
" \n Arguments: \n "
2017-06-20 00:57:31 +02:00
" 1. \" subnet \" (string, required) The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP) \n "
" 2. \" command \" (string, required) 'add' to add an IP/Subnet to the list, 'remove' to remove an IP/Subnet from the list \n "
" 3. \" bantime \" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the IP is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument) \n "
" 4. \" absolute \" (boolean, optional) If set, the bantime must be an absolute timestamp in seconds since epoch (Jan 1 1970 GMT) \n "
2015-05-19 10:07:46 +02:00
" \n Examples: \n "
+ HelpExampleCli ( " setban " , " \" 192.168.0.6 \" \" add \" 86400 " )
2015-05-25 20:03:51 +02:00
+ HelpExampleCli ( " setban " , " \" 192.168.0.0/24 \" \" add \" " )
2016-08-14 14:35:27 +02:00
+ HelpExampleRpc ( " setban " , " \" 192.168.0.6 \" , \" add \" , 86400 " )
2015-05-19 10:07:46 +02:00
) ;
2016-04-16 23:43:11 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2015-05-19 10:07:46 +02:00
2015-05-25 20:03:51 +02:00
CSubNet subNet ;
CNetAddr netAddr ;
bool isSubnet = false ;
2018-01-11 21:40:51 +01:00
if ( request . params [ 0 ] . get_str ( ) . find ( ' / ' ) ! = std : : string : : npos )
2015-05-25 20:03:51 +02:00
isSubnet = true ;
2016-05-31 19:05:52 +02:00
if ( ! isSubnet ) {
CNetAddr resolved ;
2016-09-22 09:46:41 +02:00
LookupHost ( request . params [ 0 ] . get_str ( ) . c_str ( ) , resolved , false ) ;
2016-05-31 19:05:52 +02:00
netAddr = resolved ;
}
2015-05-25 20:03:51 +02:00
else
2016-09-22 09:46:41 +02:00
LookupSubNet ( request . params [ 0 ] . get_str ( ) . c_str ( ) , subNet ) ;
2015-05-25 20:03:51 +02:00
if ( ! ( isSubnet ? subNet . IsValid ( ) : netAddr . IsValid ( ) ) )
2017-02-07 18:57:37 +01:00
throw JSONRPCError ( RPC_CLIENT_INVALID_IP_OR_SUBNET , " Error: Invalid IP/Subnet " ) ;
2015-05-19 10:07:46 +02:00
if ( strCommand = = " add " )
{
2016-04-16 23:43:11 +02:00
if ( isSubnet ? g_connman - > IsBanned ( subNet ) : g_connman - > IsBanned ( netAddr ) )
2015-05-25 20:03:51 +02:00
throw JSONRPCError ( RPC_CLIENT_NODE_ALREADY_ADDED , " Error: IP/Subnet already banned " ) ;
2015-05-19 10:07:46 +02:00
int64_t banTime = 0 ; //use standard bantime if not specified
2017-08-15 01:38:18 +02:00
if ( ! request . params [ 2 ] . isNull ( ) )
2016-09-22 09:46:41 +02:00
banTime = request . params [ 2 ] . get_int64 ( ) ;
2015-05-19 10:07:46 +02:00
2015-06-12 18:31:47 +02:00
bool absolute = false ;
2017-08-15 01:38:18 +02:00
if ( request . params [ 3 ] . isTrue ( ) )
2015-06-12 18:31:47 +02:00
absolute = true ;
2016-04-16 23:43:11 +02:00
isSubnet ? g_connman - > Ban ( subNet , BanReasonManuallyAdded , banTime , absolute ) : g_connman - > Ban ( netAddr , BanReasonManuallyAdded , banTime , absolute ) ;
2015-05-19 10:07:46 +02:00
}
else if ( strCommand = = " remove " )
{
2016-04-16 23:43:11 +02:00
if ( ! ( isSubnet ? g_connman - > Unban ( subNet ) : g_connman - > Unban ( netAddr ) ) )
2017-02-07 18:57:37 +01:00
throw JSONRPCError ( RPC_CLIENT_INVALID_IP_OR_SUBNET , " Error: Unban failed. Requested address/subnet was not previously banned. " ) ;
2015-05-19 10:07:46 +02:00
}
2015-06-12 18:31:47 +02:00
return NullUniValue ;
2015-05-19 10:07:46 +02:00
}
2018-05-02 17:14:48 +02:00
static UniValue listbanned ( const JSONRPCRequest & request )
2015-05-19 10:07:46 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) ! = 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2015-05-19 10:07:46 +02:00
" listbanned \n "
2015-05-25 20:03:51 +02:00
" \n List all banned IPs/Subnets. \n "
2015-05-19 10:07:46 +02:00
" \n Examples: \n "
+ HelpExampleCli ( " listbanned " , " " )
+ HelpExampleRpc ( " listbanned " , " " )
) ;
2016-04-16 23:43:11 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2015-06-26 21:38:33 +02:00
banmap_t banMap ;
2016-04-16 23:43:11 +02:00
g_connman - > GetBanned ( banMap ) ;
2015-05-19 10:07:46 +02:00
2015-06-12 18:31:47 +02:00
UniValue bannedAddresses ( UniValue : : VARR ) ;
2017-06-04 22:02:43 +02:00
for ( const auto & entry : banMap )
2015-05-19 10:07:46 +02:00
{
2017-06-04 22:02:43 +02:00
const CBanEntry & banEntry = entry . second ;
2015-06-12 18:31:47 +02:00
UniValue rec ( UniValue : : VOBJ ) ;
2017-09-22 20:04:07 +02:00
rec . pushKV ( " address " , entry . first . ToString ( ) ) ;
rec . pushKV ( " banned_until " , banEntry . nBanUntil ) ;
rec . pushKV ( " ban_created " , banEntry . nCreateTime ) ;
rec . pushKV ( " ban_reason " , banEntry . banReasonToString ( ) ) ;
2015-06-26 21:38:33 +02:00
2015-05-19 10:07:46 +02:00
bannedAddresses . push_back ( rec ) ;
}
return bannedAddresses ;
}
2018-05-02 17:14:48 +02:00
static UniValue clearbanned ( const JSONRPCRequest & request )
2015-05-19 10:07:46 +02:00
{
2016-09-22 09:46:41 +02:00
if ( request . fHelp | | request . params . size ( ) ! = 0 )
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2015-05-19 10:07:46 +02:00
" clearbanned \n "
" \n Clear all banned IPs. \n "
" \n Examples: \n "
+ HelpExampleCli ( " clearbanned " , " " )
+ HelpExampleRpc ( " clearbanned " , " " )
) ;
2016-04-16 23:43:11 +02:00
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
2015-05-19 10:07:46 +02:00
2016-04-16 23:43:11 +02:00
g_connman - > ClearBanned ( ) ;
2015-05-19 10:07:46 +02:00
2015-06-12 18:31:47 +02:00
return NullUniValue ;
2015-05-19 10:07:46 +02:00
}
2016-03-29 19:43:02 +02:00
2018-05-02 17:14:48 +02:00
static UniValue setnetworkactive ( const JSONRPCRequest & request )
2013-03-26 02:38:24 +01:00
{
2014-11-19 13:33:34 +01:00
if ( request . fHelp | | request . params . size ( ) ! = 1 ) {
2017-01-04 05:22:19 +01:00
throw std : : runtime_error (
2016-10-23 07:35:52 +02:00
" setnetworkactive true|false \n "
2016-11-21 13:55:35 +01:00
" \n Disable/enable all p2p network activity. \n "
" \n Arguments: \n "
" 1. \" state \" (boolean, required) true to enable networking, false to disable \n "
2013-03-26 02:38:24 +01:00
) ;
}
if ( ! g_connman ) {
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
}
2014-11-19 13:33:34 +01:00
g_connman - > SetNetworkActive ( request . params [ 0 ] . get_bool ( ) ) ;
2013-03-26 02:38:24 +01:00
return g_connman - > GetNetworkActive ( ) ;
}
2016-03-29 19:43:02 +02:00
static const CRPCCommand commands [ ] =
2017-06-09 02:38:23 +02:00
{ // category name actor (function) argNames
2016-03-29 19:43:02 +02:00
// --------------------- ------------------------ ----------------------- ----------
2017-06-09 02:38:23 +02:00
{ " network " , " getconnectioncount " , & getconnectioncount , { } } ,
{ " network " , " ping " , & ping , { } } ,
{ " network " , " getpeerinfo " , & getpeerinfo , { } } ,
{ " network " , " addnode " , & addnode , { " node " , " command " } } ,
{ " network " , " disconnectnode " , & disconnectnode , { " address " , " nodeid " } } ,
{ " network " , " getaddednodeinfo " , & getaddednodeinfo , { " node " } } ,
{ " network " , " getnettotals " , & getnettotals , { } } ,
{ " network " , " getnetworkinfo " , & getnetworkinfo , { } } ,
{ " network " , " setban " , & setban , { " subnet " , " command " , " bantime " , " absolute " } } ,
{ " network " , " listbanned " , & listbanned , { } } ,
{ " network " , " clearbanned " , & clearbanned , { } } ,
{ " network " , " setnetworkactive " , & setnetworkactive , { " state " } } ,
2016-03-29 19:43:02 +02:00
} ;
2016-06-07 18:42:42 +02:00
void RegisterNetRPCCommands ( CRPCTable & t )
2016-03-29 19:43:02 +02:00
{
for ( unsigned int vcidx = 0 ; vcidx < ARRAYLEN ( commands ) ; vcidx + + )
2016-06-07 18:42:42 +02:00
t . appendCommand ( commands [ vcidx ] . name , & commands [ vcidx ] ) ;
2016-03-29 19:43:02 +02:00
}