Bitcoin Core  21.99.0
P2P Digital Currency
net.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <rpc/server.h>
6 
7 #include <banman.h>
8 #include <chainparams.h>
9 #include <clientversion.h>
10 #include <core_io.h>
11 #include <net.h>
12 #include <net_permissions.h>
13 #include <net_processing.h>
14 #include <net_types.h> // For banmap_t
15 #include <netbase.h>
16 #include <node/context.h>
17 #include <policy/settings.h>
18 #include <rpc/blockchain.h>
19 #include <rpc/protocol.h>
20 #include <rpc/util.h>
21 #include <sync.h>
22 #include <timedata.h>
23 #include <util/strencodings.h>
24 #include <util/string.h>
25 #include <util/system.h>
26 #include <util/translation.h>
27 #include <validation.h>
28 #include <version.h>
29 #include <warnings.h>
30 
31 #include <univalue.h>
32 
33 const std::vector<std::string> CONNECTION_TYPE_DOC{
34  "outbound-full-relay (default automatic connections)",
35  "block-relay-only (does not relay transactions or addresses)",
36  "inbound (initiated by the peer)",
37  "manual (added via addnode RPC or -addnode/-connect configuration options)",
38  "addr-fetch (short-lived automatic connection for soliciting addresses)",
39  "feeler (short-lived automatic connection for testing addresses)"
40 };
41 
43 {
44  return RPCHelpMan{"getconnectioncount",
45  "\nReturns the number of connections to other nodes.\n",
46  {},
47  RPCResult{
48  RPCResult::Type::NUM, "", "The connection count"
49  },
51  HelpExampleCli("getconnectioncount", "")
52  + HelpExampleRpc("getconnectioncount", "")
53  },
54  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
55 {
56  NodeContext& node = EnsureNodeContext(request.context);
57  if(!node.connman)
58  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
59 
60  return (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL);
61 },
62  };
63 }
64 
65 static RPCHelpMan ping()
66 {
67  return RPCHelpMan{"ping",
68  "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
69  "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
70  "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n",
71  {},
74  HelpExampleCli("ping", "")
75  + HelpExampleRpc("ping", "")
76  },
77  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
78 {
79  NodeContext& node = EnsureNodeContext(request.context);
80  if(!node.connman)
81  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
82 
83  // Request that each node send a ping during next message processing pass
84  node.connman->ForEachNode([](CNode* pnode) {
85  pnode->fPingQueued = true;
86  });
87  return NullUniValue;
88 },
89  };
90 }
91 
93 {
94  return RPCHelpMan{"getpeerinfo",
95  "\nReturns data about each connected network node as a json array of objects.\n",
96  {},
97  RPCResult{
98  RPCResult::Type::ARR, "", "",
99  {
100  {RPCResult::Type::OBJ, "", "",
101  {
102  {
103  {RPCResult::Type::NUM, "id", "Peer index"},
104  {RPCResult::Type::STR, "addr", "(host:port) The IP address and port of the peer"},
105  {RPCResult::Type::STR, "addrbind", "(ip:port) Bind address of the connection to the peer"},
106  {RPCResult::Type::STR, "addrlocal", "(ip:port) Local address as reported by the peer"},
107  {RPCResult::Type::STR, "network", "Network (ipv4, ipv6, or onion) the peer connected through"},
108  {RPCResult::Type::NUM, "mapped_as", "The AS in the BGP route to the peer used for diversifying\n"
109  "peer selection (only available if the asmap config flag is set)"},
110  {RPCResult::Type::STR_HEX, "services", "The services offered"},
111  {RPCResult::Type::ARR, "servicesnames", "the services offered, in human-readable form",
112  {
113  {RPCResult::Type::STR, "SERVICE_NAME", "the service name if it is recognised"}
114  }},
115  {RPCResult::Type::BOOL, "relaytxes", "Whether peer has asked us to relay transactions to it"},
116  {RPCResult::Type::NUM_TIME, "lastsend", "The " + UNIX_EPOCH_TIME + " of the last send"},
117  {RPCResult::Type::NUM_TIME, "lastrecv", "The " + UNIX_EPOCH_TIME + " of the last receive"},
118  {RPCResult::Type::NUM_TIME, "last_transaction", "The " + UNIX_EPOCH_TIME + " of the last valid transaction received from this peer"},
119  {RPCResult::Type::NUM_TIME, "last_block", "The " + UNIX_EPOCH_TIME + " of the last block received from this peer"},
120  {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
121  {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
122  {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
123  {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
124  {RPCResult::Type::NUM, "pingtime", "ping time (if available)"},
125  {RPCResult::Type::NUM, "minping", "minimum observed ping time (if any at all)"},
126  {RPCResult::Type::NUM, "pingwait", "ping wait (if non-zero)"},
127  {RPCResult::Type::NUM, "version", "The peer version, such as 70001"},
128  {RPCResult::Type::STR, "subver", "The string version"},
129  {RPCResult::Type::BOOL, "inbound", "Inbound (true) or Outbound (false)"},
130  {RPCResult::Type::BOOL, "bip152_hb_to", "Whether we selected peer as (compact blocks) high-bandwidth peer"},
131  {RPCResult::Type::BOOL, "bip152_hb_from", "Whether peer selected us as (compact blocks) high-bandwidth peer"},
132  {RPCResult::Type::NUM, "startingheight", "The starting height (block) of the peer"},
133  {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
134  {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
135  {RPCResult::Type::ARR, "inflight", "",
136  {
137  {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
138  }},
139  {RPCResult::Type::ARR, "permissions", "Any special permissions that have been granted to this peer",
140  {
141  {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"},
142  }},
143  {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
144  {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
145  {
146  {RPCResult::Type::NUM, "msg", "The total bytes sent aggregated by message type\n"
147  "When a message type is not listed in this json object, the bytes sent are 0.\n"
148  "Only known message types can appear as keys in the object."}
149  }},
150  {RPCResult::Type::OBJ, "bytesrecv_per_msg", "",
151  {
152  {RPCResult::Type::NUM, "msg", "The total bytes received aggregated by message type\n"
153  "When a message type is not listed in this json object, the bytes received are 0.\n"
154  "Only known message types can appear as keys in the object and all bytes received\n"
155  "of unknown message types are listed under '"+NET_MESSAGE_COMMAND_OTHER+"'."}
156  }},
157  {RPCResult::Type::STR, "connection_type", "Type of connection: \n" + Join(CONNECTION_TYPE_DOC, ",\n") + ".\n"
158  "Please note this output is unlikely to be stable in upcoming releases as we iterate to\n"
159  "best capture connection behaviors."},
160  }},
161  }},
162  },
163  RPCExamples{
164  HelpExampleCli("getpeerinfo", "")
165  + HelpExampleRpc("getpeerinfo", "")
166  },
167  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
168 {
169  NodeContext& node = EnsureNodeContext(request.context);
170  if(!node.connman || !node.peerman) {
171  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
172  }
173 
174  std::vector<CNodeStats> vstats;
175  node.connman->GetNodeStats(vstats);
176 
178 
179  for (const CNodeStats& stats : vstats) {
181  CNodeStateStats statestats;
182  bool fStateStats = node.peerman->GetNodeStateStats(stats.nodeid, statestats);
183  obj.pushKV("id", stats.nodeid);
184  obj.pushKV("addr", stats.addrName);
185  if (stats.addrBind.IsValid()) {
186  obj.pushKV("addrbind", stats.addrBind.ToString());
187  }
188  if (!(stats.addrLocal.empty())) {
189  obj.pushKV("addrlocal", stats.addrLocal);
190  }
191  obj.pushKV("network", GetNetworkName(stats.m_network));
192  if (stats.m_mapped_as != 0) {
193  obj.pushKV("mapped_as", uint64_t(stats.m_mapped_as));
194  }
195  obj.pushKV("services", strprintf("%016x", stats.nServices));
196  obj.pushKV("servicesnames", GetServicesNames(stats.nServices));
197  obj.pushKV("relaytxes", stats.fRelayTxes);
198  obj.pushKV("lastsend", stats.nLastSend);
199  obj.pushKV("lastrecv", stats.nLastRecv);
200  obj.pushKV("last_transaction", stats.nLastTXTime);
201  obj.pushKV("last_block", stats.nLastBlockTime);
202  obj.pushKV("bytessent", stats.nSendBytes);
203  obj.pushKV("bytesrecv", stats.nRecvBytes);
204  obj.pushKV("conntime", stats.nTimeConnected);
205  obj.pushKV("timeoffset", stats.nTimeOffset);
206  if (stats.m_ping_usec > 0) {
207  obj.pushKV("pingtime", ((double)stats.m_ping_usec) / 1e6);
208  }
209  if (stats.m_min_ping_usec < std::numeric_limits<int64_t>::max()) {
210  obj.pushKV("minping", ((double)stats.m_min_ping_usec) / 1e6);
211  }
212  if (stats.m_ping_wait_usec > 0) {
213  obj.pushKV("pingwait", ((double)stats.m_ping_wait_usec) / 1e6);
214  }
215  obj.pushKV("version", stats.nVersion);
216  // Use the sanitized form of subver here, to avoid tricksy remote peers from
217  // corrupting or modifying the JSON output by putting special characters in
218  // their ver message.
219  obj.pushKV("subver", stats.cleanSubVer);
220  obj.pushKV("inbound", stats.fInbound);
221  obj.pushKV("bip152_hb_to", stats.m_bip152_highbandwidth_to);
222  obj.pushKV("bip152_hb_from", stats.m_bip152_highbandwidth_from);
223  if (fStateStats) {
224  obj.pushKV("startingheight", statestats.m_starting_height);
225  obj.pushKV("synced_headers", statestats.nSyncHeight);
226  obj.pushKV("synced_blocks", statestats.nCommonHeight);
227  UniValue heights(UniValue::VARR);
228  for (const int height : statestats.vHeightInFlight) {
229  heights.push_back(height);
230  }
231  obj.pushKV("inflight", heights);
232  }
233  UniValue permissions(UniValue::VARR);
234  for (const auto& permission : NetPermissions::ToStrings(stats.m_permissionFlags)) {
235  permissions.push_back(permission);
236  }
237  obj.pushKV("permissions", permissions);
238  obj.pushKV("minfeefilter", ValueFromAmount(stats.minFeeFilter));
239 
240  UniValue sendPerMsgCmd(UniValue::VOBJ);
241  for (const auto& i : stats.mapSendBytesPerMsgCmd) {
242  if (i.second > 0)
243  sendPerMsgCmd.pushKV(i.first, i.second);
244  }
245  obj.pushKV("bytessent_per_msg", sendPerMsgCmd);
246 
247  UniValue recvPerMsgCmd(UniValue::VOBJ);
248  for (const auto& i : stats.mapRecvBytesPerMsgCmd) {
249  if (i.second > 0)
250  recvPerMsgCmd.pushKV(i.first, i.second);
251  }
252  obj.pushKV("bytesrecv_per_msg", recvPerMsgCmd);
253  obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
254 
255  ret.push_back(obj);
256  }
257 
258  return ret;
259 },
260  };
261 }
262 
264 {
265  return RPCHelpMan{"addnode",
266  "\nAttempts to add or remove a node from the addnode list.\n"
267  "Or try a connection to a node once.\n"
268  "Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be\n"
269  "full nodes/support SegWit as other outbound peers are (though such peers will not be synced from).\n",
270  {
271  {"node", RPCArg::Type::STR, RPCArg::Optional::NO, "The node (see getpeerinfo for nodes)"},
272  {"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"},
273  },
275  RPCExamples{
276  HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
277  + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
278  },
279  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
280 {
281  std::string strCommand;
282  if (!request.params[1].isNull())
283  strCommand = request.params[1].get_str();
284  if (strCommand != "onetry" && strCommand != "add" && strCommand != "remove") {
285  throw std::runtime_error(
286  self.ToString());
287  }
288 
289  NodeContext& node = EnsureNodeContext(request.context);
290  if(!node.connman)
291  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
292 
293  std::string strNode = request.params[0].get_str();
294 
295  if (strCommand == "onetry")
296  {
297  CAddress addr;
298  node.connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), ConnectionType::MANUAL);
299  return NullUniValue;
300  }
301 
302  if (strCommand == "add")
303  {
304  if(!node.connman->AddNode(strNode))
305  throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
306  }
307  else if(strCommand == "remove")
308  {
309  if(!node.connman->RemoveAddedNode(strNode))
310  throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node could not be removed. It has not been added previously.");
311  }
312 
313  return NullUniValue;
314 },
315  };
316 }
317 
319 {
320  return RPCHelpMan{"addconnection",
321  "\nOpen an outbound connection to a specified node. This RPC is for testing only.\n",
322  {
323  {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address and port to attempt connecting to."},
324  {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open, either \"outbound-full-relay\" or \"block-relay-only\"."},
325  },
326  RPCResult{
327  RPCResult::Type::OBJ, "", "",
328  {
329  { RPCResult::Type::STR, "address", "Address of newly added connection." },
330  { RPCResult::Type::STR, "connection_type", "Type of connection opened." },
331  }},
332  RPCExamples{
333  HelpExampleCli("addconnection", "\"192.168.0.6:8333\" \"outbound-full-relay\"")
334  + HelpExampleRpc("addconnection", "\"192.168.0.6:8333\" \"outbound-full-relay\"")
335  },
336  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
337 {
339  throw std::runtime_error("addconnection is for regression testing (-regtest mode) only.");
340  }
341 
342  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VSTR});
343  const std::string address = request.params[0].get_str();
344  const std::string conn_type_in{TrimString(request.params[1].get_str())};
345  ConnectionType conn_type{};
346  if (conn_type_in == "outbound-full-relay") {
348  } else if (conn_type_in == "block-relay-only") {
349  conn_type = ConnectionType::BLOCK_RELAY;
350  } else {
352  }
353 
354  NodeContext& node = EnsureNodeContext(request.context);
355  if (!node.connman) {
356  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled.");
357  }
358 
359  const bool success = node.connman->AddConnection(address, conn_type);
360  if (!success) {
361  throw JSONRPCError(RPC_CLIENT_NODE_CAPACITY_REACHED, "Error: Already at capacity for specified connection type.");
362  }
363 
364  UniValue info(UniValue::VOBJ);
365  info.pushKV("address", address);
366  info.pushKV("connection_type", conn_type_in);
367 
368  return info;
369 },
370  };
371 }
372 
374 {
375  return RPCHelpMan{"disconnectnode",
376  "\nImmediately disconnects from the specified peer node.\n"
377  "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
378  "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
379  {
380  {"address", RPCArg::Type::STR, /* default */ "fallback to nodeid", "The IP address/port of the node"},
381  {"nodeid", RPCArg::Type::NUM, /* default */ "fallback to address", "The node ID (see getpeerinfo for node IDs)"},
382  },
384  RPCExamples{
385  HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"")
386  + HelpExampleCli("disconnectnode", "\"\" 1")
387  + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
388  + HelpExampleRpc("disconnectnode", "\"\", 1")
389  },
390  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
391 {
392  NodeContext& node = EnsureNodeContext(request.context);
393  if(!node.connman)
394  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
395 
396  bool success;
397  const UniValue &address_arg = request.params[0];
398  const UniValue &id_arg = request.params[1];
399 
400  if (!address_arg.isNull() && id_arg.isNull()) {
401  /* handle disconnect-by-address */
402  success = node.connman->DisconnectNode(address_arg.get_str());
403  } else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
404  /* handle disconnect-by-id */
405  NodeId nodeid = (NodeId) id_arg.get_int64();
406  success = node.connman->DisconnectNode(nodeid);
407  } else {
408  throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided.");
409  }
410 
411  if (!success) {
412  throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
413  }
414 
415  return NullUniValue;
416 },
417  };
418 }
419 
421 {
422  return RPCHelpMan{"getaddednodeinfo",
423  "\nReturns information about the given added node, or all added nodes\n"
424  "(note that onetry addnodes are not listed here)\n",
425  {
426  {"node", RPCArg::Type::STR, /* default */ "all nodes", "If provided, return information about this specific node, otherwise all nodes are returned."},
427  },
428  RPCResult{
429  RPCResult::Type::ARR, "", "",
430  {
431  {RPCResult::Type::OBJ, "", "",
432  {
433  {RPCResult::Type::STR, "addednode", "The node IP address or name (as provided to addnode)"},
434  {RPCResult::Type::BOOL, "connected", "If connected"},
435  {RPCResult::Type::ARR, "addresses", "Only when connected = true",
436  {
437  {RPCResult::Type::OBJ, "", "",
438  {
439  {RPCResult::Type::STR, "address", "The bitcoin server IP and port we're connected to"},
440  {RPCResult::Type::STR, "connected", "connection, inbound or outbound"},
441  }},
442  }},
443  }},
444  }
445  },
446  RPCExamples{
447  HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"")
448  + HelpExampleRpc("getaddednodeinfo", "\"192.168.0.201\"")
449  },
450  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
451 {
452  NodeContext& node = EnsureNodeContext(request.context);
453  if(!node.connman)
454  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
455 
456  std::vector<AddedNodeInfo> vInfo = node.connman->GetAddedNodeInfo();
457 
458  if (!request.params[0].isNull()) {
459  bool found = false;
460  for (const AddedNodeInfo& info : vInfo) {
461  if (info.strAddedNode == request.params[0].get_str()) {
462  vInfo.assign(1, info);
463  found = true;
464  break;
465  }
466  }
467  if (!found) {
468  throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
469  }
470  }
471 
473 
474  for (const AddedNodeInfo& info : vInfo) {
476  obj.pushKV("addednode", info.strAddedNode);
477  obj.pushKV("connected", info.fConnected);
478  UniValue addresses(UniValue::VARR);
479  if (info.fConnected) {
480  UniValue address(UniValue::VOBJ);
481  address.pushKV("address", info.resolvedAddress.ToString());
482  address.pushKV("connected", info.fInbound ? "inbound" : "outbound");
483  addresses.push_back(address);
484  }
485  obj.pushKV("addresses", addresses);
486  ret.push_back(obj);
487  }
488 
489  return ret;
490 },
491  };
492 }
493 
495 {
496  return RPCHelpMan{"getnettotals",
497  "\nReturns information about network traffic, including bytes in, bytes out,\n"
498  "and current time.\n",
499  {},
500  RPCResult{
501  RPCResult::Type::OBJ, "", "",
502  {
503  {RPCResult::Type::NUM, "totalbytesrecv", "Total bytes received"},
504  {RPCResult::Type::NUM, "totalbytessent", "Total bytes sent"},
505  {RPCResult::Type::NUM_TIME, "timemillis", "Current " + UNIX_EPOCH_TIME + " in milliseconds"},
506  {RPCResult::Type::OBJ, "uploadtarget", "",
507  {
508  {RPCResult::Type::NUM, "timeframe", "Length of the measuring timeframe in seconds"},
509  {RPCResult::Type::NUM, "target", "Target in bytes"},
510  {RPCResult::Type::BOOL, "target_reached", "True if target is reached"},
511  {RPCResult::Type::BOOL, "serve_historical_blocks", "True if serving historical blocks"},
512  {RPCResult::Type::NUM, "bytes_left_in_cycle", "Bytes left in current time cycle"},
513  {RPCResult::Type::NUM, "time_left_in_cycle", "Seconds left in current time cycle"},
514  }},
515  }
516  },
517  RPCExamples{
518  HelpExampleCli("getnettotals", "")
519  + HelpExampleRpc("getnettotals", "")
520  },
521  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
522 {
523  NodeContext& node = EnsureNodeContext(request.context);
524  if(!node.connman)
525  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
526 
528  obj.pushKV("totalbytesrecv", node.connman->GetTotalBytesRecv());
529  obj.pushKV("totalbytessent", node.connman->GetTotalBytesSent());
530  obj.pushKV("timemillis", GetTimeMillis());
531 
532  UniValue outboundLimit(UniValue::VOBJ);
533  outboundLimit.pushKV("timeframe", count_seconds(node.connman->GetMaxOutboundTimeframe()));
534  outboundLimit.pushKV("target", node.connman->GetMaxOutboundTarget());
535  outboundLimit.pushKV("target_reached", node.connman->OutboundTargetReached(false));
536  outboundLimit.pushKV("serve_historical_blocks", !node.connman->OutboundTargetReached(true));
537  outboundLimit.pushKV("bytes_left_in_cycle", node.connman->GetOutboundTargetBytesLeft());
538  outboundLimit.pushKV("time_left_in_cycle", count_seconds(node.connman->GetMaxOutboundTimeLeftInCycle()));
539  obj.pushKV("uploadtarget", outboundLimit);
540  return obj;
541 },
542  };
543 }
544 
546 {
547  UniValue networks(UniValue::VARR);
548  for (int n = 0; n < NET_MAX; ++n) {
549  enum Network network = static_cast<enum Network>(n);
550  if (network == NET_UNROUTABLE || network == NET_I2P || network == NET_CJDNS || network == NET_INTERNAL) continue;
551  proxyType proxy;
553  GetProxy(network, proxy);
554  obj.pushKV("name", GetNetworkName(network));
555  obj.pushKV("limited", !IsReachable(network));
556  obj.pushKV("reachable", IsReachable(network));
557  obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string());
558  obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials);
559  networks.push_back(obj);
560  }
561  return networks;
562 }
563 
565 {
566  return RPCHelpMan{"getnetworkinfo",
567  "Returns an object containing various state info regarding P2P networking.\n",
568  {},
569  RPCResult{
570  RPCResult::Type::OBJ, "", "",
571  {
572  {RPCResult::Type::NUM, "version", "the server version"},
573  {RPCResult::Type::STR, "subversion", "the server subversion string"},
574  {RPCResult::Type::NUM, "protocolversion", "the protocol version"},
575  {RPCResult::Type::STR_HEX, "localservices", "the services we offer to the network"},
576  {RPCResult::Type::ARR, "localservicesnames", "the services we offer to the network, in human-readable form",
577  {
578  {RPCResult::Type::STR, "SERVICE_NAME", "the service name"},
579  }},
580  {RPCResult::Type::BOOL, "localrelay", "true if transaction relay is requested from peers"},
581  {RPCResult::Type::NUM, "timeoffset", "the time offset"},
582  {RPCResult::Type::NUM, "connections", "the total number of connections"},
583  {RPCResult::Type::NUM, "connections_in", "the number of inbound connections"},
584  {RPCResult::Type::NUM, "connections_out", "the number of outbound connections"},
585  {RPCResult::Type::BOOL, "networkactive", "whether p2p networking is enabled"},
586  {RPCResult::Type::ARR, "networks", "information per network",
587  {
588  {RPCResult::Type::OBJ, "", "",
589  {
590  {RPCResult::Type::STR, "name", "network (ipv4, ipv6 or onion)"},
591  {RPCResult::Type::BOOL, "limited", "is the network limited using -onlynet?"},
592  {RPCResult::Type::BOOL, "reachable", "is the network reachable?"},
593  {RPCResult::Type::STR, "proxy", "(\"host:port\") the proxy that is used for this network, or empty if none"},
594  {RPCResult::Type::BOOL, "proxy_randomize_credentials", "Whether randomized credentials are used"},
595  }},
596  }},
597  {RPCResult::Type::NUM, "relayfee", "minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB"},
598  {RPCResult::Type::NUM, "incrementalfee", "minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB"},
599  {RPCResult::Type::ARR, "localaddresses", "list of local addresses",
600  {
601  {RPCResult::Type::OBJ, "", "",
602  {
603  {RPCResult::Type::STR, "address", "network address"},
604  {RPCResult::Type::NUM, "port", "network port"},
605  {RPCResult::Type::NUM, "score", "relative score"},
606  }},
607  }},
608  {RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
609  }
610  },
611  RPCExamples{
612  HelpExampleCli("getnetworkinfo", "")
613  + HelpExampleRpc("getnetworkinfo", "")
614  },
615  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
616 {
617  LOCK(cs_main);
619  obj.pushKV("version", CLIENT_VERSION);
620  obj.pushKV("subversion", strSubVersion);
621  obj.pushKV("protocolversion",PROTOCOL_VERSION);
622  NodeContext& node = EnsureNodeContext(request.context);
623  if (node.connman) {
624  ServiceFlags services = node.connman->GetLocalServices();
625  obj.pushKV("localservices", strprintf("%016x", services));
626  obj.pushKV("localservicesnames", GetServicesNames(services));
627  }
628  if (node.peerman) {
629  obj.pushKV("localrelay", !node.peerman->IgnoresIncomingTxs());
630  }
631  obj.pushKV("timeoffset", GetTimeOffset());
632  if (node.connman) {
633  obj.pushKV("networkactive", node.connman->GetNetworkActive());
634  obj.pushKV("connections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL));
635  obj.pushKV("connections_in", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_IN));
636  obj.pushKV("connections_out", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_OUT));
637  }
638  obj.pushKV("networks", GetNetworksInfo());
639  obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
640  obj.pushKV("incrementalfee", ValueFromAmount(::incrementalRelayFee.GetFeePerK()));
641  UniValue localAddresses(UniValue::VARR);
642  {
644  for (const std::pair<const CNetAddr, LocalServiceInfo> &item : mapLocalHost)
645  {
647  rec.pushKV("address", item.first.ToString());
648  rec.pushKV("port", item.second.nPort);
649  rec.pushKV("score", item.second.nScore);
650  localAddresses.push_back(rec);
651  }
652  }
653  obj.pushKV("localaddresses", localAddresses);
654  obj.pushKV("warnings", GetWarnings(false).original);
655  return obj;
656 },
657  };
658 }
659 
661 {
662  return RPCHelpMan{"setban",
663  "\nAttempts to add or remove an IP/Subnet from the banned list.\n",
664  {
665  {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)"},
666  {"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"},
667  {"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)"},
668  {"absolute", RPCArg::Type::BOOL, /* default */ "false", "If set, the bantime must be an absolute timestamp expressed in " + UNIX_EPOCH_TIME},
669  },
671  RPCExamples{
672  HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
673  + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
674  + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400")
675  },
676  [&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue
677 {
678  std::string strCommand;
679  if (!request.params[1].isNull())
680  strCommand = request.params[1].get_str();
681  if (strCommand != "add" && strCommand != "remove") {
682  throw std::runtime_error(help.ToString());
683  }
684  NodeContext& node = EnsureNodeContext(request.context);
685  if (!node.banman) {
686  throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
687  }
688 
689  CSubNet subNet;
690  CNetAddr netAddr;
691  bool isSubnet = false;
692 
693  if (request.params[0].get_str().find('/') != std::string::npos)
694  isSubnet = true;
695 
696  if (!isSubnet) {
697  CNetAddr resolved;
698  LookupHost(request.params[0].get_str(), resolved, false);
699  netAddr = resolved;
700  }
701  else
702  LookupSubNet(request.params[0].get_str(), subNet);
703 
704  if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
705  throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Invalid IP/Subnet");
706 
707  if (strCommand == "add")
708  {
709  if (isSubnet ? node.banman->IsBanned(subNet) : node.banman->IsBanned(netAddr)) {
710  throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
711  }
712 
713  int64_t banTime = 0; //use standard bantime if not specified
714  if (!request.params[2].isNull())
715  banTime = request.params[2].get_int64();
716 
717  bool absolute = false;
718  if (request.params[3].isTrue())
719  absolute = true;
720 
721  if (isSubnet) {
722  node.banman->Ban(subNet, banTime, absolute);
723  if (node.connman) {
724  node.connman->DisconnectNode(subNet);
725  }
726  } else {
727  node.banman->Ban(netAddr, banTime, absolute);
728  if (node.connman) {
729  node.connman->DisconnectNode(netAddr);
730  }
731  }
732  }
733  else if(strCommand == "remove")
734  {
735  if (!( isSubnet ? node.banman->Unban(subNet) : node.banman->Unban(netAddr) )) {
736  throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Unban failed. Requested address/subnet was not previously manually banned.");
737  }
738  }
739  return NullUniValue;
740 },
741  };
742 }
743 
745 {
746  return RPCHelpMan{"listbanned",
747  "\nList all manually banned IPs/Subnets.\n",
748  {},
750  {
751  {RPCResult::Type::OBJ, "", "",
752  {
753  {RPCResult::Type::STR, "address", ""},
754  {RPCResult::Type::NUM_TIME, "banned_until", ""},
755  {RPCResult::Type::NUM_TIME, "ban_created", ""},
756  }},
757  }},
758  RPCExamples{
759  HelpExampleCli("listbanned", "")
760  + HelpExampleRpc("listbanned", "")
761  },
762  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
763 {
764  NodeContext& node = EnsureNodeContext(request.context);
765  if(!node.banman) {
766  throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
767  }
768 
769  banmap_t banMap;
770  node.banman->GetBanned(banMap);
771 
772  UniValue bannedAddresses(UniValue::VARR);
773  for (const auto& entry : banMap)
774  {
775  const CBanEntry& banEntry = entry.second;
777  rec.pushKV("address", entry.first.ToString());
778  rec.pushKV("banned_until", banEntry.nBanUntil);
779  rec.pushKV("ban_created", banEntry.nCreateTime);
780 
781  bannedAddresses.push_back(rec);
782  }
783 
784  return bannedAddresses;
785 },
786  };
787 }
788 
790 {
791  return RPCHelpMan{"clearbanned",
792  "\nClear all banned IPs.\n",
793  {},
795  RPCExamples{
796  HelpExampleCli("clearbanned", "")
797  + HelpExampleRpc("clearbanned", "")
798  },
799  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
800 {
801  NodeContext& node = EnsureNodeContext(request.context);
802  if (!node.banman) {
803  throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
804  }
805 
806  node.banman->ClearBanned();
807 
808  return NullUniValue;
809 },
810  };
811 }
812 
814 {
815  return RPCHelpMan{"setnetworkactive",
816  "\nDisable/enable all p2p network activity.\n",
817  {
818  {"state", RPCArg::Type::BOOL, RPCArg::Optional::NO, "true to enable networking, false to disable"},
819  },
820  RPCResult{RPCResult::Type::BOOL, "", "The value that was passed in"},
821  RPCExamples{""},
822  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
823 {
824  NodeContext& node = EnsureNodeContext(request.context);
825  if (!node.connman) {
826  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
827  }
828 
829  node.connman->SetNetworkActive(request.params[0].get_bool());
830 
831  return node.connman->GetNetworkActive();
832 },
833  };
834 }
835 
837 {
838  return RPCHelpMan{"getnodeaddresses",
839  "\nReturn known addresses which can potentially be used to find new nodes in the network\n",
840  {
841  {"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."},
842  },
843  RPCResult{
844  RPCResult::Type::ARR, "", "",
845  {
846  {RPCResult::Type::OBJ, "", "",
847  {
848  {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " of when the node was last seen"},
849  {RPCResult::Type::NUM, "services", "The services offered"},
850  {RPCResult::Type::STR, "address", "The address of the node"},
851  {RPCResult::Type::NUM, "port", "The port of the node"},
852  }},
853  }
854  },
855  RPCExamples{
856  HelpExampleCli("getnodeaddresses", "8")
857  + HelpExampleRpc("getnodeaddresses", "8")
858  },
859  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
860 {
861  NodeContext& node = EnsureNodeContext(request.context);
862  if (!node.connman) {
863  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
864  }
865 
866  int count = 1;
867  if (!request.params[0].isNull()) {
868  count = request.params[0].get_int();
869  if (count < 0) {
870  throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
871  }
872  }
873  // returns a shuffled list of CAddress
874  std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0);
876 
877  for (const CAddress& addr : vAddr) {
879  obj.pushKV("time", (int)addr.nTime);
880  obj.pushKV("services", (uint64_t)addr.nServices);
881  obj.pushKV("address", addr.ToStringIP());
882  obj.pushKV("port", addr.GetPort());
883  ret.push_back(obj);
884  }
885  return ret;
886 },
887  };
888 }
889 
891 {
892  return RPCHelpMan{"addpeeraddress",
893  "\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n",
894  {
895  {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address of the peer"},
896  {"port", RPCArg::Type::NUM, RPCArg::Optional::NO, "The port of the peer"},
897  },
898  RPCResult{
899  RPCResult::Type::OBJ, "", "",
900  {
901  {RPCResult::Type::BOOL, "success", "whether the peer address was successfully added to the address manager"},
902  },
903  },
904  RPCExamples{
905  HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 8333")
906  + HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 8333")
907  },
908  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
909 {
910  NodeContext& node = EnsureNodeContext(request.context);
911  if (!node.connman) {
912  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
913  }
914 
916 
917  std::string addr_string = request.params[0].get_str();
918  uint16_t port = request.params[1].get_int();
919 
920  CNetAddr net_addr;
921  if (!LookupHost(addr_string, net_addr, false)) {
922  obj.pushKV("success", false);
923  return obj;
924  }
925  CAddress address = CAddress({net_addr, port}, ServiceFlags(NODE_NETWORK|NODE_WITNESS));
926  address.nTime = GetAdjustedTime();
927  // The source address is set equal to the address. This is equivalent to the peer
928  // announcing itself.
929  if (!node.connman->AddNewAddresses({address}, address)) {
930  obj.pushKV("success", false);
931  return obj;
932  }
933 
934  obj.pushKV("success", true);
935  return obj;
936 },
937  };
938 }
939 
941 {
942 // clang-format off
943 static const CRPCCommand commands[] =
944 { // category name actor (function) argNames
945  // --------------------- ------------------------ ----------------------- ----------
946  { "network", "getconnectioncount", &getconnectioncount, {} },
947  { "network", "ping", &ping, {} },
948  { "network", "getpeerinfo", &getpeerinfo, {} },
949  { "network", "addnode", &addnode, {"node","command"} },
950  { "network", "disconnectnode", &disconnectnode, {"address", "nodeid"} },
951  { "network", "getaddednodeinfo", &getaddednodeinfo, {"node"} },
952  { "network", "getnettotals", &getnettotals, {} },
953  { "network", "getnetworkinfo", &getnetworkinfo, {} },
954  { "network", "setban", &setban, {"subnet", "command", "bantime", "absolute"} },
955  { "network", "listbanned", &listbanned, {} },
956  { "network", "clearbanned", &clearbanned, {} },
957  { "network", "setnetworkactive", &setnetworkactive, {"state"} },
958  { "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
959 
960  { "hidden", "addconnection", &addconnection, {"address", "connection_type"} },
961  { "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} },
962 };
963 // clang-format on
964  for (const auto& c : commands) {
965  t.appendCommand(c.name, &c);
966  }
967 }
std::string NetworkIDString() const
Return the network string.
Definition: chainparams.h:86
static RPCHelpMan ping()
Definition: net.cpp:65
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:23
Node has not been added before.
Definition: protocol.h:61
const std::vector< std::string > NET_PERMISSIONS_DOC
ServiceFlags
nServices flags
Definition: protocol.h:269
static RPCHelpMan clearbanned()
Definition: net.cpp:789
RPC command dispatcher.
Definition: server.h:128
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:65
We open manual connections to addresses that users explicitly inputted via the addnode RPC...
Max number of outbound or block-relay connections already open.
Definition: protocol.h:65
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:68
Required arg.
static const std::string REGTEST
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:57
std::unique_ptr< BanMan > banman
Definition: context.h:43
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
Definition: string.h:36
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:264
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency...
Definition: util.cpp:20
void RegisterNetRPCCommands(CRPCTable &t)
Register P2P networking RPC commands.
Definition: net.cpp:940
UniValue ValueFromAmount(const CAmount &amount)
Definition: core_write.cpp:20
static UniValue GetNetworksInfo()
Definition: net.cpp:545
static RPCHelpMan addpeeraddress()
Definition: net.cpp:890
const std::string & get_str() const
bool isStr() const
Definition: univalue.h:81
int64_t get_int64() const
int64_t GetTimeOffset()
"Never go to sea with two chronometers; take one or three." Our three time sources are: ...
Definition: timedata.cpp:28
static RPCHelpMan getnettotals()
Definition: net.cpp:494
std::string ToString() const
Definition: util.cpp:500
I2P.
Definition: netaddress.h:58
int64_t nCreateTime
Definition: addrdb.h:25
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
std::string TrimString(const std::string &str, const std::string &pattern=" \\\)
Definition: string.h:18
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret)
Parse and resolve a specified subnet string into the appropriate internal representation.
Definition: netbase.cpp:831
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:109
bool IsValid() const
Definition: netaddress.cpp:432
static RPCHelpMan getpeerinfo()
Definition: net.cpp:92
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:71
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
Definition: net.cpp:501
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:51
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
static RPCHelpMan getnodeaddresses()
Definition: net.cpp:836
Special string with only hex chars.
NodeContext struct containing references to chain state and connection state.
Definition: context.h:37
int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
Definition: time.h:27
std::unique_ptr< CConnman > connman
Definition: context.h:38
bool randomize_credentials
Definition: netbase.h:37
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
Definition: validation.cpp:148
#define LOCK(cs)
Definition: sync.h:232
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:138
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:128
static RPCHelpMan disconnectnode()
Definition: net.cpp:373
A CService with information about it as peer.
Definition: protocol.h:356
const std::string CURRENCY_UNIT
Definition: feerate.h:14
static RPCHelpMan setban()
Definition: net.cpp:660
static RPCHelpMan addnode()
Definition: net.cpp:263
Network
A network type.
Definition: netaddress.h:43
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
int64_t NodeId
Definition: net.h:83
Invalid IP/Subnet.
Definition: protocol.h:63
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:112
bool isNull() const
Definition: univalue.h:77
Special numeric to denote unix epoch time.
static RPCHelpMan setnetworkactive()
Definition: net.cpp:813
std::unique_ptr< PeerManager > peerman
Definition: context.h:41
CFeeRate incrementalRelayFee
Definition: settings.cpp:12
const std::string NET_MESSAGE_COMMAND_OTHER
Definition: net.cpp:99
int64_t nBanUntil
Definition: addrdb.h:26
NodeContext & EnsureNodeContext(const util::Ref &context)
Definition: blockchain.cpp:59
Database error.
Definition: protocol.h:44
const std::vector< std::string > CONNECTION_TYPE_DOC
Definition: net.cpp:33
Network address.
Definition: netaddress.h:119
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Resolve a host string to its corresponding network addresses.
Definition: netbase.cpp:159
bool IsValid() const
std::atomic< bool > fPingQueued
Definition: net.h:595
bool IsReachable(enum Network net)
Definition: net.cpp:276
CService proxy
Definition: netbase.h:36
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:31
bool IsValid() const
Definition: netbase.h:34
ConnectionType
Different types of connections to a peer.
Definition: net.h:115
const CChainParams & Params()
Return the currently selected parameters.
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
std::string ToStringIPPort() const
Definition: netaddress.cpp:977
static RPCHelpMan getnetworkinfo()
Definition: net.cpp:564
Node to disconnect not found in connected nodes.
Definition: protocol.h:62
Node is already added.
Definition: protocol.h:60
const UniValue NullUniValue
Definition: univalue.cpp:13
static int count
Definition: tests.c:35
These are the default connections that we use to connect with the network.
UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: util.cpp:867
static RPCHelpMan getaddednodeinfo()
Definition: net.cpp:420
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:133
static RPCHelpMan getconnectioncount()
Definition: net.cpp:42
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:13
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:727
No valid connection manager instance found.
Definition: protocol.h:64
static RPCHelpMan listbanned()
Definition: net.cpp:744
std::string GetNetworkName(enum Network net)
Definition: netbase.cpp:55
Information about a peer.
Definition: net.h:388
std::vector< int > vHeightInFlight
Special dictionary with keys that are not literals.
We use block-relay-only connections to help prevent against partition attacks.
Definition: addrdb.h:20
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
CJDNS.
Definition: netaddress.h:61
static RPCHelpMan help()
Definition: server.cpp:133
uint32_t nTime
Definition: protocol.h:394
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:60
static std::vector< std::string > ToStrings(NetPermissionFlags flags)
static RPCHelpMan addconnection()
Definition: net.cpp:318
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:46