2020-04-16 13:14:08 -04:00
// Copyright (c) 2009-2020 The Bitcoin Core developers
2014-11-19 23:19:29 -03:00
// Distributed under the MIT software license, see the accompanying
2012-06-28 23:18:38 -04:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2013-11-17 21:25:17 -03:00
2017-11-09 21:57:53 -03:00
# include <rpc/server.h>
2013-11-17 21:25:17 -03:00
2021-11-30 10:49:43 -03:00
# include <addrman.h>
2017-10-05 17:40:43 -03:00
# include <banman.h>
2020-06-02 12:46:41 -04:00
# include <chainparams.h>
2017-11-09 21:57:53 -03:00
# include <clientversion.h>
# include <core_io.h>
2019-06-20 05:37:51 -04:00
# include <net_permissions.h>
2019-10-29 05:49:48 -03:00
# include <net_processing.h>
# include <net_types.h> // For banmap_t
2017-11-09 21:57:53 -03:00
# include <netbase.h>
2019-09-17 19:28:03 -03:00
# include <node/context.h>
2019-04-02 15:14:58 -03:00
# include <policy/settings.h>
2019-09-17 20:05:26 -03:00
# include <rpc/blockchain.h>
2017-11-09 21:57:53 -03:00
# include <rpc/protocol.h>
2021-04-21 10:39:40 -04:00
# include <rpc/server_util.h>
2018-11-06 12:40:50 -03:00
# include <rpc/util.h>
2017-11-09 21:57:53 -03:00
# include <sync.h>
# include <timedata.h>
2018-10-22 19:51:11 -03:00
# include <util/strencodings.h>
2020-02-13 01:01:45 -03:00
# include <util/string.h>
2020-06-10 04:44:48 -04:00
# include <util/translation.h>
2018-11-06 12:40:50 -03:00
# include <validation.h>
2017-11-09 21:57:53 -03:00
# include <version.h>
# include <warnings.h>
2014-09-14 07:43:56 -03:00
2021-05-02 13:05:42 -04:00
# include <optional>
2015-09-04 11:11:34 -03:00
# include <univalue.h>
2012-06-28 23:18:38 -04:00
2020-09-28 20:58:31 -03:00
const std : : vector < std : : string > CONNECTION_TYPE_DOC {
" outbound-full-relay (default automatic connections) " ,
" block-relay-only (does not relay transactions or addresses) " ,
" inbound (initiated by the peer) " ,
" manual (added via addnode RPC or -addnode/-connect configuration options) " ,
" addr-fetch (short-lived automatic connection for soliciting addresses) " ,
" feeler (short-lived automatic connection for testing addresses) "
} ;
2020-09-22 13:13:52 -03:00
static RPCHelpMan getconnectioncount ( )
2012-06-28 23:18:38 -04:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " getconnectioncount " ,
2018-12-21 14:29:36 -03:00
" \n Returns the number of connections to other nodes. \n " ,
{ } ,
RPCResult {
2020-01-09 14:00:57 -03:00
RPCResult : : Type : : NUM , " " , " The connection count "
2018-12-21 14:29:36 -03:00
} ,
RPCExamples {
HelpExampleCli ( " getconnectioncount " , " " )
2013-10-29 08:29:44 -03:00
+ HelpExampleRpc ( " getconnectioncount " , " " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
const CConnman & connman = EnsureConnman ( node ) ;
2014-10-19 05:46:17 -03:00
2021-04-17 14:59:17 -04:00
return ( int ) connman . GetNodeCount ( ConnectionDirection : : Both ) ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2012-06-28 23:18:38 -04:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan ping ( )
2013-08-22 07:34:33 -04:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " ping " ,
2018-10-20 09:19:44 -03:00
" \n Requests that a ping be sent to all other nodes, to measure ping time. \n "
" Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds. \n "
" Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping. \n " ,
2018-12-21 14:29:36 -03:00
{ } ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : NONE , " " , " " } ,
2018-12-21 14:29:36 -03:00
RPCExamples {
HelpExampleCli ( " ping " , " " )
2013-10-29 08:29:44 -03:00
+ HelpExampleRpc ( " ping " , " " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
PeerManager & peerman = EnsurePeerman ( node ) ;
2013-08-22 07:34:33 -04:00
2016-04-16 20:13:12 -03:00
// Request that each node send a ping during next message processing pass
2021-04-17 14:59:17 -04:00
peerman . SendPings ( ) ;
2014-08-20 15:15:16 -04:00
return NullUniValue ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2013-08-22 07:34:33 -04:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan getpeerinfo ( )
2012-06-29 17:24:53 -04:00
{
2021-12-02 13:09:36 -03:00
return RPCHelpMan {
" getpeerinfo " ,
" \n Returns data about each connected network node as a json array of objects. \n " ,
{ } ,
RPCResult {
RPCResult : : Type : : ARR , " " , " " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
2020-01-09 14:00:57 -03:00
{
2021-12-02 13:09:36 -03:00
{ RPCResult : : Type : : NUM , " id " , " Peer index " } ,
{ RPCResult : : Type : : STR , " addr " , " (host:port) The IP address and port of the peer " } ,
{ RPCResult : : Type : : STR , " addrbind " , /* optional */ true , " (ip:port) Bind address of the connection to the peer " } ,
{ RPCResult : : Type : : STR , " addrlocal " , /* optional */ true , " (ip:port) Local address as reported by the peer " } ,
{ RPCResult : : Type : : STR , " network " , " Network ( " + Join ( GetNetworkNames ( /* append_unroutable */ true ) , " , " ) + " ) " } ,
{ RPCResult : : Type : : NUM , " mapped_as " , /* optional */ true , " The AS in the BGP route to the peer used for diversifying \n "
" peer selection (only available if the asmap config flag is set) " } ,
{ RPCResult : : Type : : STR_HEX , " services " , " The services offered " } ,
{ RPCResult : : Type : : ARR , " servicesnames " , " the services offered, in human-readable form " ,
{
{ RPCResult : : Type : : STR , " SERVICE_NAME " , " the service name if it is recognised " }
2020-01-09 14:00:57 -03:00
} } ,
2021-12-02 13:09:36 -03:00
{ RPCResult : : Type : : BOOL , " relaytxes " , " Whether peer has asked us to relay transactions to it " } ,
{ RPCResult : : Type : : NUM_TIME , " lastsend " , " The " + UNIX_EPOCH_TIME + " of the last send " } ,
{ RPCResult : : Type : : NUM_TIME , " lastrecv " , " The " + UNIX_EPOCH_TIME + " of the last receive " } ,
{ RPCResult : : Type : : NUM_TIME , " last_transaction " , " The " + UNIX_EPOCH_TIME + " of the last valid transaction received from this peer " } ,
{ RPCResult : : Type : : NUM_TIME , " last_block " , " The " + UNIX_EPOCH_TIME + " of the last block received from this peer " } ,
{ RPCResult : : Type : : NUM , " bytessent " , " The total bytes sent " } ,
{ RPCResult : : Type : : NUM , " bytesrecv " , " The total bytes received " } ,
{ RPCResult : : Type : : NUM_TIME , " conntime " , " The " + UNIX_EPOCH_TIME + " of the connection " } ,
{ RPCResult : : Type : : NUM , " timeoffset " , " The time offset in seconds " } ,
{ RPCResult : : Type : : NUM , " pingtime " , /* optional */ true , " ping time (if available) " } ,
{ RPCResult : : Type : : NUM , " minping " , /* optional */ true , " minimum observed ping time (if any at all) " } ,
{ RPCResult : : Type : : NUM , " pingwait " , /* optional */ true , " ping wait (if non-zero) " } ,
{ RPCResult : : Type : : NUM , " version " , " The peer version, such as 70001 " } ,
{ RPCResult : : Type : : STR , " subver " , " The string version " } ,
{ RPCResult : : Type : : BOOL , " inbound " , " Inbound (true) or Outbound (false) " } ,
{ RPCResult : : Type : : BOOL , " bip152_hb_to " , " Whether we selected peer as (compact blocks) high-bandwidth peer " } ,
{ RPCResult : : Type : : BOOL , " bip152_hb_from " , " Whether peer selected us as (compact blocks) high-bandwidth peer " } ,
{ RPCResult : : Type : : NUM , " startingheight " , /*optional=*/ true , " The starting height (block) of the peer " } ,
{ RPCResult : : Type : : NUM , " synced_headers " , /*optional=*/ true , " The last header we have in common with this peer " } ,
{ RPCResult : : Type : : NUM , " synced_blocks " , /*optional=*/ true , " The last block we have in common with this peer " } ,
{ RPCResult : : Type : : ARR , " inflight " , /*optional=*/ true , " " ,
{
{ RPCResult : : Type : : NUM , " n " , " The heights of blocks we're currently asking from this peer " } ,
} } ,
{ RPCResult : : Type : : BOOL , " addr_relay_enabled " , /*optional=*/ true , " Whether we participate in address relay with this peer " } ,
{ RPCResult : : Type : : NUM , " addr_processed " , /*optional=*/ true , " The total number of addresses processed, excluding those dropped due to rate limiting " } ,
{ RPCResult : : Type : : NUM , " addr_rate_limited " , /*optional=*/ true , " The total number of addresses dropped due to rate limiting " } ,
{ RPCResult : : Type : : ARR , " permissions " , " Any special permissions that have been granted to this peer " ,
{
{ RPCResult : : Type : : STR , " permission_type " , Join ( NET_PERMISSIONS_DOC , " , \n " ) + " . \n " } ,
} } ,
{ RPCResult : : Type : : NUM , " minfeefilter " , " The minimum fee rate for transactions this peer accepts " } ,
{ RPCResult : : Type : : OBJ_DYN , " bytessent_per_msg " , " " ,
{
{ RPCResult : : Type : : NUM , " msg " , " The total bytes sent aggregated by message type \n "
" When a message type is not listed in this json object, the bytes sent are 0. \n "
" Only known message types can appear as keys in the object. " }
} } ,
{ RPCResult : : Type : : OBJ_DYN , " bytesrecv_per_msg " , " " ,
{
{ RPCResult : : Type : : NUM , " msg " , " The total bytes received aggregated by message type \n "
" When a message type is not listed in this json object, the bytes received are 0. \n "
" Only known message types can appear as keys in the object and all bytes received \n "
" of unknown message types are listed under ' " + NET_MESSAGE_COMMAND_OTHER + " '. " }
} } ,
{ RPCResult : : Type : : STR , " connection_type " , " Type of connection: \n " + Join ( CONNECTION_TYPE_DOC , " , \n " ) + " . \n "
" Please note this output is unlikely to be stable in upcoming releases as we iterate to \n "
" best capture connection behaviors. " } ,
} } ,
} } ,
} ,
RPCExamples {
HelpExampleCli ( " getpeerinfo " , " " )
2013-10-29 08:29:44 -03:00
+ HelpExampleRpc ( " getpeerinfo " , " " )
2021-12-02 13:09:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
const CConnman & connman = EnsureConnman ( node ) ;
const PeerManager & peerman = EnsurePeerman ( node ) ;
2014-10-19 05:46:17 -03:00
2017-01-04 01:22:19 -03:00
std : : vector < CNodeStats > vstats ;
2021-04-17 14:59:17 -04:00
connman . GetNodeStats ( vstats ) ;
2012-06-29 17:24:53 -04:00
2015-05-10 09:48:35 -03:00
UniValue ret ( UniValue : : VARR ) ;
2012-06-29 17:24:53 -04:00
2017-06-01 21:18:57 -04:00
for ( const CNodeStats & stats : vstats ) {
2015-05-10 09:48:35 -03:00
UniValue obj ( UniValue : : VOBJ ) ;
2013-11-17 21:25:17 -03:00
CNodeStateStats statestats ;
2021-04-17 14:59:17 -04:00
bool fStateStats = peerman . GetNodeStateStats ( stats . nodeid , statestats ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " id " , stats . nodeid ) ;
2021-08-26 04:39:10 -04:00
obj . pushKV ( " addr " , stats . m_addr_name ) ;
2020-09-23 06:27:54 -03:00
if ( stats . addrBind . IsValid ( ) ) {
2017-09-22 15:04:07 -03:00
obj . pushKV ( " addrbind " , stats . addrBind . ToString ( ) ) ;
2020-09-23 06:27:54 -03:00
}
if ( ! ( stats . addrLocal . empty ( ) ) ) {
obj . pushKV ( " addrlocal " , stats . addrLocal ) ;
}
2020-12-25 10:25:45 -03:00
obj . pushKV ( " network " , GetNetworkName ( stats . m_network ) ) ;
2019-12-24 15:26:46 -03:00
if ( stats . m_mapped_as ! = 0 ) {
obj . pushKV ( " mapped_as " , uint64_t ( stats . m_mapped_as ) ) ;
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " services " , strprintf ( " %016x " , stats . nServices ) ) ;
2019-03-01 13:06:27 -03:00
obj . pushKV ( " servicesnames " , GetServicesNames ( stats . nServices ) ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " relaytxes " , stats . fRelayTxes ) ;
obj . pushKV ( " lastsend " , stats . nLastSend ) ;
obj . pushKV ( " lastrecv " , stats . nLastRecv ) ;
2020-08-15 05:07:02 -04:00
obj . pushKV ( " last_transaction " , stats . nLastTXTime ) ;
obj . pushKV ( " last_block " , stats . nLastBlockTime ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " bytessent " , stats . nSendBytes ) ;
obj . pushKV ( " bytesrecv " , stats . nRecvBytes ) ;
obj . pushKV ( " conntime " , stats . nTimeConnected ) ;
obj . pushKV ( " timeoffset " , stats . nTimeOffset ) ;
2020-09-29 23:11:53 -03:00
if ( stats . m_last_ping_time > 0u s ) {
obj . pushKV ( " pingtime " , CountSecondsDouble ( stats . m_last_ping_time ) ) ;
2020-03-05 06:44:45 -03:00
}
2020-09-29 23:11:53 -03:00
if ( stats . m_min_ping_time < std : : chrono : : microseconds : : max ( ) ) {
obj . pushKV ( " minping " , CountSecondsDouble ( stats . m_min_ping_time ) ) ;
2020-03-05 06:44:45 -03:00
}
2020-09-29 23:11:53 -03:00
if ( fStateStats & & statestats . m_ping_wait > 0 s ) {
obj . pushKV ( " pingwait " , CountSecondsDouble ( statestats . m_ping_wait ) ) ;
2020-03-05 06:44:45 -03:00
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " version " , stats . nVersion ) ;
2013-11-26 08:52:21 -03:00
// Use the sanitized form of subver here, to avoid tricksy remote peers from
2017-01-18 12:15:37 -03:00
// corrupting or modifying the JSON output by putting special characters in
2013-11-26 08:52:21 -03:00
// their ver message.
2017-09-22 15:04:07 -03:00
obj . pushKV ( " subver " , stats . cleanSubVer ) ;
obj . pushKV ( " inbound " , stats . fInbound ) ;
2020-08-21 09:20:21 -04:00
obj . pushKV ( " bip152_hb_to " , stats . m_bip152_highbandwidth_to ) ;
obj . pushKV ( " bip152_hb_from " , stats . m_bip152_highbandwidth_from ) ;
2013-11-17 21:25:17 -03:00
if ( fStateStats ) {
2020-06-16 16:27:34 -04:00
obj . pushKV ( " startingheight " , statestats . m_starting_height ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " synced_headers " , statestats . nSyncHeight ) ;
obj . pushKV ( " synced_blocks " , statestats . nCommonHeight ) ;
2015-05-10 09:48:35 -03:00
UniValue heights ( UniValue : : VARR ) ;
2018-06-18 01:58:28 -04:00
for ( const int height : statestats . vHeightInFlight ) {
2014-07-11 18:03:10 -04:00
heights . push_back ( height ) ;
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " inflight " , heights ) ;
2021-08-03 07:04:19 -04:00
obj . pushKV ( " addr_relay_enabled " , statestats . m_addr_relay_enabled ) ;
2021-07-07 14:44:40 -04:00
obj . pushKV ( " addr_processed " , statestats . m_addr_processed ) ;
obj . pushKV ( " addr_rate_limited " , statestats . m_addr_rate_limited ) ;
2013-11-17 21:25:17 -03:00
}
2019-06-20 05:37:51 -04:00
UniValue permissions ( UniValue : : VARR ) ;
for ( const auto & permission : NetPermissions : : ToStrings ( stats . m_permissionFlags ) ) {
permissions . push_back ( permission ) ;
}
obj . pushKV ( " permissions " , permissions ) ;
2018-06-22 04:53:39 -04:00
obj . pushKV ( " minfeefilter " , ValueFromAmount ( stats . minFeeFilter ) ) ;
2012-06-29 17:24:53 -04:00
2015-08-25 11:30:31 -03:00
UniValue sendPerMsgCmd ( UniValue : : VOBJ ) ;
2019-01-02 09:13:50 -03:00
for ( const auto & i : stats . mapSendBytesPerMsgCmd ) {
2015-08-25 11:30:31 -03:00
if ( i . second > 0 )
2017-09-22 15:04:07 -03:00
sendPerMsgCmd . pushKV ( i . first , i . second ) ;
2015-08-25 11:30:31 -03:00
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " bytessent_per_msg " , sendPerMsgCmd ) ;
2015-08-25 11:30:31 -03:00
UniValue recvPerMsgCmd ( UniValue : : VOBJ ) ;
2019-01-02 09:13:50 -03:00
for ( const auto & i : stats . mapRecvBytesPerMsgCmd ) {
2015-08-25 11:30:31 -03:00
if ( i . second > 0 )
2017-09-22 15:04:07 -03:00
recvPerMsgCmd . pushKV ( i . first , i . second ) ;
2015-08-25 11:30:31 -03:00
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " bytesrecv_per_msg " , recvPerMsgCmd ) ;
2021-01-02 06:44:03 -03:00
obj . pushKV ( " connection_type " , ConnectionTypeAsString ( stats . m_conn_type ) ) ;
2015-08-25 11:30:31 -03:00
2012-06-29 17:24:53 -04:00
ret . push_back ( obj ) ;
}
2012-09-18 16:07:58 -03:00
2012-06-29 17:24:53 -04:00
return ret ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2012-06-29 17:24:53 -04:00
}
2012-06-28 23:18:38 -04:00
2020-09-22 13:13:52 -03:00
static RPCHelpMan addnode ( )
2013-01-23 13:45:00 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " addnode " ,
2018-10-20 09:19:44 -03:00
" \n Attempts to add or remove a node from the addnode list. \n "
" Or try a connection to a node once. \n "
" Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be \n "
2021-04-16 14:06:36 -04:00
" full nodes/support SegWit as other outbound peers are (though such peers will not be synced from). \n " +
strprintf ( " Addnode connections are limited to %u at a time " , MAX_ADDNODE_CONNECTIONS ) +
" and are counted separately from the -maxconnections limit. \n " ,
2018-10-20 09:19:44 -03:00
{
2018-12-10 18:56:51 -03:00
{ " node " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " The node (see getpeerinfo for nodes) " } ,
{ " command " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " '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 " } ,
2018-12-21 14:29:36 -03:00
} ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : NONE , " " , " " } ,
2018-12-21 14:29:36 -03:00
RPCExamples {
HelpExampleCli ( " addnode " , " \" 192.168.0.6:8333 \" \" onetry \" " )
2013-10-29 08:29:44 -03:00
+ HelpExampleRpc ( " addnode " , " \" 192.168.0.6:8333 \" , \" onetry \" " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
std : : string strCommand ;
if ( ! request . params [ 1 ] . isNull ( ) )
strCommand = request . params [ 1 ] . get_str ( ) ;
2020-09-22 14:08:36 -03:00
if ( strCommand ! = " onetry " & & strCommand ! = " add " & & strCommand ! = " remove " ) {
2020-09-22 13:13:52 -03:00
throw std : : runtime_error (
self . ToString ( ) ) ;
2020-09-22 14:08:36 -03:00
}
2013-01-23 13:45:00 -03:00
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
CConnman & connman = EnsureConnman ( node ) ;
2016-04-16 16:59:10 -03:00
2017-01-04 01:22:19 -03:00
std : : string strNode = request . params [ 0 ] . get_str ( ) ;
2013-01-23 13:45:00 -03:00
if ( strCommand = = " onetry " )
{
CAddress addr ;
2021-04-17 14:59:17 -04:00
connman . OpenNetworkConnection ( addr , false , nullptr , strNode . c_str ( ) , ConnectionType : : MANUAL ) ;
2014-08-20 15:15:16 -04:00
return NullUniValue ;
2013-01-23 13:45:00 -03:00
}
if ( strCommand = = " add " )
{
2021-04-17 14:59:17 -04:00
if ( ! connman . AddNode ( strNode ) ) {
2013-10-23 11:19:49 -03:00
throw JSONRPCError ( RPC_CLIENT_NODE_ALREADY_ADDED , " Error: Node already added " ) ;
2021-04-17 14:59:17 -04:00
}
2013-01-23 13:45:00 -03:00
}
else if ( strCommand = = " remove " )
{
2021-04-17 14:59:17 -04:00
if ( ! connman . RemoveAddedNode ( strNode ) ) {
2020-08-10 18:01:53 -04:00
throw JSONRPCError ( RPC_CLIENT_NODE_NOT_ADDED , " Error: Node could not be removed. It has not been added previously. " ) ;
2021-04-17 14:59:17 -04:00
}
2013-01-23 13:45:00 -03:00
}
2014-08-20 15:15:16 -04:00
return NullUniValue ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2013-01-23 13:45:00 -03:00
}
2020-06-02 12:46:41 -04:00
static RPCHelpMan addconnection ( )
{
return RPCHelpMan { " addconnection " ,
" \n Open an outbound connection to a specified node. This RPC is for testing only. \n " ,
{
{ " address " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " The IP address and port to attempt connecting to. " } ,
2021-05-31 16:49:42 -04:00
{ " connection_type " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " Type of connection to open ( \" outbound-full-relay \" , \" block-relay-only \" or \" addr-fetch \" ). " } ,
2020-06-02 12:46:41 -04:00
} ,
RPCResult {
RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : STR , " address " , " Address of newly added connection. " } ,
{ RPCResult : : Type : : STR , " connection_type " , " Type of connection opened. " } ,
} } ,
RPCExamples {
HelpExampleCli ( " addconnection " , " \" 192.168.0.6:8333 \" \" outbound-full-relay \" " )
+ HelpExampleRpc ( " addconnection " , " \" 192.168.0.6:8333 \" \" outbound-full-relay \" " )
} ,
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
if ( Params ( ) . NetworkIDString ( ) ! = CBaseChainParams : : REGTEST ) {
throw std : : runtime_error ( " addconnection is for regression testing (-regtest mode) only. " ) ;
}
RPCTypeCheck ( request . params , { UniValue : : VSTR , UniValue : : VSTR } ) ;
const std : : string address = request . params [ 0 ] . get_str ( ) ;
const std : : string conn_type_in { TrimString ( request . params [ 1 ] . get_str ( ) ) } ;
ConnectionType conn_type { } ;
if ( conn_type_in = = " outbound-full-relay " ) {
conn_type = ConnectionType : : OUTBOUND_FULL_RELAY ;
} else if ( conn_type_in = = " block-relay-only " ) {
conn_type = ConnectionType : : BLOCK_RELAY ;
2021-05-31 16:49:42 -04:00
} else if ( conn_type_in = = " addr-fetch " ) {
conn_type = ConnectionType : : ADDR_FETCH ;
2020-06-02 12:46:41 -04:00
} else {
throw JSONRPCError ( RPC_INVALID_PARAMETER , self . ToString ( ) ) ;
}
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
CConnman & connman = EnsureConnman ( node ) ;
2020-06-02 12:46:41 -04:00
2021-04-17 14:59:17 -04:00
const bool success = connman . AddConnection ( address , conn_type ) ;
2020-06-02 12:46:41 -04:00
if ( ! success ) {
throw JSONRPCError ( RPC_CLIENT_NODE_CAPACITY_REACHED , " Error: Already at capacity for specified connection type. " ) ;
}
UniValue info ( UniValue : : VOBJ ) ;
info . pushKV ( " address " , address ) ;
info . pushKV ( " connection_type " , conn_type_in ) ;
return info ;
} ,
} ;
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan disconnectnode ( )
2015-06-12 00:20:54 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " disconnectnode " ,
2018-10-20 09:19:44 -03:00
" \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 " ,
{
2021-04-14 10:01:00 -04:00
{ " address " , RPCArg : : Type : : STR , RPCArg : : DefaultHint { " fallback to nodeid " } , " The IP address/port of the node " } ,
{ " nodeid " , RPCArg : : Type : : NUM , RPCArg : : DefaultHint { " fallback to address " } , " The node ID (see getpeerinfo for node IDs) " } ,
2018-12-21 14:29:36 -03:00
} ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : NONE , " " , " " } ,
2018-12-21 14:29:36 -03:00
RPCExamples {
HelpExampleCli ( " disconnectnode " , " \" 192.168.0.6:8333 \" " )
2017-04-03 11:03:00 -03:00
+ HelpExampleCli ( " disconnectnode " , " \" \" 1 " )
2015-06-12 00:20:54 -03:00
+ HelpExampleRpc ( " disconnectnode " , " \" 192.168.0.6:8333 \" " )
2017-04-03 11:03:00 -03:00
+ HelpExampleRpc ( " disconnectnode " , " \" \" , 1 " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
CConnman & connman = EnsureConnman ( node ) ;
2015-06-12 00:20:54 -03:00
2017-04-03 11:03:00 -03:00
bool success ;
const UniValue & address_arg = request . params [ 0 ] ;
2017-08-14 20:38:18 -03:00
const UniValue & id_arg = request . params [ 1 ] ;
2017-04-03 11:03:00 -03:00
if ( ! address_arg . isNull ( ) & & id_arg . isNull ( ) ) {
/* handle disconnect-by-address */
2021-04-17 14:59:17 -04:00
success = connman . DisconnectNode ( address_arg . get_str ( ) ) ;
2017-04-03 11:03:00 -03:00
} 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 ( ) ;
2021-04-17 14:59:17 -04:00
success = connman . DisconnectNode ( nodeid ) ;
2017-04-03 11:03:00 -03:00
} else {
throw JSONRPCError ( RPC_INVALID_PARAMS , " Only one of address and nodeid should be provided. " ) ;
}
if ( ! success ) {
2016-04-16 19:30:03 -03:00
throw JSONRPCError ( RPC_CLIENT_NODE_NOT_CONNECTED , " Node not found in connected nodes " ) ;
2017-04-03 11:03:00 -03:00
}
2015-06-12 00:20:54 -03:00
return NullUniValue ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2015-06-12 00:20:54 -03:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan getaddednodeinfo ( )
2013-01-23 13:48:17 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " getaddednodeinfo " ,
2018-10-20 09:19:44 -03:00
" \n Returns information about the given added node, or all added nodes \n "
" (note that onetry addnodes are not listed here) \n " ,
{
2021-04-14 10:01:00 -04:00
{ " node " , RPCArg : : Type : : STR , RPCArg : : DefaultHint { " all nodes " } , " If provided, return information about this specific node, otherwise all nodes are returned. " } ,
2018-12-21 14:29:36 -03:00
} ,
RPCResult {
2020-01-09 14:00:57 -03:00
RPCResult : : Type : : ARR , " " , " " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : STR , " addednode " , " The node IP address or name (as provided to addnode) " } ,
{ RPCResult : : Type : : BOOL , " connected " , " If connected " } ,
{ RPCResult : : Type : : ARR , " addresses " , " Only when connected = true " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : STR , " address " , " The bitcoin server IP and port we're connected to " } ,
{ RPCResult : : Type : : STR , " connected " , " connection, inbound or outbound " } ,
} } ,
} } ,
} } ,
}
2018-12-21 14:29:36 -03:00
} ,
RPCExamples {
HelpExampleCli ( " getaddednodeinfo " , " \" 192.168.0.201 \" " )
2017-06-08 17:25:53 -04:00
+ HelpExampleRpc ( " getaddednodeinfo " , " \" 192.168.0.201 \" " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
const CConnman & connman = EnsureConnman ( node ) ;
2016-04-16 19:12:58 -03:00
2021-04-17 14:59:17 -04:00
std : : vector < AddedNodeInfo > vInfo = connman . GetAddedNodeInfo ( ) ;
2013-01-23 13:48:17 -03:00
2017-08-14 20:38:18 -03:00
if ( ! request . params [ 0 ] . isNull ( ) ) {
2016-05-28 09:32:30 -04:00
bool found = false ;
for ( const AddedNodeInfo & info : vInfo ) {
2016-09-22 04:46:41 -03:00
if ( info . strAddedNode = = request . params [ 0 ] . get_str ( ) ) {
2016-05-28 09:32:30 -04:00
vInfo . assign ( 1 , info ) ;
found = true ;
2013-01-23 13:48:17 -03:00
break ;
}
2015-05-31 10:36:44 -03:00
}
2016-05-28 09:32:30 -04:00
if ( ! found ) {
2013-10-23 11:19:49 -03:00
throw JSONRPCError ( RPC_CLIENT_NODE_NOT_ADDED , " Error: Node has not been added. " ) ;
2014-01-27 06:31:22 -03:00
}
2013-01-23 13:48:17 -03:00
}
2016-05-28 09:32:30 -04:00
UniValue ret ( UniValue : : VARR ) ;
2013-01-23 13:48:17 -03:00
2016-05-28 09:32:30 -04:00
for ( const AddedNodeInfo & info : vInfo ) {
2015-05-10 09:48:35 -03:00
UniValue obj ( UniValue : : VOBJ ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " addednode " , info . strAddedNode ) ;
obj . pushKV ( " connected " , info . fConnected ) ;
2015-05-10 09:48:35 -03:00
UniValue addresses ( UniValue : : VARR ) ;
2016-05-28 09:32:30 -04:00
if ( info . fConnected ) {
UniValue address ( UniValue : : VOBJ ) ;
2017-09-22 15:04:07 -03:00
address . pushKV ( " address " , info . resolvedAddress . ToString ( ) ) ;
address . pushKV ( " connected " , info . fInbound ? " inbound " : " outbound " ) ;
2016-05-28 09:32:30 -04:00
addresses . push_back ( address ) ;
2013-01-23 13:48:17 -03:00
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " addresses " , addresses ) ;
2013-01-23 13:48:17 -03:00
ret . push_back ( obj ) ;
}
return ret ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2013-01-23 13:48:17 -03:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan getnettotals ( )
2013-08-22 12:09:32 -04:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " getnettotals " ,
2018-10-20 09:19:44 -03:00
" \n Returns information about network traffic, including bytes in, bytes out, \n "
" and current time. \n " ,
2018-12-21 14:29:36 -03:00
{ } ,
RPCResult {
2020-01-09 14:00:57 -03:00
RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : NUM , " totalbytesrecv " , " Total bytes received " } ,
{ RPCResult : : Type : : NUM , " totalbytessent " , " Total bytes sent " } ,
2020-06-29 04:31:25 -04:00
{ RPCResult : : Type : : NUM_TIME , " timemillis " , " Current " + UNIX_EPOCH_TIME + " in milliseconds " } ,
2020-01-09 14:00:57 -03:00
{ RPCResult : : Type : : OBJ , " uploadtarget " , " " ,
{
{ RPCResult : : Type : : NUM , " timeframe " , " Length of the measuring timeframe in seconds " } ,
{ RPCResult : : Type : : NUM , " target " , " Target in bytes " } ,
{ RPCResult : : Type : : BOOL , " target_reached " , " True if target is reached " } ,
{ RPCResult : : Type : : BOOL , " serve_historical_blocks " , " True if serving historical blocks " } ,
{ RPCResult : : Type : : NUM , " bytes_left_in_cycle " , " Bytes left in current time cycle " } ,
{ RPCResult : : Type : : NUM , " time_left_in_cycle " , " Seconds left in current time cycle " } ,
} } ,
}
2018-12-21 14:29:36 -03:00
} ,
RPCExamples {
HelpExampleCli ( " getnettotals " , " " )
2013-10-29 08:29:44 -03:00
+ HelpExampleRpc ( " getnettotals " , " " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
const CConnman & connman = EnsureConnman ( node ) ;
2013-08-22 12:09:32 -04:00
2015-05-10 09:48:35 -03:00
UniValue obj ( UniValue : : VOBJ ) ;
2021-04-17 14:59:17 -04:00
obj . pushKV ( " totalbytesrecv " , connman . GetTotalBytesRecv ( ) ) ;
obj . pushKV ( " totalbytessent " , connman . GetTotalBytesSent ( ) ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " timemillis " , GetTimeMillis ( ) ) ;
2015-09-02 12:03:27 -03:00
UniValue outboundLimit ( UniValue : : VOBJ ) ;
2021-04-17 14:59:17 -04:00
outboundLimit . pushKV ( " timeframe " , count_seconds ( connman . GetMaxOutboundTimeframe ( ) ) ) ;
outboundLimit . pushKV ( " target " , connman . GetMaxOutboundTarget ( ) ) ;
outboundLimit . pushKV ( " target_reached " , connman . OutboundTargetReached ( false ) ) ;
outboundLimit . pushKV ( " serve_historical_blocks " , ! connman . OutboundTargetReached ( true ) ) ;
outboundLimit . pushKV ( " bytes_left_in_cycle " , connman . GetOutboundTargetBytesLeft ( ) ) ;
outboundLimit . pushKV ( " time_left_in_cycle " , count_seconds ( connman . GetMaxOutboundTimeLeftInCycle ( ) ) ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " uploadtarget " , outboundLimit ) ;
2013-08-22 12:09:32 -04:00
return obj ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2013-08-22 12:09:32 -04:00
}
2014-05-05 07:22:28 -04:00
2015-05-13 16:29:19 -03:00
static UniValue GetNetworksInfo ( )
2014-07-30 09:35:14 -04:00
{
2015-05-10 09:48:35 -03:00
UniValue networks ( UniValue : : VARR ) ;
2020-10-11 06:49:08 -03:00
for ( int n = 0 ; n < NET_MAX ; + + n ) {
2014-07-30 09:35:14 -04:00
enum Network network = static_cast < enum Network > ( n ) ;
2021-09-21 12:03:47 -03:00
if ( network = = NET_UNROUTABLE | | network = = NET_INTERNAL ) continue ;
2014-07-30 09:35:14 -04:00
proxyType proxy ;
2015-05-10 09:48:35 -03:00
UniValue obj ( UniValue : : VOBJ ) ;
2014-07-30 09:35:14 -04:00
GetProxy ( network , proxy ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " name " , GetNetworkName ( network ) ) ;
2019-01-09 21:41:37 -03:00
obj . pushKV ( " limited " , ! IsReachable ( network ) ) ;
2017-09-22 15:04:07 -03:00
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 09:35:14 -04:00
networks . push_back ( obj ) ;
}
return networks ;
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan getnetworkinfo ( )
2014-05-05 07:22:28 -04:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " getnetworkinfo " ,
2018-12-21 14:29:36 -03:00
" Returns an object containing various state info regarding P2P networking. \n " ,
{ } ,
RPCResult {
2020-01-09 14:00:57 -03:00
RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : NUM , " version " , " the server version " } ,
{ RPCResult : : Type : : STR , " subversion " , " the server subversion string " } ,
{ RPCResult : : Type : : NUM , " protocolversion " , " the protocol version " } ,
{ RPCResult : : Type : : STR_HEX , " localservices " , " the services we offer to the network " } ,
{ RPCResult : : Type : : ARR , " localservicesnames " , " the services we offer to the network, in human-readable form " ,
{
{ RPCResult : : Type : : STR , " SERVICE_NAME " , " the service name " } ,
} } ,
{ RPCResult : : Type : : BOOL , " localrelay " , " true if transaction relay is requested from peers " } ,
{ RPCResult : : Type : : NUM , " timeoffset " , " the time offset " } ,
2020-06-29 04:04:08 -04:00
{ RPCResult : : Type : : NUM , " connections " , " the total number of connections " } ,
{ RPCResult : : Type : : NUM , " connections_in " , " the number of inbound connections " } ,
{ RPCResult : : Type : : NUM , " connections_out " , " the number of outbound connections " } ,
2020-01-09 14:00:57 -03:00
{ RPCResult : : Type : : BOOL , " networkactive " , " whether p2p networking is enabled " } ,
{ RPCResult : : Type : : ARR , " networks " , " information per network " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
2021-02-01 19:56:20 -03:00
{ RPCResult : : Type : : STR , " name " , " network ( " + Join ( GetNetworkNames ( ) , " , " ) + " ) " } ,
2020-01-09 14:00:57 -03:00
{ RPCResult : : Type : : BOOL , " limited " , " is the network limited using -onlynet? " } ,
{ RPCResult : : Type : : BOOL , " reachable " , " is the network reachable? " } ,
{ RPCResult : : Type : : STR , " proxy " , " ( \" host:port \" ) the proxy that is used for this network, or empty if none " } ,
{ RPCResult : : Type : : BOOL , " proxy_randomize_credentials " , " Whether randomized credentials are used " } ,
} } ,
} } ,
2021-05-01 12:29:22 -04:00
{ RPCResult : : Type : : NUM , " relayfee " , " minimum relay fee rate for transactions in " + CURRENCY_UNIT + " /kvB " } ,
{ RPCResult : : Type : : NUM , " incrementalfee " , " minimum fee rate increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + " /kvB " } ,
2020-01-09 14:00:57 -03:00
{ RPCResult : : Type : : ARR , " localaddresses " , " list of local addresses " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : STR , " address " , " network address " } ,
{ RPCResult : : Type : : NUM , " port " , " network port " } ,
{ RPCResult : : Type : : NUM , " score " , " relative score " } ,
} } ,
} } ,
{ RPCResult : : Type : : STR , " warnings " , " any network and blockchain warnings " } ,
}
2018-12-21 14:29:36 -03:00
} ,
RPCExamples {
HelpExampleCli ( " getnetworkinfo " , " " )
2014-05-05 07:22:28 -04:00
+ HelpExampleRpc ( " getnetworkinfo " , " " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2014-10-19 05:46:17 -03:00
LOCK ( cs_main ) ;
2015-05-10 09:48:35 -03:00
UniValue obj ( UniValue : : VOBJ ) ;
2017-09-22 15:04:07 -03:00
obj . pushKV ( " version " , CLIENT_VERSION ) ;
obj . pushKV ( " subversion " , strSubVersion ) ;
obj . pushKV ( " protocolversion " , PROTOCOL_VERSION ) ;
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2020-04-17 11:28:45 -04:00
if ( node . connman ) {
2020-04-17 11:32:13 -04:00
ServiceFlags services = node . connman - > GetLocalServices ( ) ;
2019-03-01 13:06:27 -03:00
obj . pushKV ( " localservices " , strprintf ( " %016x " , services ) ) ;
obj . pushKV ( " localservicesnames " , GetServicesNames ( services ) ) ;
}
2020-10-22 06:38:10 -03:00
if ( node . peerman ) {
obj . pushKV ( " localrelay " , ! node . peerman - > IgnoresIncomingTxs ( ) ) ;
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " timeoffset " , GetTimeOffset ( ) ) ;
2020-04-17 11:32:13 -04:00
if ( node . connman ) {
obj . pushKV ( " networkactive " , node . connman - > GetNetworkActive ( ) ) ;
2019-10-16 14:37:19 -03:00
obj . pushKV ( " connections " , ( int ) node . connman - > GetNodeCount ( ConnectionDirection : : Both ) ) ;
obj . pushKV ( " connections_in " , ( int ) node . connman - > GetNodeCount ( ConnectionDirection : : In ) ) ;
obj . pushKV ( " connections_out " , ( int ) node . connman - > GetNodeCount ( ConnectionDirection : : Out ) ) ;
2014-11-19 09:33:34 -03:00
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " networks " , GetNetworksInfo ( ) ) ;
obj . pushKV ( " relayfee " , ValueFromAmount ( : : minRelayTxFee . GetFeePerK ( ) ) ) ;
obj . pushKV ( " incrementalfee " , ValueFromAmount ( : : incrementalRelayFee . GetFeePerK ( ) ) ) ;
2015-05-10 09:48:35 -03:00
UniValue localAddresses ( UniValue : : VARR ) ;
2014-05-05 07:22:28 -04:00
{
LOCK ( cs_mapLocalHost ) ;
2018-05-15 18:41:53 -04:00
for ( const std : : pair < const CNetAddr , LocalServiceInfo > & item : mapLocalHost )
2014-05-05 07:22:28 -04:00
{
2015-05-10 09:48:35 -03:00
UniValue rec ( UniValue : : VOBJ ) ;
2017-09-22 15:04:07 -03:00
rec . pushKV ( " address " , item . first . ToString ( ) ) ;
rec . pushKV ( " port " , item . second . nPort ) ;
rec . pushKV ( " score " , item . second . nScore ) ;
2014-05-05 07:22:28 -04:00
localAddresses . push_back ( rec ) ;
}
}
2017-09-22 15:04:07 -03:00
obj . pushKV ( " localaddresses " , localAddresses ) ;
2020-06-10 04:44:48 -04:00
obj . pushKV ( " warnings " , GetWarnings ( false ) . original ) ;
2014-05-05 07:22:28 -04:00
return obj ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2014-05-05 07:22:28 -04:00
}
2015-05-19 05:07:46 -03:00
2020-09-22 13:13:52 -03:00
static RPCHelpMan setban ( )
2015-05-19 05:07:46 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " setban " ,
2018-10-20 09:19:44 -03:00
" \n Attempts to add or remove an IP/Subnet from the banned list. \n " ,
{
2018-12-10 18:56:51 -03:00
{ " subnet " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP) " } ,
{ " command " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " 'add' to add an IP/Subnet to the list, 'remove' to remove an IP/Subnet from the list " } ,
2021-04-14 10:01:00 -04:00
{ " bantime " , RPCArg : : Type : : NUM , RPCArg : : Default { 0 } , " 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) " } ,
{ " absolute " , RPCArg : : Type : : BOOL , RPCArg : : Default { false } , " If set, the bantime must be an absolute timestamp expressed in " + UNIX_EPOCH_TIME } ,
2018-12-21 14:29:36 -03:00
} ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : NONE , " " , " " } ,
2018-12-21 14:29:36 -03:00
RPCExamples {
HelpExampleCli ( " setban " , " \" 192.168.0.6 \" \" add \" 86400 " )
2015-05-25 15:03:51 -03:00
+ HelpExampleCli ( " setban " , " \" 192.168.0.0/24 \" \" add \" " )
2016-08-14 09:35:27 -03:00
+ HelpExampleRpc ( " setban " , " \" 192.168.0.6 \" , \" add \" , 86400 " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & help , const JSONRPCRequest & request ) - > UniValue
{
2019-02-13 18:51:27 -03:00
std : : string strCommand ;
if ( ! request . params [ 1 ] . isNull ( ) )
strCommand = request . params [ 1 ] . get_str ( ) ;
2020-09-22 14:08:36 -03:00
if ( strCommand ! = " add " & & strCommand ! = " remove " ) {
2019-02-13 18:51:27 -03:00
throw std : : runtime_error ( help . ToString ( ) ) ;
}
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2020-04-17 11:28:45 -04:00
if ( ! node . banman ) {
2017-10-05 14:10:58 -03:00
throw JSONRPCError ( RPC_DATABASE_ERROR , " Error: Ban database not loaded " ) ;
}
2015-05-19 05:07:46 -03:00
2015-05-25 15:03:51 -03:00
CSubNet subNet ;
CNetAddr netAddr ;
bool isSubnet = false ;
2018-01-11 17:40:51 -03:00
if ( request . params [ 0 ] . get_str ( ) . find ( ' / ' ) ! = std : : string : : npos )
2015-05-25 15:03:51 -03:00
isSubnet = true ;
2016-05-31 13:05:52 -04:00
if ( ! isSubnet ) {
CNetAddr resolved ;
2019-12-11 13:39:29 -03:00
LookupHost ( request . params [ 0 ] . get_str ( ) , resolved , false ) ;
2016-05-31 13:05:52 -04:00
netAddr = resolved ;
}
2015-05-25 15:03:51 -03:00
else
2019-12-11 13:39:29 -03:00
LookupSubNet ( request . params [ 0 ] . get_str ( ) , subNet ) ;
2015-05-25 15:03:51 -03:00
if ( ! ( isSubnet ? subNet . IsValid ( ) : netAddr . IsValid ( ) ) )
2017-02-07 14:57:37 -03:00
throw JSONRPCError ( RPC_CLIENT_INVALID_IP_OR_SUBNET , " Error: Invalid IP/Subnet " ) ;
2015-05-19 05:07:46 -03:00
if ( strCommand = = " add " )
{
2020-06-10 20:11:38 -04:00
if ( isSubnet ? node . banman - > IsBanned ( subNet ) : node . banman - > IsBanned ( netAddr ) ) {
2015-05-25 15:03:51 -03:00
throw JSONRPCError ( RPC_CLIENT_NODE_ALREADY_ADDED , " Error: IP/Subnet already banned " ) ;
2017-10-05 14:10:58 -03:00
}
2015-05-19 05:07:46 -03:00
int64_t banTime = 0 ; //use standard bantime if not specified
2017-08-14 20:38:18 -03:00
if ( ! request . params [ 2 ] . isNull ( ) )
2016-09-22 04:46:41 -03:00
banTime = request . params [ 2 ] . get_int64 ( ) ;
2015-05-19 05:07:46 -03:00
2015-06-12 13:31:47 -03:00
bool absolute = false ;
2017-08-14 20:38:18 -03:00
if ( request . params [ 3 ] . isTrue ( ) )
2015-06-12 13:31:47 -03:00
absolute = true ;
2017-10-04 19:25:34 -03:00
if ( isSubnet ) {
2020-06-10 20:11:38 -04:00
node . banman - > Ban ( subNet , banTime , absolute ) ;
2020-04-17 11:32:13 -04:00
if ( node . connman ) {
node . connman - > DisconnectNode ( subNet ) ;
2017-10-05 14:10:58 -03:00
}
2017-10-04 19:25:34 -03:00
} else {
2020-06-10 20:11:38 -04:00
node . banman - > Ban ( netAddr , banTime , absolute ) ;
2020-04-17 11:32:13 -04:00
if ( node . connman ) {
node . connman - > DisconnectNode ( netAddr ) ;
2017-10-05 14:10:58 -03:00
}
2017-10-04 19:25:34 -03:00
}
2015-05-19 05:07:46 -03:00
}
else if ( strCommand = = " remove " )
{
2020-04-17 11:32:13 -04:00
if ( ! ( isSubnet ? node . banman - > Unban ( subNet ) : node . banman - > Unban ( netAddr ) ) ) {
2020-06-08 21:46:53 -04:00
throw JSONRPCError ( RPC_CLIENT_INVALID_IP_OR_SUBNET , " Error: Unban failed. Requested address/subnet was not previously manually banned. " ) ;
2017-10-05 14:10:58 -03:00
}
2015-05-19 05:07:46 -03:00
}
2015-06-12 13:31:47 -03:00
return NullUniValue ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2015-05-19 05:07:46 -03:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan listbanned ( )
2015-05-19 05:07:46 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " listbanned " ,
2020-06-08 21:46:53 -04:00
" \n List all manually banned IPs/Subnets. \n " ,
2018-12-21 14:29:36 -03:00
{ } ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : ARR , " " , " " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
2021-04-06 18:18:52 -04:00
{ RPCResult : : Type : : STR , " address " , " The IP/Subnet of the banned node " } ,
{ RPCResult : : Type : : NUM_TIME , " ban_created " , " The " + UNIX_EPOCH_TIME + " the ban was created " } ,
{ RPCResult : : Type : : NUM_TIME , " banned_until " , " The " + UNIX_EPOCH_TIME + " the ban expires " } ,
2021-04-06 23:01:10 -04:00
{ RPCResult : : Type : : NUM_TIME , " ban_duration " , " The ban duration, in seconds " } ,
2021-04-06 23:45:31 -04:00
{ RPCResult : : Type : : NUM_TIME , " time_remaining " , " The time remaining until the ban expires, in seconds " } ,
2020-03-13 15:40:53 -03:00
} } ,
} } ,
2018-12-21 14:29:36 -03:00
RPCExamples {
HelpExampleCli ( " listbanned " , " " )
2015-05-19 05:07:46 -03:00
+ HelpExampleRpc ( " listbanned " , " " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2020-04-17 11:28:45 -04:00
if ( ! node . banman ) {
2017-10-05 14:10:58 -03:00
throw JSONRPCError ( RPC_DATABASE_ERROR , " Error: Ban database not loaded " ) ;
}
2016-04-16 18:43:11 -03:00
2015-06-26 16:38:33 -03:00
banmap_t banMap ;
2020-04-17 11:32:13 -04:00
node . banman - > GetBanned ( banMap ) ;
2021-04-06 23:45:31 -04:00
const int64_t current_time { GetTime ( ) } ;
2015-05-19 05:07:46 -03:00
2015-06-12 13:31:47 -03:00
UniValue bannedAddresses ( UniValue : : VARR ) ;
2017-06-04 16:02:43 -04:00
for ( const auto & entry : banMap )
2015-05-19 05:07:46 -03:00
{
2017-06-04 16:02:43 -04:00
const CBanEntry & banEntry = entry . second ;
2015-06-12 13:31:47 -03:00
UniValue rec ( UniValue : : VOBJ ) ;
2017-09-22 15:04:07 -03:00
rec . pushKV ( " address " , entry . first . ToString ( ) ) ;
rec . pushKV ( " ban_created " , banEntry . nCreateTime ) ;
2021-04-06 17:54:29 -04:00
rec . pushKV ( " banned_until " , banEntry . nBanUntil ) ;
2021-04-06 23:01:10 -04:00
rec . pushKV ( " ban_duration " , ( banEntry . nBanUntil - banEntry . nCreateTime ) ) ;
2021-04-06 23:45:31 -04:00
rec . pushKV ( " time_remaining " , ( banEntry . nBanUntil - current_time ) ) ;
2015-06-26 16:38:33 -03:00
2015-05-19 05:07:46 -03:00
bannedAddresses . push_back ( rec ) ;
}
return bannedAddresses ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2015-05-19 05:07:46 -03:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan clearbanned ( )
2015-05-19 05:07:46 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " clearbanned " ,
2018-12-21 14:29:36 -03:00
" \n Clear all banned IPs. \n " ,
{ } ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : NONE , " " , " " } ,
2018-12-21 14:29:36 -03:00
RPCExamples {
HelpExampleCli ( " clearbanned " , " " )
2015-05-19 05:07:46 -03:00
+ HelpExampleRpc ( " clearbanned " , " " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2020-04-17 11:28:45 -04:00
if ( ! node . banman ) {
2017-10-05 14:10:58 -03:00
throw JSONRPCError ( RPC_DATABASE_ERROR , " Error: Ban database not loaded " ) ;
}
2015-05-19 05:07:46 -03:00
2020-04-17 11:32:13 -04:00
node . banman - > ClearBanned ( ) ;
2015-05-19 05:07:46 -03:00
2015-06-12 13:31:47 -03:00
return NullUniValue ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2015-05-19 05:07:46 -03:00
}
2016-03-29 14:43:02 -03:00
2020-09-22 13:13:52 -03:00
static RPCHelpMan setnetworkactive ( )
2013-03-25 22:38:24 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " setnetworkactive " ,
2018-10-20 09:19:44 -03:00
" \n Disable/enable all p2p network activity. \n " ,
{
2018-12-10 18:56:51 -03:00
{ " state " , RPCArg : : Type : : BOOL , RPCArg : : Optional : : NO , " true to enable networking, false to disable " } ,
2018-12-21 14:29:36 -03:00
} ,
2020-03-13 15:40:53 -03:00
RPCResult { RPCResult : : Type : : BOOL , " " , " The value that was passed in " } ,
2018-12-21 14:29:36 -03:00
RPCExamples { " " } ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
CConnman & connman = EnsureConnman ( node ) ;
2013-03-25 22:38:24 -03:00
2021-04-17 14:59:17 -04:00
connman . SetNetworkActive ( request . params [ 0 ] . get_bool ( ) ) ;
2013-03-25 22:38:24 -03:00
2021-04-17 14:59:17 -04:00
return connman . GetNetworkActive ( ) ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2013-03-25 22:38:24 -03:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan getnodeaddresses ( )
2018-05-02 09:19:40 -03:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " getnodeaddresses " ,
2021-04-03 15:30:29 -03:00
" \n Return known addresses, which can potentially be used to find new nodes in the network. \n " ,
2018-10-20 09:19:44 -03:00
{
2021-04-14 10:01:00 -04:00
{ " count " , RPCArg : : Type : : NUM , RPCArg : : Default { 1 } , " The maximum number of addresses to return. Specify 0 to return all known addresses. " } ,
2021-05-02 11:15:25 -04:00
{ " network " , RPCArg : : Type : : STR , RPCArg : : DefaultHint { " all networks " } , " Return only addresses of the specified network. Can be one of: " + Join ( GetNetworkNames ( ) , " , " ) + " . " } ,
2018-12-21 14:29:36 -03:00
} ,
RPCResult {
2020-01-09 14:00:57 -03:00
RPCResult : : Type : : ARR , " " , " " ,
{
{ RPCResult : : Type : : OBJ , " " , " " ,
{
2021-04-03 15:30:29 -03:00
{ RPCResult : : Type : : NUM_TIME , " time " , " The " + UNIX_EPOCH_TIME + " when the node was last seen " } ,
{ RPCResult : : Type : : NUM , " services " , " The services offered by the node " } ,
2020-01-09 14:00:57 -03:00
{ RPCResult : : Type : : STR , " address " , " The address of the node " } ,
2021-04-03 15:30:29 -03:00
{ RPCResult : : Type : : NUM , " port " , " The port number of the node " } ,
2021-04-03 15:21:28 -03:00
{ RPCResult : : Type : : STR , " network " , " The network ( " + Join ( GetNetworkNames ( ) , " , " ) + " ) the node connected through " } ,
2020-01-09 14:00:57 -03:00
} } ,
}
2018-12-21 14:29:36 -03:00
} ,
RPCExamples {
HelpExampleCli ( " getnodeaddresses " , " 8 " )
2021-05-02 11:15:25 -04:00
+ HelpExampleCli ( " getnodeaddresses " , " 4 \" i2p \" " )
+ HelpExampleCli ( " -named getnodeaddresses " , " network=onion count=12 " )
+ HelpExampleRpc ( " getnodeaddresses " , " 8 " )
+ HelpExampleRpc ( " getnodeaddresses " , " 4, \" i2p \" " )
2018-12-21 14:29:36 -03:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2021-04-17 14:59:17 -04:00
const CConnman & connman = EnsureConnman ( node ) ;
2018-05-02 09:19:40 -03:00
2021-04-03 15:22:55 -03:00
const int count { request . params [ 0 ] . isNull ( ) ? 1 : request . params [ 0 ] . get_int ( ) } ;
if ( count < 0 ) throw JSONRPCError ( RPC_INVALID_PARAMETER , " Address count out of range " ) ;
2021-05-02 11:15:25 -04:00
const std : : optional < Network > network { request . params [ 1 ] . isNull ( ) ? std : : nullopt : std : : optional < Network > { ParseNetwork ( request . params [ 1 ] . get_str ( ) ) } } ;
if ( network = = NET_UNROUTABLE ) {
throw JSONRPCError ( RPC_INVALID_PARAMETER , strprintf ( " Network not recognized: %s " , request . params [ 1 ] . get_str ( ) ) ) ;
}
2018-05-02 09:19:40 -03:00
// returns a shuffled list of CAddress
2021-05-02 11:15:25 -04:00
const std : : vector < CAddress > vAddr { connman . GetAddresses ( count , /* max_pct */ 0 , network ) } ;
2018-05-02 09:19:40 -03:00
UniValue ret ( UniValue : : VARR ) ;
2020-07-23 10:34:40 -04:00
for ( const CAddress & addr : vAddr ) {
2018-05-02 09:19:40 -03:00
UniValue obj ( UniValue : : VOBJ ) ;
obj . pushKV ( " time " , ( int ) addr . nTime ) ;
obj . pushKV ( " services " , ( uint64_t ) addr . nServices ) ;
obj . pushKV ( " address " , addr . ToStringIP ( ) ) ;
obj . pushKV ( " port " , addr . GetPort ( ) ) ;
2021-04-03 15:21:28 -03:00
obj . pushKV ( " network " , GetNetworkName ( addr . GetNetClass ( ) ) ) ;
2018-05-02 09:19:40 -03:00
ret . push_back ( obj ) ;
}
return ret ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2018-05-02 09:19:40 -03:00
}
2020-09-22 13:13:52 -03:00
static RPCHelpMan addpeeraddress ( )
2020-07-23 13:10:35 -04:00
{
2020-09-22 13:13:52 -03:00
return RPCHelpMan { " addpeeraddress " ,
2020-07-23 13:10:35 -04:00
" \n Add the address of a potential peer to the address manager. This RPC is for testing only. \n " ,
{
{ " address " , RPCArg : : Type : : STR , RPCArg : : Optional : : NO , " The IP address of the peer " } ,
{ " port " , RPCArg : : Type : : NUM , RPCArg : : Optional : : NO , " The port of the peer " } ,
2021-09-14 07:14:43 -03:00
{ " tried " , RPCArg : : Type : : BOOL , RPCArg : : Default { false } , " If true, attempt to add the peer to the tried addresses table " } ,
2020-07-23 13:10:35 -04:00
} ,
RPCResult {
RPCResult : : Type : : OBJ , " " , " " ,
{
{ RPCResult : : Type : : BOOL , " success " , " whether the peer address was successfully added to the address manager " } ,
} ,
} ,
RPCExamples {
2021-09-14 07:14:43 -03:00
HelpExampleCli ( " addpeeraddress " , " \" 1.2.3.4 \" 8333 true " )
+ HelpExampleRpc ( " addpeeraddress " , " \" 1.2.3.4 \" , 8333, true " )
2020-07-23 13:10:35 -04:00
} ,
2020-09-22 13:13:52 -03:00
[ & ] ( const RPCHelpMan & self , const JSONRPCRequest & request ) - > UniValue
{
2021-04-13 17:04:43 -04:00
NodeContext & node = EnsureAnyNodeContext ( request . context ) ;
2020-10-23 06:24:16 -03:00
if ( ! node . addrman ) {
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Address manager functionality missing or disabled " ) ;
2020-07-23 13:10:35 -04:00
}
2021-05-22 16:08:46 -04:00
const std : : string & addr_string { request . params [ 0 ] . get_str ( ) } ;
const uint16_t port { static_cast < uint16_t > ( request . params [ 1 ] . get_int ( ) ) } ;
2021-09-14 07:14:43 -03:00
const bool tried { request . params [ 2 ] . isTrue ( ) } ;
2020-07-23 13:10:35 -04:00
2021-05-22 16:08:46 -04:00
UniValue obj ( UniValue : : VOBJ ) ;
2020-07-23 13:10:35 -04:00
CNetAddr net_addr ;
2021-05-22 16:08:46 -04:00
bool success { false } ;
if ( LookupHost ( addr_string , net_addr , false ) ) {
2021-06-06 09:49:22 -04:00
CAddress address { { net_addr , port } , ServiceFlags { NODE_NETWORK | NODE_WITNESS } } ;
2021-05-22 16:08:46 -04:00
address . nTime = GetAdjustedTime ( ) ;
// The source address is set equal to the address. This is equivalent to the peer
// announcing itself.
2021-09-14 07:14:43 -03:00
if ( node . addrman - > Add ( { address } , address ) ) {
success = true ;
if ( tried ) {
// Attempt to move the address to the tried addresses table.
node . addrman - > Good ( address ) ;
}
}
2020-07-23 13:10:35 -04:00
}
2021-05-22 16:08:46 -04:00
obj . pushKV ( " success " , success ) ;
2020-07-23 13:10:35 -04:00
return obj ;
2020-09-22 13:13:52 -03:00
} ,
} ;
2020-07-23 13:10:35 -04:00
}
2020-04-05 12:21:33 -04:00
void RegisterNetRPCCommands ( CRPCTable & t )
{
2018-08-20 09:19:43 -03:00
// clang-format off
2016-03-29 14:43:02 -03:00
static const CRPCCommand commands [ ] =
2021-01-12 02:41:46 -03:00
{ // category actor
// --------------------- -----------------------
{ " network " , & getconnectioncount , } ,
{ " network " , & ping , } ,
{ " network " , & getpeerinfo , } ,
{ " network " , & addnode , } ,
{ " network " , & disconnectnode , } ,
{ " network " , & getaddednodeinfo , } ,
{ " network " , & getnettotals , } ,
{ " network " , & getnetworkinfo , } ,
{ " network " , & setban , } ,
{ " network " , & listbanned , } ,
{ " network " , & clearbanned , } ,
{ " network " , & setnetworkactive , } ,
{ " network " , & getnodeaddresses , } ,
{ " hidden " , & addconnection , } ,
{ " hidden " , & addpeeraddress , } ,
2016-03-29 14:43:02 -03:00
} ;
2018-08-20 09:19:43 -03:00
// clang-format on
2020-07-15 15:29:41 -04:00
for ( const auto & c : commands ) {
t . appendCommand ( c . name , & c ) ;
}
2016-03-29 14:43:02 -03:00
}