aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc/net.cpp')
-rw-r--r--src/rpc/net.cpp294
1 files changed, 179 insertions, 115 deletions
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 89ddfb35cb..2bfcaeafc9 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -5,6 +5,7 @@
#include <rpc/server.h>
#include <banman.h>
+#include <chainparams.h>
#include <clientversion.h>
#include <core_io.h>
#include <net.h>
@@ -38,6 +39,22 @@ const std::vector<std::string> CONNECTION_TYPE_DOC{
"feeler (short-lived automatic connection for testing addresses)"
};
+CConnman& EnsureConnman(const NodeContext& node)
+{
+ if (!node.connman) {
+ throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ }
+ return *node.connman;
+}
+
+PeerManager& EnsurePeerman(const NodeContext& node)
+{
+ if (!node.peerman) {
+ throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ }
+ return *node.peerman;
+}
+
static RPCHelpMan getconnectioncount()
{
return RPCHelpMan{"getconnectioncount",
@@ -52,11 +69,10 @@ static RPCHelpMan getconnectioncount()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ const CConnman& connman = EnsureConnman(node);
- return (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL);
+ return (int)connman.GetNodeCount(ConnectionDirection::Both);
},
};
}
@@ -75,14 +91,11 @@ static RPCHelpMan ping()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ PeerManager& peerman = EnsurePeerman(node);
// Request that each node send a ping during next message processing pass
- node.connman->ForEachNode([](CNode* pnode) {
- pnode->fPingQueued = true;
- });
+ peerman.SendPings();
return NullUniValue;
},
};
@@ -103,7 +116,7 @@ static RPCHelpMan getpeerinfo()
{RPCResult::Type::STR, "addr", "(host:port) The IP address and port of the peer"},
{RPCResult::Type::STR, "addrbind", "(ip:port) Bind address of the connection to the peer"},
{RPCResult::Type::STR, "addrlocal", "(ip:port) Local address as reported by the peer"},
- {RPCResult::Type::STR, "network", "Network (ipv4, ipv6, or onion) the peer connected through"},
+ {RPCResult::Type::STR, "network", "Network (" + Join(GetNetworkNames(/* append_unroutable */ true), ", ") + ")"},
{RPCResult::Type::NUM, "mapped_as", "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"},
@@ -128,9 +141,6 @@ static RPCHelpMan getpeerinfo()
{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::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."},
{RPCResult::Type::NUM, "startingheight", "The starting height (block) of the peer"},
{RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
{RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
@@ -156,6 +166,9 @@ static RPCHelpMan getpeerinfo()
"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."},
}},
}},
},
@@ -165,20 +178,19 @@ static RPCHelpMan getpeerinfo()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman || !node.peerman) {
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
- }
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ const CConnman& connman = EnsureConnman(node);
+ const PeerManager& peerman = EnsurePeerman(node);
std::vector<CNodeStats> vstats;
- node.connman->GetNodeStats(vstats);
+ connman.GetNodeStats(vstats);
UniValue ret(UniValue::VARR);
for (const CNodeStats& stats : vstats) {
UniValue obj(UniValue::VOBJ);
CNodeStateStats statestats;
- bool fStateStats = node.peerman->GetNodeStateStats(stats.nodeid, statestats);
+ bool fStateStats = peerman.GetNodeStateStats(stats.nodeid, statestats);
obj.pushKV("id", stats.nodeid);
obj.pushKV("addr", stats.addrName);
if (stats.addrBind.IsValid()) {
@@ -202,14 +214,14 @@ static RPCHelpMan getpeerinfo()
obj.pushKV("bytesrecv", stats.nRecvBytes);
obj.pushKV("conntime", stats.nTimeConnected);
obj.pushKV("timeoffset", stats.nTimeOffset);
- if (stats.m_ping_usec > 0) {
- obj.pushKV("pingtime", ((double)stats.m_ping_usec) / 1e6);
+ if (stats.m_last_ping_time > 0us) {
+ obj.pushKV("pingtime", CountSecondsDouble(stats.m_last_ping_time));
}
- if (stats.m_min_ping_usec < std::numeric_limits<int64_t>::max()) {
- obj.pushKV("minping", ((double)stats.m_min_ping_usec) / 1e6);
+ if (stats.m_min_ping_time < std::chrono::microseconds::max()) {
+ obj.pushKV("minping", CountSecondsDouble(stats.m_min_ping_time));
}
- if (stats.m_ping_wait_usec > 0) {
- obj.pushKV("pingwait", ((double)stats.m_ping_wait_usec) / 1e6);
+ if (fStateStats && statestats.m_ping_wait > 0s) {
+ obj.pushKV("pingwait", CountSecondsDouble(statestats.m_ping_wait));
}
obj.pushKV("version", stats.nVersion);
// Use the sanitized form of subver here, to avoid tricksy remote peers from
@@ -249,7 +261,7 @@ static RPCHelpMan getpeerinfo()
recvPerMsgCmd.pushKV(i.first, i.second);
}
obj.pushKV("bytesrecv_per_msg", recvPerMsgCmd);
- obj.pushKV("connection_type", stats.m_conn_type_string);
+ obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
ret.push_back(obj);
}
@@ -285,28 +297,29 @@ static RPCHelpMan addnode()
self.ToString());
}
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ CConnman& connman = EnsureConnman(node);
std::string strNode = request.params[0].get_str();
if (strCommand == "onetry")
{
CAddress addr;
- node.connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), ConnectionType::MANUAL);
+ connman.OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), ConnectionType::MANUAL);
return NullUniValue;
}
if (strCommand == "add")
{
- if(!node.connman->AddNode(strNode))
+ if (!connman.AddNode(strNode)) {
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
+ }
}
else if(strCommand == "remove")
{
- if(!node.connman->RemoveAddedNode(strNode))
+ if (!connman.RemoveAddedNode(strNode)) {
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node could not be removed. It has not been added previously.");
+ }
}
return NullUniValue;
@@ -314,6 +327,59 @@ static RPCHelpMan addnode()
};
}
+static RPCHelpMan addconnection()
+{
+ return RPCHelpMan{"addconnection",
+ "\nOpen 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."},
+ {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open, either \"outbound-full-relay\" or \"block-relay-only\"."},
+ },
+ 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;
+ } else {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, self.ToString());
+ }
+
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ CConnman& connman = EnsureConnman(node);
+
+ const bool success = connman.AddConnection(address, conn_type);
+ 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;
+},
+ };
+}
+
static RPCHelpMan disconnectnode()
{
return RPCHelpMan{"disconnectnode",
@@ -321,8 +387,8 @@ static RPCHelpMan disconnectnode()
"\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
"\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
{
- {"address", RPCArg::Type::STR, /* default */ "fallback to nodeid", "The IP address/port of the node"},
- {"nodeid", RPCArg::Type::NUM, /* default */ "fallback to address", "The node ID (see getpeerinfo for node IDs)"},
+ {"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)"},
},
RPCResult{RPCResult::Type::NONE, "", ""},
RPCExamples{
@@ -333,9 +399,8 @@ static RPCHelpMan disconnectnode()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ CConnman& connman = EnsureConnman(node);
bool success;
const UniValue &address_arg = request.params[0];
@@ -343,11 +408,11 @@ static RPCHelpMan disconnectnode()
if (!address_arg.isNull() && id_arg.isNull()) {
/* handle disconnect-by-address */
- success = node.connman->DisconnectNode(address_arg.get_str());
+ success = connman.DisconnectNode(address_arg.get_str());
} else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
/* handle disconnect-by-id */
NodeId nodeid = (NodeId) id_arg.get_int64();
- success = node.connman->DisconnectNode(nodeid);
+ success = connman.DisconnectNode(nodeid);
} else {
throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided.");
}
@@ -367,7 +432,7 @@ static RPCHelpMan getaddednodeinfo()
"\nReturns information about the given added node, or all added nodes\n"
"(note that onetry addnodes are not listed here)\n",
{
- {"node", RPCArg::Type::STR, /* default */ "all nodes", "If provided, return information about this specific node, otherwise all nodes are returned."},
+ {"node", RPCArg::Type::STR, RPCArg::DefaultHint{"all nodes"}, "If provided, return information about this specific node, otherwise all nodes are returned."},
},
RPCResult{
RPCResult::Type::ARR, "", "",
@@ -393,11 +458,10 @@ static RPCHelpMan getaddednodeinfo()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ const CConnman& connman = EnsureConnman(node);
- std::vector<AddedNodeInfo> vInfo = node.connman->GetAddedNodeInfo();
+ std::vector<AddedNodeInfo> vInfo = connman.GetAddedNodeInfo();
if (!request.params[0].isNull()) {
bool found = false;
@@ -464,22 +528,21 @@ static RPCHelpMan getnettotals()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if(!node.connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ const CConnman& connman = EnsureConnman(node);
UniValue obj(UniValue::VOBJ);
- obj.pushKV("totalbytesrecv", node.connman->GetTotalBytesRecv());
- obj.pushKV("totalbytessent", node.connman->GetTotalBytesSent());
+ obj.pushKV("totalbytesrecv", connman.GetTotalBytesRecv());
+ obj.pushKV("totalbytessent", connman.GetTotalBytesSent());
obj.pushKV("timemillis", GetTimeMillis());
UniValue outboundLimit(UniValue::VOBJ);
- outboundLimit.pushKV("timeframe", count_seconds(node.connman->GetMaxOutboundTimeframe()));
- outboundLimit.pushKV("target", node.connman->GetMaxOutboundTarget());
- outboundLimit.pushKV("target_reached", node.connman->OutboundTargetReached(false));
- outboundLimit.pushKV("serve_historical_blocks", !node.connman->OutboundTargetReached(true));
- outboundLimit.pushKV("bytes_left_in_cycle", node.connman->GetOutboundTargetBytesLeft());
- outboundLimit.pushKV("time_left_in_cycle", count_seconds(node.connman->GetMaxOutboundTimeLeftInCycle()));
+ 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()));
obj.pushKV("uploadtarget", outboundLimit);
return obj;
},
@@ -491,7 +554,7 @@ static UniValue GetNetworksInfo()
UniValue networks(UniValue::VARR);
for (int n = 0; n < NET_MAX; ++n) {
enum Network network = static_cast<enum Network>(n);
- if (network == NET_UNROUTABLE || network == NET_I2P || network == NET_CJDNS || network == NET_INTERNAL) continue;
+ if (network == NET_UNROUTABLE || network == NET_CJDNS || network == NET_INTERNAL) continue;
proxyType proxy;
UniValue obj(UniValue::VOBJ);
GetProxy(network, proxy);
@@ -531,7 +594,7 @@ static RPCHelpMan getnetworkinfo()
{
{RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::STR, "name", "network (ipv4, ipv6 or onion)"},
+ {RPCResult::Type::STR, "name", "network (" + Join(GetNetworkNames(), ", ") + ")"},
{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"},
@@ -563,7 +626,7 @@ static RPCHelpMan getnetworkinfo()
obj.pushKV("version", CLIENT_VERSION);
obj.pushKV("subversion", strSubVersion);
obj.pushKV("protocolversion",PROTOCOL_VERSION);
- NodeContext& node = EnsureNodeContext(request.context);
+ NodeContext& node = EnsureAnyNodeContext(request.context);
if (node.connman) {
ServiceFlags services = node.connman->GetLocalServices();
obj.pushKV("localservices", strprintf("%016x", services));
@@ -575,9 +638,9 @@ static RPCHelpMan getnetworkinfo()
obj.pushKV("timeoffset", GetTimeOffset());
if (node.connman) {
obj.pushKV("networkactive", node.connman->GetNetworkActive());
- obj.pushKV("connections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL));
- obj.pushKV("connections_in", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_IN));
- obj.pushKV("connections_out", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_OUT));
+ 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));
}
obj.pushKV("networks", GetNetworksInfo());
obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
@@ -608,8 +671,8 @@ static RPCHelpMan setban()
{
{"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"},
- {"bantime", RPCArg::Type::NUM, /* 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, /* default */ "false", "If set, the bantime must be an absolute timestamp expressed in " + UNIX_EPOCH_TIME},
+ {"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},
},
RPCResult{RPCResult::Type::NONE, "", ""},
RPCExamples{
@@ -625,7 +688,7 @@ static RPCHelpMan setban()
if (strCommand != "add" && strCommand != "remove") {
throw std::runtime_error(help.ToString());
}
- NodeContext& node = EnsureNodeContext(request.context);
+ NodeContext& node = EnsureAnyNodeContext(request.context);
if (!node.banman) {
throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
}
@@ -694,9 +757,11 @@ static RPCHelpMan listbanned()
{
{RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::STR, "address", ""},
- {RPCResult::Type::NUM_TIME, "banned_until", ""},
- {RPCResult::Type::NUM_TIME, "ban_created", ""},
+ {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"},
+ {RPCResult::Type::NUM_TIME, "ban_duration", "The ban duration, in seconds"},
+ {RPCResult::Type::NUM_TIME, "time_remaining", "The time remaining until the ban expires, in seconds"},
}},
}},
RPCExamples{
@@ -705,13 +770,14 @@ static RPCHelpMan listbanned()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
+ NodeContext& node = EnsureAnyNodeContext(request.context);
if(!node.banman) {
throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
}
banmap_t banMap;
node.banman->GetBanned(banMap);
+ const int64_t current_time{GetTime()};
UniValue bannedAddresses(UniValue::VARR);
for (const auto& entry : banMap)
@@ -719,8 +785,10 @@ static RPCHelpMan listbanned()
const CBanEntry& banEntry = entry.second;
UniValue rec(UniValue::VOBJ);
rec.pushKV("address", entry.first.ToString());
- rec.pushKV("banned_until", banEntry.nBanUntil);
rec.pushKV("ban_created", banEntry.nCreateTime);
+ rec.pushKV("banned_until", banEntry.nBanUntil);
+ rec.pushKV("ban_duration", (banEntry.nBanUntil - banEntry.nCreateTime));
+ rec.pushKV("time_remaining", (banEntry.nBanUntil - current_time));
bannedAddresses.push_back(rec);
}
@@ -742,7 +810,7 @@ static RPCHelpMan clearbanned()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
+ NodeContext& node = EnsureAnyNodeContext(request.context);
if (!node.banman) {
throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
}
@@ -765,14 +833,12 @@ static RPCHelpMan setnetworkactive()
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if (!node.connman) {
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
- }
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ CConnman& connman = EnsureConnman(node);
- node.connman->SetNetworkActive(request.params[0].get_bool());
+ connman.SetNetworkActive(request.params[0].get_bool());
- return node.connman->GetNetworkActive();
+ return connman.GetNetworkActive();
},
};
}
@@ -780,19 +846,20 @@ static RPCHelpMan setnetworkactive()
static RPCHelpMan getnodeaddresses()
{
return RPCHelpMan{"getnodeaddresses",
- "\nReturn known addresses which can potentially be used to find new nodes in the network\n",
+ "\nReturn known addresses, which can potentially be used to find new nodes in the network.\n",
{
- {"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."},
+ {"count", RPCArg::Type::NUM, RPCArg::Default{1}, "The maximum number of addresses to return. Specify 0 to return all known addresses."},
},
RPCResult{
RPCResult::Type::ARR, "", "",
{
{RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " of when the node was last seen"},
- {RPCResult::Type::NUM, "services", "The services offered"},
+ {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"},
{RPCResult::Type::STR, "address", "The address of the node"},
- {RPCResult::Type::NUM, "port", "The port of the node"},
+ {RPCResult::Type::NUM, "port", "The port number of the node"},
+ {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") the node connected through"},
}},
}
},
@@ -802,20 +869,14 @@ static RPCHelpMan getnodeaddresses()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if (!node.connman) {
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
- }
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ const CConnman& connman = EnsureConnman(node);
+
+ 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");
- int count = 1;
- if (!request.params[0].isNull()) {
- count = request.params[0].get_int();
- if (count < 0) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
- }
- }
// returns a shuffled list of CAddress
- std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0);
+ const std::vector<CAddress> vAddr{connman.GetAddresses(count, /* max_pct */ 0)};
UniValue ret(UniValue::VARR);
for (const CAddress& addr : vAddr) {
@@ -824,6 +885,7 @@ static RPCHelpMan getnodeaddresses()
obj.pushKV("services", (uint64_t)addr.nServices);
obj.pushKV("address", addr.ToStringIP());
obj.pushKV("port", addr.GetPort());
+ obj.pushKV("network", GetNetworkName(addr.GetNetClass()));
ret.push_back(obj);
}
return ret;
@@ -851,15 +913,15 @@ static RPCHelpMan addpeeraddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- NodeContext& node = EnsureNodeContext(request.context);
- if (!node.connman) {
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ if (!node.addrman) {
+ throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Address manager functionality missing or disabled");
}
UniValue obj(UniValue::VOBJ);
std::string addr_string = request.params[0].get_str();
- uint16_t port = request.params[1].get_int();
+ uint16_t port{static_cast<uint16_t>(request.params[1].get_int())};
CNetAddr net_addr;
if (!LookupHost(addr_string, net_addr, false)) {
@@ -870,7 +932,7 @@ static RPCHelpMan addpeeraddress()
address.nTime = GetAdjustedTime();
// The source address is set equal to the address. This is equivalent to the peer
// announcing itself.
- if (!node.connman->AddNewAddresses({address}, address)) {
+ if (!node.addrman->Add(address, address)) {
obj.pushKV("success", false);
return obj;
}
@@ -885,22 +947,24 @@ void RegisterNetRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
-{ // category name actor (function) argNames
- // --------------------- ------------------------ ----------------------- ----------
- { "network", "getconnectioncount", &getconnectioncount, {} },
- { "network", "ping", &ping, {} },
- { "network", "getpeerinfo", &getpeerinfo, {} },
- { "network", "addnode", &addnode, {"node","command"} },
- { "network", "disconnectnode", &disconnectnode, {"address", "nodeid"} },
- { "network", "getaddednodeinfo", &getaddednodeinfo, {"node"} },
- { "network", "getnettotals", &getnettotals, {} },
- { "network", "getnetworkinfo", &getnetworkinfo, {} },
- { "network", "setban", &setban, {"subnet", "command", "bantime", "absolute"} },
- { "network", "listbanned", &listbanned, {} },
- { "network", "clearbanned", &clearbanned, {} },
- { "network", "setnetworkactive", &setnetworkactive, {"state"} },
- { "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
- { "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} },
+{ // 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, },
};
// clang-format on
for (const auto& c : commands) {