LCOV - code coverage report
Current view: top level - src/rpc - net.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 256 331 77.3 %
Date: 2025-02-23 09:33:43 Functions: 16 16 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2015 The Bitcoin developers
       2             : // Copyright (c) 2014-2015 The Dash developers
       3             : // Copyright (c) 2015-2022 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #include "rpc/server.h"
       8             : 
       9             : #include "clientversion.h"
      10             : #include "net.h"
      11             : #include "netbase.h"
      12             : #include "net_processing.h"
      13             : #include "optional.h"
      14             : #include "protocol.h"
      15             : #include "sync.h"
      16             : #include "timedata.h"
      17             : #include "guiinterface.h"
      18             : #include "util/system.h"
      19             : #include "version.h"
      20             : #include "validation.h"
      21             : #include "warnings.h"
      22             : 
      23             : #include <univalue.h>
      24             : 
      25             : 
      26           3 : UniValue getconnectioncount(const JSONRPCRequest& request)
      27             : {
      28           3 :     if (request.fHelp || request.params.size() != 0)
      29           0 :         throw std::runtime_error(
      30             :             "getconnectioncount\n"
      31             :             "\nReturns the number of connections to other nodes.\n"
      32             : 
      33             :             "\nbResult:\n"
      34             :             "n          (numeric) The connection count\n"
      35             : 
      36           0 :             "\nExamples:\n" +
      37           0 :             HelpExampleCli("getconnectioncount", "") + HelpExampleRpc("getconnectioncount", ""));
      38             : 
      39           3 :     if(!g_connman)
      40           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
      41             : 
      42           3 :     return (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL);
      43             : }
      44             : 
      45           1 : UniValue ping(const JSONRPCRequest& request)
      46             : {
      47           1 :     if (request.fHelp || request.params.size() != 0)
      48           0 :         throw std::runtime_error(
      49             :             "ping\n"
      50             :             "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
      51             :             "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
      52             :             "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
      53             : 
      54           0 :             "\nExamples:\n" +
      55           0 :             HelpExampleCli("ping", "") + HelpExampleRpc("ping", ""));
      56             : 
      57           1 :     if(!g_connman)
      58           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
      59             : 
      60             :     // Request that each node send a ping during next message processing pass
      61           1 :     g_connman->ForEachNode([](CNode* pnode) {
      62           2 :         pnode->fPingQueued = true;
      63           2 :     });
      64           1 :     return NullUniValue;
      65             : }
      66             : 
      67       16992 : UniValue getpeerinfo(const JSONRPCRequest& request)
      68             : {
      69       16992 :     if (request.fHelp || request.params.size() != 0)
      70           0 :         throw std::runtime_error(
      71             :             "getpeerinfo\n"
      72             :             "\nReturns data about each connected network node as a json array of objects.\n"
      73             : 
      74             :             "\nbResult:\n"
      75             :             "[\n"
      76             :             "  {\n"
      77             :             "    \"id\": n,                   (numeric) Peer index\n"
      78             :             "    \"addr\":\"host:port\",      (string) The ip address and port of the peer\n"
      79             :             "    \"addrlocal\":\"ip:port\",   (string) local address\n"
      80             :             "    \"mapped_as\":\"mapped_as\", (string) The AS in the BGP route to the peer used for diversifying\n"
      81             :                                                        "peer selection (only available if the asmap config flag is set)\n"
      82             :             "    \"services\":\"xxxxxxxxxxxxxxxx\",   (string) The services offered\n"
      83             :             "    \"lastsend\": ttt,           (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
      84             :             "    \"lastrecv\": ttt,           (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
      85             :             "    \"bytessent\": n,            (numeric) The total bytes sent\n"
      86             :             "    \"bytesrecv\": n,            (numeric) The total bytes received\n"
      87             :             "    \"conntime\": ttt,           (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
      88             :             "    \"timeoffset\": ttt,         (numeric) The time offset in seconds\n"
      89             :             "    \"pingtime\": n,             (numeric) ping time\n"
      90             :             "    \"pingwait\": n,             (numeric) ping wait\n"
      91             :             "    \"version\": v,              (numeric) The peer version, such as 7001\n"
      92             :             "    \"subver\": \"/Pivx Core:x.x.x.x/\",  (string) The string version\n"
      93             :             "    \"inbound\": true|false,     (boolean) Inbound (true) or Outbound (false)\n"
      94             :             "    \"addnode\": true|false,     (boolean) Whether connection was due to addnode and is using an addnode slot\n"
      95             :             "    \"masternode\": true|false,  (boolean) Whether the connection is only for masternode quorums related messages\n"
      96             :             "    \"startingheight\": n,       (numeric) The starting height (block) of the peer\n"
      97             :             "    \"banscore\": n,             (numeric) The ban score\n"
      98             :             "    \"synced_headers\": n,       (numeric) The last header we have in common with this peer\n"
      99             :             "    \"synced_blocks\": n,        (numeric) The last block we have in common with this peer\n"
     100             :             "    \"inflight\": [\n"
     101             :             "       n,                        (numeric) The heights of blocks we're currently asking from this peer\n"
     102             :             "       ...\n"
     103             :             "    ]\n"
     104             :             "    \"addr_processed\": n,       (numeric) The total number of addresses processed, excluding those dropped due to rate limiting\n"
     105             :             "    \"addr_rate_limited\": n,       (numeric) The total number of addresses dropped due to rate limiting\n"
     106             :             "    \"bytessent_per_msg\": {\n"
     107             :             "       \"addr\": n,             (numeric) The total bytes sent aggregated by message type\n"
     108             :             "       ...\n"
     109             :             "    }\n"
     110             :             "    \"bytesrecv_per_msg\": {\n"
     111             :             "       \"addr\": n,             (numeric) The total bytes received aggregated by message type\n"
     112             :             "       ...\n"
     113             :             "    }\n"
     114             :             "   \"masternode_iqr_conn\": true|false,          (boolean) Whether the connection is an intra-quorum relay connection or not\n"
     115             :             "   \"verif_mn_proreg_tx_hash\": \"hex\",         (string) The MN provider register tx hash (if the connection is verified)\n"
     116             :             "   \"verif_mn_operator_pubkey_hash\": \"hex\",   (string) The MN operator pubkey hash (if the connection is verified)\n"
     117             :             "  }\n"
     118             :             "  ,...\n"
     119             :             "]\n"
     120             : 
     121           0 :             "\nExamples:\n" +
     122           0 :             HelpExampleCli("getpeerinfo", "") + HelpExampleRpc("getpeerinfo", ""));
     123             : 
     124       16992 :     if(!g_connman)
     125           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     126             : 
     127       16992 :     std::vector<CNodeStats> vstats;
     128       16992 :     g_connman->GetNodeStats(vstats);
     129             : 
     130       16992 :     UniValue ret(UniValue::VARR);
     131             : 
     132       78365 :     for (const CNodeStats& stats : vstats) {
     133       61373 :         UniValue obj(UniValue::VOBJ);
     134      122746 :         CNodeStateStats statestats;
     135       61373 :         bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
     136       61373 :         obj.pushKV("id", stats.nodeid);
     137      122746 :         obj.pushKV("addr", stats.addrName);
     138       61373 :         if (!(stats.addrLocal.empty()))
     139         172 :             obj.pushKV("addrlocal", stats.addrLocal);
     140       61373 :         if (stats.m_mapped_as != 0) {
     141           0 :             obj.pushKV("mapped_as", uint64_t(stats.m_mapped_as));
     142             :         }
     143      122746 :         obj.pushKV("services", strprintf("%016x", stats.nServices));
     144       61373 :         obj.pushKV("lastsend", stats.nLastSend);
     145       61373 :         obj.pushKV("lastrecv", stats.nLastRecv);
     146       61373 :         obj.pushKV("bytessent", stats.nSendBytes);
     147       61373 :         obj.pushKV("bytesrecv", stats.nRecvBytes);
     148       61373 :         obj.pushKV("conntime", stats.nTimeConnected);
     149       61373 :         obj.pushKV("timeoffset", stats.nTimeOffset);
     150       61373 :         obj.pushKV("pingtime", stats.dPingTime);
     151       61373 :         if (stats.dPingWait > 0.0)
     152        1620 :             obj.pushKV("pingwait", stats.dPingWait);
     153       61373 :         obj.pushKV("version", stats.nVersion);
     154             :         // Use the sanitized form of subver here, to avoid tricksy remote peers from
     155             :         // corrupting or modifying the JSON output by putting special characters in
     156             :         // their ver message.
     157       61373 :         obj.pushKV("subver", stats.cleanSubVer);
     158       61373 :         obj.pushKV("inbound", stats.fInbound);
     159       61373 :         obj.pushKV("addnode", stats.fAddnode);
     160       61373 :         obj.pushKV("masternode", stats.m_masternode_connection);
     161       61373 :         obj.pushKV("startingheight", stats.nStartingHeight);
     162       61373 :         if (fStateStats) {
     163       61373 :             obj.pushKV("banscore", statestats.nMisbehavior);
     164       61373 :             obj.pushKV("synced_headers", statestats.nSyncHeight);
     165       61373 :             obj.pushKV("synced_blocks", statestats.nCommonHeight);
     166       61373 :             UniValue heights(UniValue::VARR);
     167       61373 :             for (int height : statestats.vHeightInFlight) {
     168           0 :                 heights.push_back(height);
     169             :             }
     170       61373 :             obj.pushKV("inflight", heights);
     171       61373 :             obj.pushKV("addr_processed", statestats.m_addr_processed);
     172      122746 :             obj.pushKV("addr_rate_limited", statestats.m_addr_rate_limited);
     173             :         }
     174       61373 :         obj.pushKV("whitelisted", stats.fWhitelisted);
     175             : 
     176      122746 :         UniValue sendPerMsgCmd(UniValue::VOBJ);
     177      920689 :         for (const mapMsgCmdSize::value_type &i : stats.mapSendBytesPerMsgCmd) {
     178      859316 :             if (i.second > 0)
     179      859316 :                 sendPerMsgCmd.pushKV(i.first, i.second);
     180             :         }
     181       61373 :         obj.pushKV("bytessent_per_msg", sendPerMsgCmd);
     182             : 
     183      122746 :         UniValue recvPerMsgCmd(UniValue::VOBJ);
     184     3621010 :         for (const mapMsgCmdSize::value_type &i : stats.mapRecvBytesPerMsgCmd) {
     185     3559630 :             if (i.second > 0)
     186      855932 :                 recvPerMsgCmd.pushKV(i.first, i.second);
     187             :         }
     188       61373 :         obj.pushKV("bytesrecv_per_msg", recvPerMsgCmd);
     189             : 
     190             :         // DMN data
     191       61373 :         if (stats.m_masternode_connection) {
     192        2600 :             obj.pushKV("masternode_iqr_conn", stats.m_masternode_iqr_connection);
     193        5200 :             obj.pushKV("verif_mn_proreg_tx_hash", stats.verifiedProRegTxHash.GetHex());
     194        7800 :             obj.pushKV("verif_mn_operator_pubkey_hash", stats.verifiedPubKeyHash.GetHex());
     195             :         }
     196             : 
     197       61373 :         ret.push_back(obj);
     198             :     }
     199             : 
     200       16992 :     return ret;
     201             : }
     202             : 
     203         604 : UniValue addnode(const JSONRPCRequest& request)
     204             : {
     205        1208 :     std::string strCommand;
     206         604 :     if (request.params.size() == 2)
     207         604 :         strCommand = request.params[1].get_str();
     208         604 :     if (request.fHelp || request.params.size() != 2 ||
     209         605 :         (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
     210           0 :         throw std::runtime_error(
     211             :             "addnode \"node\" \"add|remove|onetry\"\n"
     212             :             "\nAttempts add or remove a node from the addnode list.\n"
     213             :             "Or try a connection to a node once.\n"
     214             : 
     215             :             "\nArguments:\n"
     216             :             "1. \"node\"     (string, required) The node (see getpeerinfo for nodes)\n"
     217             :             "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"
     218             : 
     219           0 :             "\nExamples:\n" +
     220           0 :             HelpExampleCli("addnode", "\"192.168.0.6:51472\" \"onetry\"") + HelpExampleRpc("addnode", "\"192.168.0.6:51472\", \"onetry\""));
     221             : 
     222         604 :     if(!g_connman)
     223           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     224             : 
     225        1208 :     std::string strNode = request.params[0].get_str();
     226             : 
     227         604 :     if (strCommand == "onetry") {
     228        1206 :         CAddress addr;
     229         603 :         g_connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str());
     230         603 :         return NullUniValue;
     231             :     }
     232             : 
     233           1 :     if (strCommand == "add") {
     234           1 :         if(!g_connman->AddNode(strNode))
     235           0 :             throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
     236           0 :     } else if (strCommand == "remove") {
     237           0 :         if(!g_connman->RemoveAddedNode(strNode))
     238           0 :             throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
     239             :     }
     240             : 
     241           1 :     return NullUniValue;
     242             : }
     243             : 
     244          25 : UniValue disconnectnode(const JSONRPCRequest& request)
     245             : {
     246          25 :     if (request.fHelp || request.params.size() != 1)
     247           0 :         throw std::runtime_error(
     248             :             "disconnectnode \"node\" \n"
     249             :             "\nImmediately disconnects from the specified node.\n"
     250             : 
     251             :             "\nArguments:\n"
     252             :             "1. \"node\"     (string, required) The node (see getpeerinfo for nodes)\n"
     253             : 
     254             :             "\nExamples:\n"
     255           0 :             + HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"")
     256           0 :             + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
     257           0 :         );
     258             : 
     259          25 :     if(!g_connman)
     260           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     261             : 
     262          25 :     bool ret = g_connman->DisconnectNode(request.params[0].get_str());
     263          25 :     if (!ret)
     264           2 :         throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
     265             : 
     266          24 :     return NullUniValue;
     267             : }
     268             : 
     269           3 : UniValue getaddednodeinfo(const JSONRPCRequest& request)
     270             : {
     271           3 :     if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
     272           0 :         throw std::runtime_error(
     273             :             "getaddednodeinfo dummy ( \"node\" )\n"
     274             :             "\nReturns information about the given added node, or all added nodes\n"
     275             :             "(note that onetry addnodes are not listed here)\n"
     276             : 
     277             :             "\nArguments:\n"
     278             :             "1. dummy      (boolean, required) Kept for historical purposes but ignored\n"
     279             :             "2. \"node\"   (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
     280             : 
     281             :             "\nResult:\n"
     282             :             "[\n"
     283             :             "  {\n"
     284             :             "    \"addednode\" : \"192.168.0.201\",   (string) The node ip address or name (as provided to addnode)\n"
     285             :             "    \"connected\" : true|false,          (boolean) If connected\n"
     286             :             "    \"addresses\" : [                    (list of objects) Only when connected = true\n"
     287             :             "       {\n"
     288             :             "         \"address\" : \"192.168.0.201:51472\",  (string) The pivx server IP and port we're connected to\n"
     289             :             "         \"connected\" : \"outbound\"           (string) connection, inbound or outbound\n"
     290             :             "       }\n"
     291             :             "     ]\n"
     292             :             "  }\n"
     293             :             "  ,...\n"
     294             :             "]\n"
     295             : 
     296           0 :             "\nExamples:\n" +
     297           0 :             HelpExampleCli("getaddednodeinfo", "true") + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"") + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\""));
     298             : 
     299           3 :     if(!g_connman)
     300           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     301             : 
     302           4 :     std::vector<AddedNodeInfo> vInfo = g_connman->GetAddedNodeInfo();
     303             : 
     304           3 :     if (request.params.size() == 2) {
     305           2 :         bool found = false;
     306           3 :         for (const AddedNodeInfo& info : vInfo) {
     307           2 :             if (info.strAddedNode == request.params[1].get_str()) {
     308           1 :                 vInfo.assign(1, info);
     309             :                 found = true;
     310             :                 break;
     311             :             }
     312             :         }
     313           1 :         if (!found) {
     314           2 :             throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
     315             :         }
     316             :     }
     317             : 
     318           2 :     UniValue ret(UniValue::VARR);
     319             : 
     320           3 :     for (const AddedNodeInfo& info : vInfo) {
     321           2 :         UniValue obj(UniValue::VOBJ);
     322           1 :         obj.pushKV("addednode", info.strAddedNode);
     323           1 :         obj.pushKV("connected", info.fConnected);
     324           2 :         UniValue addresses(UniValue::VARR);
     325           1 :         if (info.fConnected) {
     326           0 :             UniValue address(UniValue::VOBJ);
     327           0 :             address.pushKV("address", info.resolvedAddress.ToString());
     328           0 :             address.pushKV("connected", info.fInbound ? "inbound" : "outbound");
     329           0 :             addresses.push_back(address);
     330             :         }
     331           1 :         obj.pushKV("addresses", addresses);
     332           1 :         ret.push_back(obj);
     333             :     }
     334             : 
     335           2 :     return ret;
     336             : }
     337             : 
     338           5 : UniValue getnettotals(const JSONRPCRequest& request)
     339             : {
     340           5 :     if (request.fHelp || request.params.size() > 0)
     341           0 :         throw std::runtime_error(
     342             :             "getnettotals\n"
     343             :             "\nReturns information about network traffic, including bytes in, bytes out,\n"
     344             :             "and current time.\n"
     345             : 
     346             :             "\nResult:\n"
     347             :             "{\n"
     348             :             "  \"totalbytesrecv\": n,   (numeric) Total bytes received\n"
     349             :             "  \"totalbytessent\": n,   (numeric) Total bytes sent\n"
     350             :             "  \"timemillis\": t        (numeric) Total cpu time\n"
     351             :             "}\n"
     352             : 
     353           0 :             "\nExamples:\n" +
     354           0 :             HelpExampleCli("getnettotals", "") + HelpExampleRpc("getnettotals", ""));
     355             : 
     356           5 :     if(!g_connman)
     357           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     358             : 
     359           5 :     UniValue obj(UniValue::VOBJ);
     360           5 :     obj.pushKV("totalbytesrecv", g_connman->GetTotalBytesRecv());
     361           5 :     obj.pushKV("totalbytessent", g_connman->GetTotalBytesSent());
     362           5 :     obj.pushKV("timemillis", GetTimeMillis());
     363           5 :     return obj;
     364             : }
     365             : 
     366        1222 : static UniValue GetNetworksInfo()
     367             : {
     368        1222 :     UniValue networks(UniValue::VARR);
     369        9776 :     for (int n = 0; n < NET_MAX; ++n) {
     370        8554 :         enum Network network = static_cast<enum Network>(n);
     371        8554 :         if (network == NET_UNROUTABLE || network == NET_I2P || network == NET_CJDNS || network == NET_INTERNAL) continue;
     372        7332 :         proxyType proxy;
     373        7332 :         UniValue obj(UniValue::VOBJ);
     374        3666 :         GetProxy(network, proxy);
     375        7332 :         obj.pushKV("name", GetNetworkName(network));
     376        3666 :         obj.pushKV("limited", !IsReachable(network));
     377        3666 :         obj.pushKV("reachable", IsReachable(network));
     378       10968 :         obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string());
     379        3666 :         obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials);
     380        3666 :         networks.push_back(obj);
     381             :     }
     382        1222 :     return networks;
     383             : }
     384             : 
     385        1222 : UniValue getnetworkinfo(const JSONRPCRequest& request)
     386             : {
     387        1222 :     if (request.fHelp || request.params.size() != 0)
     388           0 :         throw std::runtime_error(
     389             :             "getnetworkinfo\n"
     390             :             "\nReturns an object containing various state info regarding P2P networking.\n"
     391             : 
     392             :             "\nResult:\n"
     393             :             "{\n"
     394             :             "  \"version\": xxxxx,                      (numeric) the server version\n"
     395             :             "  \"subversion\": \"/Pivx Core:x.x.x.x/\",     (string) the server subversion string\n"
     396             :             "  \"protocolversion\": xxxxx,              (numeric) the protocol version\n"
     397             :             "  \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
     398             :             "  \"timeoffset\": xxxxx,                   (numeric) the time offset\n"
     399             :             "  \"connections\": xxxxx,                  (numeric) the number of connections\n"
     400             :             "  \"networkactive\": true|false,           (boolean) the network activity status\n"
     401             :             "  \"networks\": [                          (array) information per network\n"
     402             :             "  {\n"
     403             :             "    \"name\": \"xxx\",                     (string) network (ipv4, ipv6 or onion)\n"
     404             :             "    \"limited\": true|false,               (boolean) is the network limited using -onlynet?\n"
     405             :             "    \"reachable\": true|false,             (boolean) is the network reachable?\n"
     406             :             "    \"proxy\": \"host:port\"               (string) the proxy that is used for this network, or empty if none\n"
     407             :             "  }\n"
     408             :             "  ,...\n"
     409             :             "  ],\n"
     410           0 :             "  \"relayfee\": x.xxxxxxxx,                (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n"
     411           0 :             "  \"incrementalfee\": x.xxxxxxxx,          (numeric) minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB\n"
     412             :             "  \"localaddresses\": [                    (array) list of local addresses\n"
     413             :             "  {\n"
     414             :             "    \"address\": \"xxxx\",                 (string) network address\n"
     415             :             "    \"port\": xxx,                         (numeric) network port\n"
     416             :             "    \"score\": xxx                         (numeric) relative score\n"
     417             :             "  }\n"
     418             :             "  ,...\n"
     419             :             "  ]\n"
     420             :             "  \"warnings\": \"...\"                    (string) any network and blockchain warnings\n"
     421             :             "}\n"
     422             : 
     423           0 :             "\nExamples:\n" +
     424           0 :             HelpExampleCli("getnetworkinfo", "") + HelpExampleRpc("getnetworkinfo", ""));
     425             : 
     426        1222 :     LOCK(cs_main);
     427        1222 :     UniValue obj(UniValue::VOBJ);
     428        1222 :     obj.pushKV("version", CLIENT_VERSION);
     429        1222 :     obj.pushKV("subversion",    strSubVersion);
     430        1222 :     obj.pushKV("protocolversion", PROTOCOL_VERSION);
     431        1222 :     if (g_connman)
     432        3666 :         obj.pushKV("localservices", strprintf("%016x", g_connman->GetLocalServices()));
     433        1222 :     obj.pushKV("timeoffset", GetTimeOffset());
     434        1222 :     if (g_connman) {
     435        1222 :         obj.pushKV("networkactive", g_connman->GetNetworkActive());
     436        2444 :         obj.pushKV("connections",   (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL));
     437             :     }
     438        2444 :     obj.pushKV("networks", GetNetworksInfo());
     439        2444 :     obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
     440        2444 :     UniValue localAddresses(UniValue::VARR);
     441        1222 :     {
     442        1222 :         LOCK(cs_mapLocalHost);
     443        1222 :         for (const std::pair<const CNetAddr, LocalServiceInfo> &item : mapLocalHost) {
     444           0 :             UniValue rec(UniValue::VOBJ);
     445           0 :             rec.pushKV("address", item.first.ToString());
     446           0 :             rec.pushKV("port", item.second.nPort);
     447           0 :             rec.pushKV("score", item.second.nScore);
     448           0 :             localAddresses.push_back(rec);
     449             :         }
     450             :     }
     451        1222 :     obj.pushKV("localaddresses", localAddresses);
     452        3666 :     obj.pushKV("warnings", GetWarnings("statusbar"));
     453        2444 :     return obj;
     454             : }
     455             : 
     456          23 : UniValue setban(const JSONRPCRequest& request)
     457             : {
     458          23 :     std::string strCommand;
     459          23 :     if (request.params.size() >= 2)
     460          22 :         strCommand = request.params[1].get_str();
     461          23 :     if (request.fHelp || request.params.size() < 2 ||
     462          26 :         (strCommand != "add" && strCommand != "remove"))
     463           1 :         throw std::runtime_error(
     464             :             "setban \"subnet\" \"add|remove\" ( bantime absolute )\n"
     465             :             "\nAttempts add or remove a IP/Subnet from the banned list.\n"
     466             : 
     467             :             "\nArguments:\n"
     468             :             "1. \"subnet\"       (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
     469             :             "2. \"command\"      (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
     470             :             "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"
     471             :             "4. \"absolute\"     (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
     472             : 
     473             :             "\nExamples:\n"
     474           3 :             + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
     475           5 :             + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
     476           5 :             + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400"));
     477             : 
     478          22 :     if (!g_connman)
     479           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     480             : 
     481          44 :     CSubNet subNet;
     482          44 :     CNetAddr netAddr;
     483          22 :     bool isSubnet = false;
     484             : 
     485          22 :     if (request.params[0].get_str().find('/') != std::string::npos)
     486          12 :         isSubnet = true;
     487             : 
     488          22 :     if (!isSubnet) {
     489          20 :         CNetAddr resolved;
     490          10 :         LookupHost(request.params[0].get_str(), resolved, false);
     491          10 :         netAddr = resolved;
     492             :     } else
     493          12 :         LookupSubNet(request.params[0].get_str(), subNet);
     494             : 
     495          22 :     if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
     496           4 :         throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
     497             : 
     498          20 :     if (strCommand == "add")
     499             :     {
     500          38 :         if (isSubnet ? g_connman->IsBanned(subNet) : g_connman->IsBanned(netAddr))
     501           6 :             throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
     502             : 
     503          13 :         int64_t banTime = 0; //use standard bantime if not specified
     504          13 :         if (request.params.size() >= 3 && !request.params[2].isNull())
     505           4 :             banTime = request.params[2].get_int64();
     506             : 
     507          13 :         bool absolute = false;
     508          13 :         if (request.params.size() == 4)
     509           1 :             absolute = request.params[3].get_bool();
     510             : 
     511          13 :         isSubnet ? g_connman->Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : g_connman->Ban(netAddr, BanReasonManuallyAdded, banTime, absolute);
     512             :     }
     513           4 :     else if(strCommand == "remove")
     514             :     {
     515           4 :         if (!( isSubnet ? g_connman->Unban(subNet) : g_connman->Unban(netAddr) ))
     516           2 :             throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed");
     517             :     }
     518          32 :     return NullUniValue;
     519             : }
     520             : 
     521          19 : UniValue listbanned(const JSONRPCRequest& request)
     522             : {
     523          19 :     if (request.fHelp || request.params.size() != 0)
     524           0 :         throw std::runtime_error(
     525             :             "listbanned\n"
     526             :             "\nList all banned IPs/Subnets.\n"
     527             : 
     528             :             "\nResult:\n"
     529             :             "[\n"
     530             :             "  {\n"
     531             :             "    \"address\": \"xxx\",          (string) Network address of banned client.\n"
     532             :             "    \"banned_until\": nnn,         (numeric) Timestamp when the ban is lifted.\n"
     533             :             "    \"ban_created\": nnn,          (numeric) Timestamp when the ban was created.\n"
     534             :             "    \"ban_reason\": \"xxx\"        (string) Reason for banning.\n"
     535             :             "  }\n"
     536             :             "  ,...\n"
     537             :             "]\n"
     538             : 
     539             :             "\nExamples:\n"
     540           0 :             + HelpExampleCli("listbanned", "")
     541           0 :             + HelpExampleRpc("listbanned", ""));
     542             : 
     543          19 :     if (!g_connman)
     544           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     545             : 
     546          19 :     banmap_t banMap;
     547          19 :     g_connman->GetBanned(banMap);
     548             : 
     549          19 :     UniValue bannedAddresses(UniValue::VARR);
     550          39 :     for (const auto& entry : banMap)
     551             :     {
     552          20 :         const CBanEntry& banEntry = entry.second;
     553          40 :         UniValue rec(UniValue::VOBJ);
     554          40 :         rec.pushKV("address", entry.first.ToString());
     555          20 :         rec.pushKV("banned_until", banEntry.nBanUntil);
     556          20 :         rec.pushKV("ban_created", banEntry.nCreateTime);
     557          40 :         rec.pushKV("ban_reason", banEntry.banReasonToString());
     558             : 
     559          20 :         bannedAddresses.push_back(rec);
     560             :     }
     561             : 
     562          19 :     return bannedAddresses;
     563             : }
     564             : 
     565           8 : UniValue clearbanned(const JSONRPCRequest& request)
     566             : {
     567           8 :     if (request.fHelp || request.params.size() != 0)
     568           0 :         throw std::runtime_error(
     569             :             "clearbanned\n"
     570             :             "\nClear all banned IPs.\n"
     571             : 
     572             :             "\nExamples:\n"
     573           0 :             + HelpExampleCli("clearbanned", "")
     574           0 :             + HelpExampleRpc("clearbanned", ""));
     575             : 
     576           8 :     if (!g_connman)
     577           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     578             : 
     579           8 :     g_connman->ClearBanned();
     580             : 
     581           8 :     return NullUniValue;
     582             : }
     583             : 
     584           8 : static UniValue getnodeaddresses(const JSONRPCRequest& request)
     585             : {
     586           8 :     if (request.fHelp || request.params.size() > 2) {
     587           0 :         throw std::runtime_error(
     588             :             "getnodeaddresses ( count \"network\" )\n"
     589             :             "\nReturn known addresses which can potentially be used to find new nodes in the network\n"
     590             : 
     591             :             "\nArguments:\n"
     592             :             "1. count        (numeric, optional) The maximum number of addresses to return. Specify 0 to return all known addresses.\n"
     593             :             "2. \"network\"  (string, optional) Return only addresses of the specified network. Can be one of: ipv4, ipv6, onion."
     594             : 
     595             :             "\nResult:\n"
     596             :             "[\n"
     597             :             "  {\n"
     598             :             "    \"time\": ttt,                (numeric) Timestamp in seconds since epoch (Jan 1 1970 GMT) when the node was last seen\n"
     599             :             "    \"services\": n,              (numeric) The services offered by the node\n"
     600             :             "    \"address\": \"host\",        (string) The address of the node\n"
     601             :             "    \"port\": n,                  (numeric) The port number of the node\n"
     602             :             "    \"network\": \"xxxx\"         (string) The network (ipv4, ipv6, onion) the node connected through\n"
     603             :             "  }\n"
     604             :             "  ,...\n"
     605             :             "]\n"
     606             : 
     607             :             "\nExamples:\n"
     608           0 :             + HelpExampleCli("getnodeaddresses", "8")
     609           0 :             + HelpExampleCli("getnodeaddresses", "4 \"ipv4\"")
     610           0 :             + HelpExampleRpc("getnodeaddresses", "8")
     611           0 :             + HelpExampleRpc("getnodeaddresses", "4 \"ipv4\"")
     612           0 :         );
     613             :     }
     614           8 :     if (!g_connman) {
     615           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     616             :     }
     617             : 
     618           8 :     const int count{request.params[0].isNull() ? 1 : request.params[0].get_int()};
     619           8 :     if (count < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
     620             : 
     621          12 :     const Optional<Network> network{request.params[1].isNull() ? nullopt : Optional<Network>{ParseNetwork(request.params[1].get_str())}};
     622           7 :     if (network == NET_UNROUTABLE) {
     623           2 :         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Network not recognized: %s", request.params[1].get_str()));
     624             :     }
     625             : 
     626             :     // returns a shuffled list of CAddress
     627           6 :     const std::vector<CAddress> vAddr{g_connman->GetAddresses(count, /* max_pct */ 0, network)};
     628           6 :     UniValue ret(UniValue::VARR);
     629             : 
     630        8858 :     for (const CAddress& addr : vAddr) {
     631       17704 :         UniValue obj(UniValue::VOBJ);
     632        8852 :         obj.pushKV("time", (int)addr.nTime);
     633        8852 :         obj.pushKV("services", (uint64_t)addr.nServices);
     634       17704 :         obj.pushKV("address", addr.ToStringIP());
     635        8852 :         obj.pushKV("port", addr.GetPort());
     636       17704 :         obj.pushKV("network", GetNetworkName(addr.GetNetClass()));
     637        8852 :         ret.push_back(obj);
     638             :     }
     639           6 :     return ret;
     640             : }
     641             : 
     642       10001 : static UniValue addpeeraddress(const JSONRPCRequest& request)
     643             : {
     644       10001 :     if (request.fHelp || request.params.size() != 2) {
     645           0 :         throw std::runtime_error(
     646             :             "addpeeraddress \"address\" port\n"
     647             :             "\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n"
     648             : 
     649             :             "\nArguments\n"
     650             :             "1. \"address\"     (string, required) The IP address of the peer\n"
     651             :             "2. port            (numeric, required) The port of the peer\n"
     652             : 
     653             :             "\nResult:\n"
     654             :             "{\n"
     655             :             "  \"success\": true|false      (boolean) Whether the peer address was successfully added to the address manager\n"
     656             :             "}\n"
     657             : 
     658             :             "\nExamples:\n"
     659           0 :             + HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 51472")
     660           0 :             + HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 51472"));
     661             :     }
     662       10001 :     if (!g_connman) {
     663           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     664             :     }
     665             : 
     666       10001 :     UniValue obj(UniValue::VOBJ);
     667             : 
     668       20002 :     std::string addr_string = request.params[0].get_str();
     669       10001 :     uint16_t port = request.params[1].get_int();
     670             : 
     671       20002 :     CNetAddr net_addr;
     672       10001 :     if (!LookupHost(addr_string, net_addr, false)) {
     673           0 :         obj.pushKV("success", false);
     674           0 :         return obj;
     675             :     }
     676       30003 :     CAddress address = CAddress({net_addr, port}, ServiceFlags(NODE_NETWORK));
     677       10001 :     address.nTime = GetAdjustedTime();
     678             :     // The source address is set equal to the address. This is equivalent to the peer
     679             :     // announcing itself.
     680       20002 :     if (!g_connman->AddNewAddresses({address}, address)) {
     681         512 :         obj.pushKV("success", false);
     682         512 :         return obj;
     683             :     }
     684             : 
     685        9489 :     obj.pushKV("success", true);
     686        9489 :     return obj;
     687             : }
     688             : 
     689          19 : UniValue setnetworkactive(const JSONRPCRequest& request)
     690             : {
     691          19 :     if (request.fHelp || request.params.size() != 1) {
     692           0 :         throw std::runtime_error(
     693             :                 "setnetworkactive \"true|false\"\n"
     694             :                 "Disable/enable all p2p network activity.\n"
     695             : 
     696             :                 "\nResult:\n"
     697             :                 "status    (boolean) The final network activity status\n"
     698           0 :                 "\nExamples:\n" +
     699           0 :                 HelpExampleCli("setnetworkactive", "true") + HelpExampleRpc("setnetworkactive", "true"));
     700             :     }
     701          19 :     if (!g_connman) {
     702           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     703             :     }
     704          19 :     g_connman->SetNetworkActive(request.params[0].get_bool());
     705          19 :     return g_connman->GetNetworkActive();
     706             : }
     707             : 
     708             : // clang-format off
     709             : static const CRPCCommand commands[] =
     710             : { //  category              name                      actor (function)         okSafe argNames
     711             :   //  --------------------- ------------------------  -----------------------  ------ --------
     712             :     { "network",            "addnode",                &addnode,                true,  {"node","command"} },
     713             :     { "network",            "clearbanned",            &clearbanned,            true,  {} },
     714             :     { "network",            "disconnectnode",         &disconnectnode,         true,  {"node"} },
     715             :     { "network",            "getaddednodeinfo",       &getaddednodeinfo,       true,  {"dummy","node"} },
     716             :     { "network",            "getconnectioncount",     &getconnectioncount,     true,  {} },
     717             :     { "network",            "getnettotals",           &getnettotals,           true,  {} },
     718             :     { "network",            "getnetworkinfo",         &getnetworkinfo,         true,  {} },
     719             :     { "network",            "getnodeaddresses",       &getnodeaddresses,       true,  {"count"} },
     720             :     { "network",            "getpeerinfo",            &getpeerinfo,            true,  {} },
     721             :     { "network",            "listbanned",             &listbanned,             true,  {} },
     722             :     { "network",            "ping",                   &ping,                   true,  {} },
     723             :     { "network",            "setban",                 &setban,                 true,  {"subnet", "command", "bantime", "absolute"} },
     724             :     { "network",            "setnetworkactive",       &setnetworkactive,       true,  {"active"} },
     725             : 
     726             :     /** Not shown in help */
     727             :     { "hidden",             "addpeeraddress",         &addpeeraddress,         true,  {"address", "port"} },
     728             : };
     729             : // clang-format on
     730             : 
     731         494 : void RegisterNetRPCCommands(CRPCTable &tableRPC)
     732             : {
     733        7410 :     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
     734        6916 :         tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
     735         494 : }

Generated by: LCOV version 1.14