Bitcoin Core 32.99.0
P2P Digital Currency
net.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-present 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/register.h> // IWYU pragma: associated
6#include <rpc/server.h>
7
8#include <addrman.h>
9#include <addrman_impl.h>
10#include <banman.h>
11#include <chainparams.h>
12#include <clientversion.h>
13#include <core_io.h>
14#include <net.h>
15#include <net_permissions.h>
16#include <net_processing.h>
17#include <net_types.h>
18#include <netaddress.h>
19#include <netbase.h>
21#include <node/context.h>
23#include <node/warnings.h>
24#include <policy/feerate.h>
25#include <protocol.h>
26#include <rpc/protocol.h>
27#include <rpc/request.h>
28#include <rpc/server_util.h>
29#include <rpc/util.h>
30#include <semaphore_grant.h>
31#include <sync.h>
32#include <tinyformat.h>
33#include <txmempool.h>
34#include <univalue.h>
35#include <util/chaintype.h>
36#include <util/check.h>
37#include <util/strencodings.h>
38#include <util/string.h>
39#include <util/time.h>
40#include <validation.h>
41#ifdef ENABLE_EMBEDDED_ASMAP
42#include <common/args.h>
43#include <hash.h>
44#include <node/data/ip_asn.dat.h>
45#include <streams.h>
46#include <util/asmap.h>
47#include <util/fs.h>
48#endif
49
50#include <atomic>
51#include <compare>
52#include <cstdint>
53#include <functional>
54#include <map>
55#include <memory>
56#include <optional>
57#include <sstream>
58#include <stdexcept>
59#include <string>
60#include <string_view>
61#include <type_traits>
62#include <utility>
63#include <vector>
64
66using util::Join;
68
69const std::vector<std::string> CONNECTION_TYPE_DOC{
70 "outbound-full-relay (default automatic connections)",
71 "block-relay-only (does not relay transactions or addresses)",
72 "inbound (initiated by the peer)",
73 "manual (added via addnode RPC or -addnode/-connect configuration options)",
74 "addr-fetch (short-lived automatic connection for soliciting addresses)",
75 "feeler (short-lived automatic connection for testing addresses)",
76 "private-broadcast (short-lived automatic connection for broadcasting privacy-sensitive transactions)"
77};
78
79const std::vector<std::string> TRANSPORT_TYPE_DOC{
80 "detecting (peer could be v1 or v2)",
81 "v1 (plaintext transport protocol)",
82 "v2 (BIP324 encrypted transport protocol)"
83};
84
86{
87 return RPCMethod{
88 "getconnectioncount",
89 "Returns the number of connections to other nodes.\n",
90 {},
92 RPCResult::Type::NUM, "", "The connection count"
93 },
95 HelpExampleCli("getconnectioncount", "")
96 + HelpExampleRpc("getconnectioncount", "")
97 },
98 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
99{
100 NodeContext& node = EnsureAnyNodeContext(request.context);
101 const CConnman& connman = EnsureConnman(node);
102
104},
105 };
106}
107
109{
110 return RPCMethod{
111 "ping",
112 "Requests that a ping be sent to all other nodes, to measure ping time.\n"
113 "Results are provided in getpeerinfo.\n"
114 "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n",
115 {},
118 HelpExampleCli("ping", "")
119 + HelpExampleRpc("ping", "")
120 },
121 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
122{
123 NodeContext& node = EnsureAnyNodeContext(request.context);
124 PeerManager& peerman = EnsurePeerman(node);
125
126 // Request that each node send a ping during next message processing pass
127 peerman.SendPings();
128 return UniValue::VNULL;
129},
130 };
131}
132
135{
136 UniValue servicesNames(UniValue::VARR);
137
138 for (const auto& flag : serviceFlagsToStr(services)) {
139 servicesNames.push_back(flag);
140 }
141
142 return servicesNames;
143}
144
146{
147 return RPCMethod{
148 "getpeerinfo",
149 "Returns data about each connected network peer as a json array of objects.",
150 {},
151 RPCResult{
152 RPCResult::Type::ARR, "", "",
153 {
154 {RPCResult::Type::OBJ, "", "",
155 {
156 {
157 {RPCResult::Type::NUM, "id", "Peer index"},
158 {RPCResult::Type::STR, "addr", "(host:port) The IP address/hostname optionally followed by :port of the peer"},
159 {RPCResult::Type::STR, "addrbind", /*optional=*/true, "(ip:port) Bind address of the connection to the peer"},
160 {RPCResult::Type::STR, "addrlocal", /*optional=*/true, "(ip:port) Local address as reported by the peer"},
161 {RPCResult::Type::STR, "network", "Network (" + Join(GetNetworkNames(/*append_unroutable=*/true), ", ") + ")"},
162 {RPCResult::Type::NUM, "mapped_as", /*optional=*/true, "Mapped AS (Autonomous System) number at the end of the BGP route to the peer, used for diversifying\n"
163 "peer selection (only displayed if the -asmap config option is set)"},
164 {RPCResult::Type::STR_HEX, "services", "The services offered"},
165 {RPCResult::Type::ARR, "servicesnames", "the services offered, in human-readable form",
166 {
167 {RPCResult::Type::STR, "SERVICE_NAME", "the service name if it is recognised"}
168 }},
169 {RPCResult::Type::BOOL, "relaytxes", "Whether we relay transactions to this peer"},
170 {RPCResult::Type::NUM, "last_inv_sequence", "Mempool sequence number of this peer's last INV"},
171 {RPCResult::Type::NUM, "inv_to_send", "How many txs we have queued to announce to this peer"},
172 {RPCResult::Type::NUM_TIME, "lastsend", "The " + UNIX_EPOCH_TIME + " of the last send"},
173 {RPCResult::Type::NUM_TIME, "lastrecv", "The " + UNIX_EPOCH_TIME + " of the last receive"},
174 {RPCResult::Type::NUM_TIME, "last_transaction", "The " + UNIX_EPOCH_TIME + " of the last valid transaction received from this peer"},
175 {RPCResult::Type::NUM_TIME, "last_block", "The " + UNIX_EPOCH_TIME + " of the last block received from this peer"},
176 {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
177 {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
178 {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
179 {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
180 {RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in seconds, if any"},
181 {RPCResult::Type::NUM, "minping", /*optional=*/true, "The minimum observed ping time in seconds, if any"},
182 {RPCResult::Type::NUM, "pingwait", /*optional=*/true, "The duration in seconds of an outstanding ping (if non-zero)"},
183 {RPCResult::Type::NUM, "version", "The peer version, such as 70001"},
184 {RPCResult::Type::STR, "subver", "The string version"},
185 {RPCResult::Type::BOOL, "inbound", "Inbound (true) or Outbound (false)"},
186 {RPCResult::Type::BOOL, "bip152_hb_to", "Whether we selected peer as (compact blocks) high-bandwidth peer"},
187 {RPCResult::Type::BOOL, "bip152_hb_from", "Whether peer selected us as (compact blocks) high-bandwidth peer"},
188 {RPCResult::Type::NUM, "presynced_headers", "The current height of header pre-synchronization with this peer, or -1 if no low-work sync is in progress"},
189 {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
190 {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
191 {RPCResult::Type::ARR, "inflight", "",
192 {
193 {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
194 }},
195 {RPCResult::Type::BOOL, "addr_relay_enabled", "Whether we participate in address relay with this peer"},
196 {RPCResult::Type::NUM, "addr_processed", "The total number of addresses processed, excluding those dropped due to rate limiting"},
197 {RPCResult::Type::NUM, "addr_rate_limited", "The total number of addresses dropped due to rate limiting"},
198 {RPCResult::Type::ARR, "permissions", "Any special permissions that have been granted to this peer",
199 {
200 {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"},
201 }},
202 {RPCResult::Type::STR_AMOUNT, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
203 {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
204 {
205 {RPCResult::Type::NUM, "msg", "The total bytes sent aggregated by message type\n"
206 "When a message type is not listed in this json object, the bytes sent are 0.\n"
207 "Only known message types can appear as keys in the object."}
208 }},
209 {RPCResult::Type::OBJ_DYN, "bytesrecv_per_msg", "",
210 {
211 {RPCResult::Type::NUM, "msg", "The total bytes received aggregated by message type\n"
212 "When a message type is not listed in this json object, the bytes received are 0.\n"
213 "Only known message types can appear as keys in the object and all bytes received\n"
214 "of unknown message types are listed under '"+NET_MESSAGE_TYPE_OTHER+"'."}
215 }},
216 {RPCResult::Type::STR, "connection_type", "Type of connection: \n" + Join(CONNECTION_TYPE_DOC, ",\n") + ".\n"
217 "Please note this output is unlikely to be stable in upcoming releases as we iterate to\n"
218 "best capture connection behaviors."},
219 {RPCResult::Type::STR, "transport_protocol_type", "Type of transport protocol: \n" + Join(TRANSPORT_TYPE_DOC, ",\n") + ".\n"},
220 {RPCResult::Type::STR, "session_id", "The session ID for this connection, or \"\" if there is none (\"v2\" transport protocol only).\n"},
221 }},
222 }},
223 },
225 HelpExampleCli("getpeerinfo", "")
226 + HelpExampleRpc("getpeerinfo", "")
227 },
228 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
229{
230 NodeContext& node = EnsureAnyNodeContext(request.context);
231 const CConnman& connman = EnsureConnman(node);
232 const PeerManager& peerman = EnsurePeerman(node);
233
234 std::vector<CNodeStats> vstats;
235 connman.GetNodeStats(vstats);
236
238
239 for (const CNodeStats& stats : vstats) {
241 CNodeStateStats statestats;
242 bool fStateStats = peerman.GetNodeStateStats(stats.nodeid, statestats);
243 // GetNodeStateStats() requires the existence of a CNodeState and a Peer object
244 // to succeed for this peer. These are created at connection initialisation and
245 // exist for the duration of the connection - except if there is a race where the
246 // peer got disconnected in between the GetNodeStats() and the GetNodeStateStats()
247 // calls. In this case, the peer doesn't need to be reported here.
248 if (!fStateStats) {
249 continue;
250 }
251 obj.pushKV("id", stats.nodeid);
252 obj.pushKV("addr", stats.m_addr_name);
253 if (stats.addrBind.IsValid()) {
254 obj.pushKV("addrbind", stats.addrBind.ToStringAddrPort());
255 }
256 if (!(stats.addrLocal.empty())) {
257 obj.pushKV("addrlocal", stats.addrLocal);
258 }
259 obj.pushKV("network", GetNetworkName(stats.m_network));
260 if (stats.m_mapped_as != 0) {
261 obj.pushKV("mapped_as", stats.m_mapped_as);
262 }
263 ServiceFlags services{statestats.their_services};
264 obj.pushKV("services", strprintf("%016x", services));
265 obj.pushKV("servicesnames", GetServicesNames(services));
266 obj.pushKV("relaytxes", statestats.m_relay_txs);
267 obj.pushKV("last_inv_sequence", statestats.m_last_inv_seq);
268 obj.pushKV("inv_to_send", statestats.m_inv_to_send);
269 obj.pushKV("lastsend", TicksSinceEpoch<std::chrono::seconds>(stats.m_last_send));
270 obj.pushKV("lastrecv", TicksSinceEpoch<std::chrono::seconds>(stats.m_last_recv));
271 obj.pushKV("last_transaction", count_seconds(stats.m_last_tx_time));
272 obj.pushKV("last_block", count_seconds(stats.m_last_block_time));
273 obj.pushKV("bytessent", stats.nSendBytes);
274 obj.pushKV("bytesrecv", stats.nRecvBytes);
275 obj.pushKV("conntime", TicksSinceEpoch<std::chrono::seconds>(stats.m_connected));
276 obj.pushKV("timeoffset", Ticks<std::chrono::seconds>(statestats.time_offset));
277 if (stats.m_last_ping_time > 0us) {
278 obj.pushKV("pingtime", Ticks<SecondsDouble>(stats.m_last_ping_time));
279 }
280 if (stats.m_min_ping_time < decltype(CNode::m_min_ping_time.load())::max()) {
281 obj.pushKV("minping", Ticks<SecondsDouble>(stats.m_min_ping_time));
282 }
283 if (statestats.m_ping_wait > 0s) {
284 obj.pushKV("pingwait", Ticks<SecondsDouble>(statestats.m_ping_wait));
285 }
286 obj.pushKV("version", stats.nVersion);
287 // Use the sanitized form of subver here, to avoid tricksy remote peers from
288 // corrupting or modifying the JSON output by putting special characters in
289 // their ver message.
290 obj.pushKV("subver", stats.cleanSubVer);
291 obj.pushKV("inbound", stats.fInbound);
292 obj.pushKV("bip152_hb_to", stats.m_bip152_highbandwidth_to);
293 obj.pushKV("bip152_hb_from", stats.m_bip152_highbandwidth_from);
294 obj.pushKV("presynced_headers", statestats.presync_height);
295 obj.pushKV("synced_headers", statestats.nSyncHeight);
296 obj.pushKV("synced_blocks", statestats.nCommonHeight);
297 UniValue heights(UniValue::VARR);
298 for (const int height : statestats.vHeightInFlight) {
299 heights.push_back(height);
300 }
301 obj.pushKV("inflight", std::move(heights));
302 obj.pushKV("addr_relay_enabled", statestats.m_addr_relay_enabled);
303 obj.pushKV("addr_processed", statestats.m_addr_processed);
304 obj.pushKV("addr_rate_limited", statestats.m_addr_rate_limited);
305 UniValue permissions(UniValue::VARR);
306 for (const auto& permission : NetPermissions::ToStrings(stats.m_permission_flags)) {
307 permissions.push_back(permission);
308 }
309 obj.pushKV("permissions", std::move(permissions));
310 obj.pushKV("minfeefilter", ValueFromAmount(statestats.m_fee_filter_received));
311
312 UniValue sendPerMsgType(UniValue::VOBJ);
313 for (const auto& [message_type, total_bytes] : stats.mapSendBytesPerMsgType) {
314 if (total_bytes > 0) {
315 sendPerMsgType.pushKVEnd(message_type, total_bytes);
316 }
317 }
318 obj.pushKV("bytessent_per_msg", std::move(sendPerMsgType));
319
320 UniValue recvPerMsgType(UniValue::VOBJ);
321 for (const auto& [message_type, total_bytes] : stats.mapRecvBytesPerMsgType) {
322 if (total_bytes > 0) {
323 recvPerMsgType.pushKVEnd(message_type, total_bytes);
324 }
325 }
326 obj.pushKV("bytesrecv_per_msg", std::move(recvPerMsgType));
327 obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
328 obj.pushKV("transport_protocol_type", TransportTypeAsString(stats.m_transport_type));
329 obj.pushKV("session_id", stats.m_session_id);
330
331 ret.push_back(std::move(obj));
332 }
333
334 return ret;
335},
336 };
337}
338
340{
341 return RPCMethod{
342 "addnode",
343 "Attempts to add or remove a node from the addnode list.\n"
344 "Or try a connection to a node once.\n"
345 "Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be\n"
346 "full nodes/support SegWit as other outbound peers are (though such peers will not be synced from).\n" +
347 strprintf("Addnode connections are limited to %u at a time", MAX_ADDNODE_CONNECTIONS) +
348 " and are counted separately from the -maxconnections limit.\n",
349 {
350 {"node", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address/hostname optionally followed by :port of the peer to connect to"},
351 {"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"},
352 {"v2transport", RPCArg::Type::BOOL, RPCArg::DefaultHint{"set by -v2transport"}, "Attempt to connect using BIP324 v2 transport protocol (ignored for 'remove' command)"},
353 },
356 HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\" true")
357 + HelpExampleRpc("addnode", R"("192.168.0.6:8333", "onetry", true)")
358 },
359 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
360{
361 const auto command{self.Arg<std::string_view>("command")};
362 if (command != "onetry" && command != "add" && command != "remove") {
363 throw std::runtime_error(
364 self.ToString());
365 }
366
367 NodeContext& node = EnsureAnyNodeContext(request.context);
368 CConnman& connman = EnsureConnman(node);
369
370 const auto node_arg{self.Arg<std::string_view>("node")};
371 if (TrimStringView(node_arg).empty()) {
372 // Such a node would never resolve, but would be retried indefinitely.
373 throw JSONRPCError(RPC_INVALID_PARAMETER, "Error: Node address cannot be empty");
374 }
375
376 bool node_v2transport = connman.GetLocalServices() & NODE_P2P_V2;
377 bool use_v2transport = self.MaybeArg<bool>("v2transport").value_or(node_v2transport);
378
379 if (use_v2transport && !node_v2transport) {
380 throw JSONRPCError(RPC_INVALID_PARAMETER, "Error: v2transport requested but not enabled (see -v2transport)");
381 }
382
383 if (command == "onetry")
384 {
385 CAddress addr;
386 connman.OpenNetworkConnection(/*addrConnect=*/addr,
387 /*fCountFailure=*/false,
388 /*grant_outbound=*/{},
389 /*pszDest=*/std::string{node_arg}.c_str(),
390 /*conn_type=*/ConnectionType::MANUAL,
391 /*use_v2transport=*/use_v2transport,
392 /*proxy_override=*/std::nullopt);
393 return UniValue::VNULL;
394 }
395
396 if (command == "add")
397 {
398 if (!connman.AddNode({std::string{node_arg}, use_v2transport})) {
399 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
400 }
401 }
402 else if (command == "remove")
403 {
404 if (!connman.RemoveAddedNode(node_arg)) {
405 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node could not be removed. It has not been added previously.");
406 }
407 }
408
409 return UniValue::VNULL;
410},
411 };
412}
413
415{
416 return RPCMethod{
417 "addconnection",
418 "Open an outbound connection to a specified node. This RPC is for testing only.\n",
419 {
420 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address and port to attempt connecting to."},
421 {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open (\"outbound-full-relay\", \"block-relay-only\", \"addr-fetch\" or \"feeler\")."},
422 {"v2transport", RPCArg::Type::BOOL, RPCArg::Optional::NO, "Attempt to connect using BIP324 v2 transport protocol"},
423 },
424 RPCResult{
425 RPCResult::Type::OBJ, "", "",
426 {
427 { RPCResult::Type::STR, "address", "Address of newly added connection." },
428 { RPCResult::Type::STR, "connection_type", "Type of connection opened." },
429 }},
431 HelpExampleCli("addconnection", "\"192.168.0.6:8333\" \"outbound-full-relay\" true")
432 + HelpExampleRpc("addconnection", R"("192.168.0.6:8333", "outbound-full-relay", true)")
433 },
434 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
435{
437 throw std::runtime_error("addconnection is for regression testing (-regtest mode) only.");
438 }
439
440 const std::string address = request.params[0].get_str();
441 auto conn_type_in{util::TrimStringView(self.Arg<std::string_view>("connection_type"))};
442 ConnectionType conn_type{};
443 if (conn_type_in == "outbound-full-relay") {
445 } else if (conn_type_in == "block-relay-only") {
446 conn_type = ConnectionType::BLOCK_RELAY;
447 } else if (conn_type_in == "addr-fetch") {
448 conn_type = ConnectionType::ADDR_FETCH;
449 } else if (conn_type_in == "feeler") {
450 conn_type = ConnectionType::FEELER;
451 } else {
453 }
454 bool use_v2transport{self.Arg<bool>("v2transport")};
455
456 NodeContext& node = EnsureAnyNodeContext(request.context);
457 CConnman& connman = EnsureConnman(node);
458
459 if (use_v2transport && !(connman.GetLocalServices() & NODE_P2P_V2)) {
460 throw JSONRPCError(RPC_INVALID_PARAMETER, "Error: Adding v2transport connections requires -v2transport init flag to be set.");
461 }
462
463 const bool success = connman.AddConnection(address, conn_type, use_v2transport);
464 if (!success) {
465 throw JSONRPCError(RPC_CLIENT_NODE_CAPACITY_REACHED, "Error: Already at capacity for specified connection type.");
466 }
467
469 info.pushKV("address", address);
470 info.pushKV("connection_type", conn_type_in);
471
472 return info;
473},
474 };
475}
476
478{
479 return RPCMethod{
480 "disconnectnode",
481 "Immediately disconnects from the specified peer node.\n"
482 "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
483 "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
484 {
485 {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"},
486 {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"},
487 },
490 HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"")
491 + HelpExampleCli("disconnectnode", "\"\" 1")
492 + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
493 + HelpExampleRpc("disconnectnode", "\"\", 1")
494 },
495 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
496{
497 NodeContext& node = EnsureAnyNodeContext(request.context);
498 CConnman& connman = EnsureConnman(node);
499
500 bool success;
501 auto address{self.MaybeArg<std::string_view>("address")};
502 auto node_id{self.MaybeArg<int64_t>("nodeid")};
503
504 if (address && !node_id) {
505 /* handle disconnect-by-address */
506 success = connman.DisconnectNode(*address);
507 } else if (node_id && (!address || address->empty())) {
508 /* handle disconnect-by-id */
509 success = connman.DisconnectNode(*node_id);
510 } else {
511 throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided.");
512 }
513
514 if (!success) {
515 throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
516 }
517
518 return UniValue::VNULL;
519},
520 };
521}
522
524{
525 return RPCMethod{
526 "getaddednodeinfo",
527 "Returns information about the given added node, or all added nodes\n"
528 "(note that onetry addnodes are not listed here)\n",
529 {
530 {"node", RPCArg::Type::STR, RPCArg::DefaultHint{"all nodes"}, "If provided, return information about this specific node, otherwise all nodes are returned."},
531 },
532 RPCResult{
533 RPCResult::Type::ARR, "", "",
534 {
535 {RPCResult::Type::OBJ, "", "",
536 {
537 {RPCResult::Type::STR, "addednode", "The node IP address or name (as provided to addnode)"},
538 {RPCResult::Type::BOOL, "connected", "If connected"},
539 {RPCResult::Type::ARR, "addresses", "Only when connected = true",
540 {
541 {RPCResult::Type::OBJ, "", "",
542 {
543 {RPCResult::Type::STR, "address", "The bitcoin server IP and port we're connected to"},
544 {RPCResult::Type::STR, "connected", "connection, inbound or outbound"},
545 }},
546 }},
547 }},
548 }
549 },
551 HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"")
552 + HelpExampleRpc("getaddednodeinfo", "\"192.168.0.201\"")
553 },
554 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
555{
556 NodeContext& node = EnsureAnyNodeContext(request.context);
557 const CConnman& connman = EnsureConnman(node);
558
559 std::vector<AddedNodeInfo> vInfo = connman.GetAddedNodeInfo(/*include_connected=*/true);
560
561 if (auto node{self.MaybeArg<std::string_view>("node")}) {
562 bool found = false;
563 for (const AddedNodeInfo& info : vInfo) {
564 if (info.m_params.m_added_node == *node) {
565 vInfo.assign(1, info);
566 found = true;
567 break;
568 }
569 }
570 if (!found) {
571 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
572 }
573 }
574
576
577 for (const AddedNodeInfo& info : vInfo) {
579 obj.pushKV("addednode", info.m_params.m_added_node);
580 obj.pushKV("connected", info.fConnected);
581 UniValue addresses(UniValue::VARR);
582 if (info.fConnected) {
583 UniValue address(UniValue::VOBJ);
584 address.pushKV("address", info.resolvedAddress.ToStringAddrPort());
585 address.pushKV("connected", info.fInbound ? "inbound" : "outbound");
586 addresses.push_back(std::move(address));
587 }
588 obj.pushKV("addresses", std::move(addresses));
589 ret.push_back(std::move(obj));
590 }
591
592 return ret;
593},
594 };
595}
596
598{
599 return RPCMethod{"getnettotals",
600 "Returns information about network traffic, including bytes in, bytes out,\n"
601 "and current system time.",
602 {},
603 RPCResult{
604 RPCResult::Type::OBJ, "", "",
605 {
606 {RPCResult::Type::NUM, "totalbytesrecv", "Total bytes received"},
607 {RPCResult::Type::NUM, "totalbytessent", "Total bytes sent"},
608 {RPCResult::Type::NUM_TIME, "timemillis", "Current system " + UNIX_EPOCH_TIME + " in milliseconds"},
609 {RPCResult::Type::OBJ, "uploadtarget", "",
610 {
611 {RPCResult::Type::NUM, "timeframe", "Length of the measuring timeframe in seconds"},
612 {RPCResult::Type::NUM, "target", "Target in bytes"},
613 {RPCResult::Type::BOOL, "target_reached", "True if target is reached"},
614 {RPCResult::Type::BOOL, "serve_historical_blocks", "True if serving historical blocks"},
615 {RPCResult::Type::NUM, "bytes_left_in_cycle", "Bytes left in current time cycle"},
616 {RPCResult::Type::NUM, "time_left_in_cycle", "Seconds left in current time cycle"},
617 }},
618 }
619 },
621 HelpExampleCli("getnettotals", "")
622 + HelpExampleRpc("getnettotals", "")
623 },
624 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
625{
626 NodeContext& node = EnsureAnyNodeContext(request.context);
627 const CConnman& connman = EnsureConnman(node);
628
630 obj.pushKV("totalbytesrecv", connman.GetTotalBytesRecv());
631 obj.pushKV("totalbytessent", connman.GetTotalBytesSent());
632 obj.pushKV("timemillis", TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()));
633
634 UniValue outboundLimit(UniValue::VOBJ);
635 outboundLimit.pushKV("timeframe", count_seconds(connman.GetMaxOutboundTimeframe()));
636 outboundLimit.pushKV("target", connman.GetMaxOutboundTarget());
637 outboundLimit.pushKV("target_reached", connman.OutboundTargetReached(false));
638 outboundLimit.pushKV("serve_historical_blocks", !connman.OutboundTargetReached(true));
639 outboundLimit.pushKV("bytes_left_in_cycle", connman.GetOutboundTargetBytesLeft());
640 outboundLimit.pushKV("time_left_in_cycle", count_seconds(connman.GetMaxOutboundTimeLeftInCycle()));
641 obj.pushKV("uploadtarget", std::move(outboundLimit));
642 return obj;
643},
644 };
645}
646
648{
649 UniValue networks(UniValue::VARR);
650 for (int n = 0; n < NET_MAX; ++n) {
651 enum Network network = static_cast<enum Network>(n);
652 if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
654 obj.pushKV("name", GetNetworkName(network));
655 obj.pushKV("limited", !g_reachable_nets.Contains(network));
656 obj.pushKV("reachable", g_reachable_nets.Contains(network));
657 if (const auto proxy = GetProxy(network)) {
658 obj.pushKV("proxy", proxy->ToString());
659 obj.pushKV("proxy_randomize_credentials", proxy->m_tor_stream_isolation);
660 } else {
661 obj.pushKV("proxy", std::string());
662 obj.pushKV("proxy_randomize_credentials", false);
663 }
664 networks.push_back(std::move(obj));
665 }
666 return networks;
667}
668
670{
671 return RPCMethod{"getnetworkinfo",
672 "Returns an object containing various state info regarding P2P networking.\n",
673 {},
674 RPCResult{
675 RPCResult::Type::OBJ, "", "",
676 {
677 {RPCResult::Type::NUM, "version", "the server version"},
678 {RPCResult::Type::STR, "subversion", "the server subversion string"},
679 {RPCResult::Type::NUM, "protocolversion", "the protocol version"},
680 {RPCResult::Type::STR_HEX, "localservices", "the services we offer to the network"},
681 {RPCResult::Type::ARR, "localservicesnames", "the services we offer to the network, in human-readable form",
682 {
683 {RPCResult::Type::STR, "SERVICE_NAME", "the service name"},
684 }},
685 {RPCResult::Type::BOOL, "localrelay", "true if transaction relay is requested from peers"},
686 {RPCResult::Type::NUM, "timeoffset", "the time offset"},
687 {RPCResult::Type::NUM, "tx_send_rate", "configured target for maximum number of transactions per second to send to inbound peers"},
688 {RPCResult::Type::OBJ_DYN, "inv_buckets", "", {
689 {RPCResult::Type::OBJ, "inbound/outbound", "connection direction",
690 {
691 {RPCResult::Type::NUM, "backlog", "number of queued txs to announce"},
692 {RPCResult::Type::NUM, "count_tok", "tokens available to be consumed per-transaction"},
693 {RPCResult::Type::NUM, "size_tok", "tokens available to be consumed per-byte"},
694 }
695 }
696 }},
697 {RPCResult::Type::NUM, "connections", "the total number of connections"},
698 {RPCResult::Type::NUM, "connections_in", "the number of inbound connections"},
699 {RPCResult::Type::NUM, "connections_out", "the number of outbound connections"},
700 {RPCResult::Type::BOOL, "networkactive", "whether p2p networking is enabled"},
701 {RPCResult::Type::ARR, "networks", "information per network",
702 {
703 {RPCResult::Type::OBJ, "", "",
704 {
705 {RPCResult::Type::STR, "name", "network (" + Join(GetNetworkNames(), ", ") + ")"},
706 {RPCResult::Type::BOOL, "limited", "is the network limited using -onlynet?"},
707 {RPCResult::Type::BOOL, "reachable", "is the network reachable?"},
708 {RPCResult::Type::STR, "proxy", "(\"host:port\") the proxy that is used for this network, or empty if none"},
709 {RPCResult::Type::BOOL, "proxy_randomize_credentials", "Whether randomized credentials are used"},
710 }},
711 }},
712 {RPCResult::Type::STR_AMOUNT, "relayfee", "minimum relay fee rate for transactions in " + CURRENCY_UNIT + "/kvB"},
713 {RPCResult::Type::STR_AMOUNT, "incrementalfee", "minimum fee rate increment for mempool limiting or replacement in " + CURRENCY_UNIT + "/kvB"},
714 {RPCResult::Type::ARR, "localaddresses", "list of local addresses",
715 {
716 {RPCResult::Type::OBJ, "", "",
717 {
718 {RPCResult::Type::STR, "address", "network address"},
719 {RPCResult::Type::NUM, "port", "network port"},
720 {RPCResult::Type::NUM, "score", "relative score"},
721 }},
722 }},
723 (IsDeprecatedRPCEnabled("warnings") ?
724 RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
725 RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
726 {
727 {RPCResult::Type::STR, "", "warning"},
728 }
729 }
730 ),
731 }
732 },
734 HelpExampleCli("getnetworkinfo", "")
735 + HelpExampleRpc("getnetworkinfo", "")
736 },
737 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
738{
739 LOCK(cs_main);
741 obj.pushKV("version", CLIENT_VERSION);
742 obj.pushKV("subversion", strSubVersion);
743 obj.pushKV("protocolversion",PROTOCOL_VERSION);
744 NodeContext& node = EnsureAnyNodeContext(request.context);
745 CConnman& connman = EnsureConnman(node);
746 ServiceFlags services = connman.GetLocalServices();
747 obj.pushKV("localservices", strprintf("%016x", services));
748 obj.pushKV("localservicesnames", GetServicesNames(services));
749 auto peerman_info{EnsurePeerman(node).GetInfo()};
750 obj.pushKV("localrelay", !peerman_info.ignores_incoming_txs);
751 obj.pushKV("timeoffset", Ticks<std::chrono::seconds>(peerman_info.median_outbound_time_offset));
752 obj.pushKV("tx_send_rate", peerman_info.tx_send_rate);
753 auto buckjson = [&](const auto& buckinfo) {
755 b.pushKV("backlog", buckinfo.backlog_count);
756 b.pushKV("count_tok", buckinfo.count_bucket);
757 b.pushKV("size_tok", buckinfo.size_bucket);
758 return b;
759 };
760 UniValue invbuckets{UniValue::VOBJ};
761 invbuckets.pushKV("inbound", buckjson(peerman_info.inbound_bucket));
762 invbuckets.pushKV("outbound", buckjson(peerman_info.outbound_bucket));
763 obj.pushKV("inv_buckets", invbuckets);
764 obj.pushKV("networkactive", connman.GetNetworkActive());
765 obj.pushKV("connections", connman.GetNodeCount(ConnectionDirection::Both));
766 obj.pushKV("connections_in", connman.GetNodeCount(ConnectionDirection::In));
767 obj.pushKV("connections_out", connman.GetNodeCount(ConnectionDirection::Out));
768 obj.pushKV("networks", GetNetworksInfo());
769 const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
770 // Those fields can be deprecated, to be replaced by the getmempoolinfo fields
771 obj.pushKV("relayfee", ValueFromAmount(mempool.m_opts.min_relay_feerate.GetFeePerK()));
772 obj.pushKV("incrementalfee", ValueFromAmount(mempool.m_opts.incremental_relay_feerate.GetFeePerK()));
773 UniValue localAddresses(UniValue::VARR);
774 {
776 for (const std::pair<const CNetAddr, LocalServiceInfo> &item : mapLocalHost)
777 {
779 rec.pushKV("address", item.first.ToStringAddr());
780 rec.pushKV("port", item.second.nPort);
781 rec.pushKV("score", item.second.nScore);
782 localAddresses.push_back(std::move(rec));
783 }
784 }
785 obj.pushKV("localaddresses", std::move(localAddresses));
786 obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
787 return obj;
788},
789 };
790}
791
793{
794 return RPCMethod{
795 "setban",
796 "Attempts to add or remove an IP/Subnet from the banned list.\n",
797 {
798 {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)"},
799 {"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"},
800 {"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)"},
801 {"absolute", RPCArg::Type::BOOL, RPCArg::Default{false}, "If set, the bantime must be an absolute timestamp expressed in " + UNIX_EPOCH_TIME},
802 },
805 HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
806 + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
807 + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400")
808 },
809 [](const RPCMethod& help, const JSONRPCRequest& request) -> UniValue
810{
811 auto command{help.Arg<std::string_view>("command")};
812 if (command != "add" && command != "remove") {
813 throw std::runtime_error(help.ToString());
814 }
815 NodeContext& node = EnsureAnyNodeContext(request.context);
816 BanMan& banman = EnsureBanman(node);
817
818 CSubNet subNet;
819 CNetAddr netAddr;
820 std::string subnet_arg{help.Arg<std::string_view>("subnet")};
821 const bool isSubnet{subnet_arg.find('/') != subnet_arg.npos};
822
823 if (!isSubnet) {
824 const std::optional<CNetAddr> addr{LookupHost(subnet_arg, false)};
825 if (addr.has_value()) {
826 netAddr = static_cast<CNetAddr>(MaybeFlipIPv6toCJDNS(CService{addr.value(), /*port=*/0}));
827 }
828 } else {
829 subNet = LookupSubNet(subnet_arg);
830 }
831
832 if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) {
833 throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Invalid IP/Subnet");
834 }
835
836 if (command == "add") {
837 if (isSubnet ? banman.IsBanned(subNet) : banman.IsBanned(netAddr)) {
838 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
839 }
840
841 int64_t banTime = 0; //use standard bantime if not specified
842 if (!request.params[2].isNull())
843 banTime = request.params[2].getInt<int64_t>();
844
845 const bool absolute{request.params[3].isNull() ? false : request.params[3].get_bool()};
846
847 if (absolute && banTime < GetTime()) {
848 throw JSONRPCError(RPC_INVALID_PARAMETER, "Error: Absolute timestamp is in the past");
849 }
850
851 if (isSubnet) {
852 banman.Ban(subNet, banTime, absolute);
853 if (node.connman) {
854 node.connman->DisconnectNode(subNet);
855 }
856 } else {
857 banman.Ban(netAddr, banTime, absolute);
858 if (node.connman) {
859 node.connman->DisconnectNode(netAddr);
860 }
861 }
862 } else if(command == "remove") {
863 if (!( isSubnet ? banman.Unban(subNet) : banman.Unban(netAddr) )) {
864 throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Unban failed. Requested address/subnet was not previously manually banned.");
865 }
866 }
867 return UniValue::VNULL;
868},
869 };
870}
871
873{
874 return RPCMethod{
875 "listbanned",
876 "List all manually banned IPs/Subnets.\n",
877 {},
879 {
880 {RPCResult::Type::OBJ, "", "",
881 {
882 {RPCResult::Type::STR, "address", "The IP/Subnet of the banned node"},
883 {RPCResult::Type::NUM_TIME, "ban_created", "The " + UNIX_EPOCH_TIME + " the ban was created"},
884 {RPCResult::Type::NUM_TIME, "banned_until", "The " + UNIX_EPOCH_TIME + " the ban expires"},
885 {RPCResult::Type::NUM_TIME, "ban_duration", "The ban duration, in seconds"},
886 {RPCResult::Type::NUM_TIME, "time_remaining", "The time remaining until the ban expires, in seconds"},
887 }},
888 }},
890 HelpExampleCli("listbanned", "")
891 + HelpExampleRpc("listbanned", "")
892 },
893 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
894{
895 BanMan& banman = EnsureAnyBanman(request.context);
896
897 banmap_t banMap;
898 banman.GetBanned(banMap);
899 const int64_t current_time{GetTime()};
900
901 UniValue bannedAddresses(UniValue::VARR);
902 for (const auto& entry : banMap)
903 {
904 const CBanEntry& banEntry = entry.second;
906 rec.pushKV("address", entry.first.ToString());
907 rec.pushKV("ban_created", banEntry.nCreateTime);
908 rec.pushKV("banned_until", banEntry.nBanUntil);
909 rec.pushKV("ban_duration", (banEntry.nBanUntil - banEntry.nCreateTime));
910 rec.pushKV("time_remaining", (banEntry.nBanUntil - current_time));
911
912 bannedAddresses.push_back(std::move(rec));
913 }
914
915 return bannedAddresses;
916},
917 };
918}
919
921{
922 return RPCMethod{
923 "clearbanned",
924 "Clear all banned IPs.\n",
925 {},
928 HelpExampleCli("clearbanned", "")
929 + HelpExampleRpc("clearbanned", "")
930 },
931 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
932{
933 BanMan& banman = EnsureAnyBanman(request.context);
934
935 banman.ClearBanned();
936
937 return UniValue::VNULL;
938},
939 };
940}
941
943{
944 return RPCMethod{
945 "setnetworkactive",
946 "Disable/enable all p2p network activity.\n",
947 {
948 {"state", RPCArg::Type::BOOL, RPCArg::Optional::NO, "true to enable networking, false to disable"},
949 },
950 RPCResult{RPCResult::Type::BOOL, "", "The value that was passed in"},
951 RPCExamples{""},
952 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
953{
954 NodeContext& node = EnsureAnyNodeContext(request.context);
955 CConnman& connman = EnsureConnman(node);
956
957 connman.SetNetworkActive(request.params[0].get_bool());
958
959 return connman.GetNetworkActive();
960},
961 };
962}
963
965{
966 return RPCMethod{"getnodeaddresses",
967 "Return known addresses, after filtering for quality and recency.\n"
968 "These can potentially be used to find new peers in the network.\n"
969 "The total number of addresses known to the node may be higher.",
970 {
971 {"count", RPCArg::Type::NUM, RPCArg::Default{1}, "The maximum number of addresses to return. Specify 0 to return all known addresses."},
972 {"network", RPCArg::Type::STR, RPCArg::DefaultHint{"all networks"}, "Return only addresses of the specified network. Can be one of: " + Join(GetNetworkNames(), ", ") + "."},
973 },
974 RPCResult{
975 RPCResult::Type::ARR, "", "",
976 {
977 {RPCResult::Type::OBJ, "", "",
978 {
979 {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"},
980 {RPCResult::Type::NUM, "services", "The services offered by the node"},
981 {RPCResult::Type::STR, "address", "The address of the node"},
982 {RPCResult::Type::NUM, "port", "The port number of the node"},
983 {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") the node connected through"},
984 }},
985 }
986 },
988 HelpExampleCli("getnodeaddresses", "8")
989 + HelpExampleCli("getnodeaddresses", "4 \"i2p\"")
990 + HelpExampleCli("-named getnodeaddresses", "network=onion count=12")
991 + HelpExampleRpc("getnodeaddresses", "8")
992 + HelpExampleRpc("getnodeaddresses", "4, \"i2p\"")
993 },
994 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
995{
996 NodeContext& node = EnsureAnyNodeContext(request.context);
997 const CConnman& connman = EnsureConnman(node);
998
999 const int count{request.params[0].isNull() ? 1 : request.params[0].getInt<int>()};
1000 if (count < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
1001
1002 const std::optional<Network> network{request.params[1].isNull() ? std::nullopt : std::optional<Network>{ParseNetwork(request.params[1].get_str())}};
1003 if (network == NET_UNROUTABLE) {
1004 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Network not recognized: %s", request.params[1].get_str()));
1005 }
1006
1007 // returns a shuffled list of CAddress
1008 const std::vector<CAddress> vAddr{connman.GetAddressesUnsafe(count, /*max_pct=*/0, network)};
1010
1011 for (const CAddress& addr : vAddr) {
1013 obj.pushKV("time", TicksSinceEpoch<std::chrono::seconds>(addr.nTime));
1014 obj.pushKV("services", static_cast<std::underlying_type_t<decltype(addr.nServices)>>(addr.nServices));
1015 obj.pushKV("address", addr.ToStringAddr());
1016 obj.pushKV("port", addr.GetPort());
1017 obj.pushKV("network", GetNetworkName(addr.GetNetClass()));
1018 ret.push_back(std::move(obj));
1019 }
1020 return ret;
1021},
1022 };
1023}
1024
1026{
1027 return RPCMethod{"addpeeraddress",
1028 "Add the address of a potential peer to an address manager table. This RPC is for testing only.",
1029 {
1030 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address of the peer"},
1031 {"port", RPCArg::Type::NUM, RPCArg::Optional::NO, "The port of the peer"},
1032 {"tried", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, attempt to add the peer to the tried addresses table"},
1033 },
1034 RPCResult{
1035 RPCResult::Type::OBJ, "", "",
1036 {
1037 {RPCResult::Type::BOOL, "success", "whether the peer address was successfully added to the address manager table"},
1038 {RPCResult::Type::STR, "error", /*optional=*/true, "error description, if the address could not be added"},
1039 },
1040 },
1042 HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 8333 true")
1043 + HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 8333, true")
1044 },
1045 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
1046{
1047 AddrMan& addrman = EnsureAnyAddrman(request.context);
1048
1049 const std::string& addr_string{request.params[0].get_str()};
1050 const auto port{request.params[1].getInt<uint16_t>()};
1051 const bool tried{request.params[2].isNull() ? false : request.params[2].get_bool()};
1052
1054 std::optional<CNetAddr> net_addr{LookupHost(addr_string, false)};
1055 if (!net_addr.has_value()) {
1056 throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Invalid IP address");
1057 }
1058
1059 bool success{false};
1060
1061 CService service{net_addr.value(), port};
1063 address.nTime = Now<NodeSeconds>();
1064 // The source address is set equal to the address. This is equivalent to the peer
1065 // announcing itself.
1066 if (addrman.Add({address}, address)) {
1067 success = true;
1068 if (tried) {
1069 // Attempt to move the address to the tried addresses table.
1070 if (!addrman.Good(address)) {
1071 success = false;
1072 obj.pushKV("error", "failed-adding-to-tried");
1073 }
1074 }
1075 } else {
1076 obj.pushKV("error", "failed-adding-to-new");
1077 }
1078
1079 obj.pushKV("success", success);
1080 return obj;
1081},
1082 };
1083}
1084
1086{
1087 return RPCMethod{
1088 "sendmsgtopeer",
1089 "Send a p2p message to a peer specified by id.\n"
1090 "The message type and body must be provided, the message header will be generated.\n"
1091 "This RPC is for testing only.",
1092 {
1093 {"peer_id", RPCArg::Type::NUM, RPCArg::Optional::NO, "The peer to send the message to."},
1094 {"msg_type", RPCArg::Type::STR, RPCArg::Optional::NO, strprintf("The message type (maximum length %i)", CMessageHeader::MESSAGE_TYPE_SIZE)},
1095 {"msg", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The serialized message body to send, in hex, without a message header"},
1096 },
1097 RPCResult{RPCResult::Type::OBJ, "", "", std::vector<RPCResult>{}},
1099 HelpExampleCli("sendmsgtopeer", "0 \"addr\" \"ffffff\"") + HelpExampleRpc("sendmsgtopeer", R"(0, "addr", "ffffff")")},
1100 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {
1101 const NodeId peer_id{request.params[0].getInt<int64_t>()};
1102 const auto msg_type{self.Arg<std::string_view>("msg_type")};
1103 if (msg_type.size() > CMessageHeader::MESSAGE_TYPE_SIZE) {
1104 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Error: msg_type too long, max length is %i", CMessageHeader::MESSAGE_TYPE_SIZE));
1105 }
1106 auto msg{TryParseHex<unsigned char>(self.Arg<std::string_view>("msg"))};
1107 if (!msg.has_value()) {
1108 throw JSONRPCError(RPC_INVALID_PARAMETER, "Error parsing input for msg");
1109 }
1110
1111 NodeContext& node = EnsureAnyNodeContext(request.context);
1112 CConnman& connman = EnsureConnman(node);
1113
1114 CSerializedNetMsg msg_ser;
1115 msg_ser.data = msg.value();
1116 msg_ser.m_type = msg_type;
1117
1118 bool success = connman.ForNode(peer_id, [&](CNode* node) {
1119 connman.PushMessage(node, std::move(msg_ser));
1120 return true;
1121 });
1122
1123 if (!success) {
1124 throw JSONRPCError(RPC_MISC_ERROR, "Error: Could not send message to peer");
1125 }
1126
1128 return ret;
1129 },
1130 };
1131}
1132
1134{
1135 return RPCMethod{
1136 "getaddrmaninfo",
1137 "Provides information about the node's address manager by returning the number of "
1138 "addresses in the `new` and `tried` tables and their sum for all networks.\n",
1139 {},
1140 RPCResult{
1141 RPCResult::Type::OBJ_DYN, "", "json object with network type as keys", {
1142 {RPCResult::Type::OBJ, "network", "the network (" + Join(GetNetworkNames(), ", ") + ", all_networks)", {
1143 {RPCResult::Type::NUM, "new", "number of addresses in the new table, which represent potential peers the node has discovered but hasn't yet successfully connected to."},
1144 {RPCResult::Type::NUM, "tried", "number of addresses in the tried table, which represent peers the node has successfully connected to in the past."},
1145 {RPCResult::Type::NUM, "total", "total number of addresses in both new/tried tables"},
1146 }},
1147 }},
1148 RPCExamples{HelpExampleCli("getaddrmaninfo", "") + HelpExampleRpc("getaddrmaninfo", "")},
1149 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {
1150 AddrMan& addrman = EnsureAnyAddrman(request.context);
1151
1153 for (int n = 0; n < NET_MAX; ++n) {
1154 enum Network network = static_cast<enum Network>(n);
1155 if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
1157 obj.pushKV("new", addrman.Size(network, true));
1158 obj.pushKV("tried", addrman.Size(network, false));
1159 obj.pushKV("total", addrman.Size(network));
1160 ret.pushKV(GetNetworkName(network), std::move(obj));
1161 }
1163 obj.pushKV("new", addrman.Size(std::nullopt, true));
1164 obj.pushKV("tried", addrman.Size(std::nullopt, false));
1165 obj.pushKV("total", addrman.Size());
1166 ret.pushKV("all_networks", std::move(obj));
1167 return ret;
1168 },
1169 };
1170}
1171
1173{
1174 return RPCMethod{
1175 "exportasmap",
1176 "Export the embedded ASMap data to a file. Any existing file at the path will be overwritten.\n",
1177 {
1178 {"path", RPCArg::Type::STR, RPCArg::Optional::NO, "Path to the output file. If relative, will be prefixed by datadir."},
1179 },
1180 RPCResult{
1181 RPCResult::Type::OBJ, "", "",
1182 {
1183 {RPCResult::Type::STR, "path", "the absolute path that the ASMap data was written to"},
1184 {RPCResult::Type::NUM, "bytes_written", "the number of bytes written to the file"},
1185 {RPCResult::Type::STR_HEX, "file_hash", "the SHA256 hash of the exported ASMap data"},
1186 }
1187 },
1189 HelpExampleCli("exportasmap", "\"asmap.dat\"") + HelpExampleRpc("exportasmap", "\"asmap.dat\"")},
1190 [&](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {
1191#ifndef ENABLE_EMBEDDED_ASMAP
1192 throw JSONRPCError(RPC_MISC_ERROR, "No embedded ASMap data available");
1193#else
1194 if (node::data::ip_asn.empty() || !CheckStandardAsmap(node::data::ip_asn)) {
1195 throw JSONRPCError(RPC_MISC_ERROR, "Embedded ASMap data appears to be corrupted");
1196 }
1197
1198 const ArgsManager& args{EnsureAnyArgsman(request.context)};
1199 const fs::path export_path{fsbridge::AbsPathJoin(args.GetDataDirNet(), fs::u8path(self.Arg<std::string_view>("path")))};
1200
1201 AutoFile file{fsbridge::fopen(export_path, "wb")};
1202 if (file.IsNull()) {
1203 throw JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to open asmap file: %s", fs::PathToString(export_path)));
1204 }
1205
1206 file << node::data::ip_asn;
1207
1208 if (file.fclose() != 0) {
1209 throw JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to close asmap file: %s", fs::PathToString(export_path)));
1210 }
1211
1212 HashWriter hasher;
1213 hasher.write(node::data::ip_asn);
1214
1215 UniValue result(UniValue::VOBJ);
1216 result.pushKV("path", export_path.utf8string());
1217 result.pushKV("bytes_written", node::data::ip_asn.size());
1218 result.pushKV("file_hash", HexStr(hasher.GetSHA256()));
1219 return result;
1220#endif
1221 },
1222 };
1223}
1224
1225UniValue AddrmanEntryToJSON(const AddrInfo& info, const CConnman& connman)
1226{
1228 ret.pushKV("address", info.ToStringAddr());
1229 const uint32_t mapped_as{connman.GetMappedAS(info)};
1230 if (mapped_as) {
1231 ret.pushKV("mapped_as", mapped_as);
1232 }
1233 ret.pushKV("port", info.GetPort());
1234 ret.pushKV("services", static_cast<std::underlying_type_t<decltype(info.nServices)>>(info.nServices));
1235 ret.pushKV("time", TicksSinceEpoch<std::chrono::seconds>(info.nTime));
1236 ret.pushKV("network", GetNetworkName(info.GetNetClass()));
1237 ret.pushKV("source", info.source.ToStringAddr());
1238 ret.pushKV("source_network", GetNetworkName(info.source.GetNetClass()));
1239 const uint32_t source_mapped_as{connman.GetMappedAS(info.source)};
1240 if (source_mapped_as) {
1241 ret.pushKV("source_mapped_as", source_mapped_as);
1242 }
1243 return ret;
1244}
1245
1246UniValue AddrmanTableToJSON(const std::vector<std::pair<AddrInfo, AddressPosition>>& tableInfos, const CConnman& connman)
1247{
1248 UniValue table(UniValue::VOBJ);
1249 for (const auto& e : tableInfos) {
1250 AddrInfo info = e.first;
1251 AddressPosition location = e.second;
1252 std::ostringstream key;
1253 key << location.bucket << "/" << location.position;
1254 // Address manager tables have unique entries so there is no advantage
1255 // in using UniValue::pushKV, which checks if the key already exists
1256 // in O(N). UniValue::pushKVEnd is used instead which currently is O(1).
1257 table.pushKVEnd(key.str(), AddrmanEntryToJSON(info, connman));
1258 }
1259 return table;
1260}
1261
1263{
1264 return RPCMethod{"getrawaddrman",
1265 "EXPERIMENTAL warning: this call may be changed in future releases.\n"
1266 "\nReturns information on all address manager entries for the new and tried tables.\n",
1267 {},
1268 RPCResult{
1269 RPCResult::Type::OBJ_DYN, "", "", {
1270 {RPCResult::Type::OBJ_DYN, "table", "buckets with addresses in the address manager table ( new, tried )", {
1271 {RPCResult::Type::OBJ, "bucket/position", "the location in the address manager table (<bucket>/<position>)", {
1272 {RPCResult::Type::STR, "address", "The address of the node"},
1273 {RPCResult::Type::NUM, "mapped_as", /*optional=*/true, "Mapped AS (Autonomous System) number at the end of the BGP route to the peer, used for diversifying peer selection (only displayed if the -asmap config option is set)"},
1274 {RPCResult::Type::NUM, "port", "The port number of the node"},
1275 {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") of the address"},
1276 {RPCResult::Type::NUM, "services", "The services offered by the node"},
1277 {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"},
1278 {RPCResult::Type::STR, "source", "The address that relayed the address to us"},
1279 {RPCResult::Type::STR, "source_network", "The network (" + Join(GetNetworkNames(), ", ") + ") of the source address"},
1280 {RPCResult::Type::NUM, "source_mapped_as", /*optional=*/true, "Mapped AS (Autonomous System) number at the end of the BGP route to the source, used for diversifying peer selection (only displayed if the -asmap config option is set)"}
1281 }}
1282 }}
1283 }
1284 },
1286 HelpExampleCli("getrawaddrman", "")
1287 + HelpExampleRpc("getrawaddrman", "")
1288 },
1289 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {
1290 AddrMan& addrman = EnsureAnyAddrman(request.context);
1291 NodeContext& node_context = EnsureAnyNodeContext(request.context);
1292 CConnman& connman = EnsureConnman(node_context);
1293
1295 ret.pushKV("new", AddrmanTableToJSON(addrman.GetEntries(false), connman));
1296 ret.pushKV("tried", AddrmanTableToJSON(addrman.GetEntries(true), connman));
1297 return ret;
1298 },
1299 };
1300}
1301
1303{
1304 static const CRPCCommand commands[]{
1305 {"network", &getconnectioncount},
1306 {"network", &ping},
1307 {"network", &getpeerinfo},
1308 {"network", &addnode},
1309 {"network", &disconnectnode},
1310 {"network", &getaddednodeinfo},
1311 {"network", &getnettotals},
1312 {"network", &getnetworkinfo},
1313 {"network", &setban},
1314 {"network", &listbanned},
1315 {"network", &clearbanned},
1316 {"network", &setnetworkactive},
1317 {"network", &getnodeaddresses},
1318 {"network", &getaddrmaninfo},
1319 {"network", &exportasmap},
1320 {"hidden", &addconnection},
1321 {"hidden", &addpeeraddress},
1322 {"hidden", &sendmsgtopeer},
1323 {"hidden", &getrawaddrman},
1324 };
1325 for (const auto& c : commands) {
1326 t.appendCommand(c.name, &c);
1327 }
1328}
int ret
const auto command
ArgsManager & args
Definition: bitcoind.cpp:280
const CChainParams & Params()
Return the currently selected parameters.
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:112
Extended statistics about a CAddress.
Definition: addrman_impl.h:46
CNetAddr source
where knowledge about this address first came from
Definition: addrman_impl.h:55
Stochastic address manager.
Definition: addrman.h:110
size_t Size(std::optional< Network > net=std::nullopt, std::optional< bool > in_new=std::nullopt) const
Return size information about addrman.
Definition: addrman.cpp:1279
std::vector< std::pair< AddrInfo, AddressPosition > > GetEntries(bool from_tried) const
Returns an information-location pair for all addresses in the selected addrman table.
Definition: addrman.cpp:1319
bool Good(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
Mark an address record as accessible and attempt to move it to addrman's tried table.
Definition: addrman.cpp:1289
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty=0s)
Attempt to add one or more addresses to addrman's new table.
Definition: addrman.cpp:1284
fs::path GetDataDirNet() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get data directory path with appended network identifier.
Definition: args.cpp:328
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:395
Definition: banman.h:64
void Ban(const CNetAddr &net_addr, int64_t ban_time_offset=0, bool since_unix_epoch=false) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Definition: banman.cpp:118
bool IsBanned(const CNetAddr &net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Return whether net_addr is banned.
Definition: banman.cpp:89
void GetBanned(banmap_t &banmap) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Definition: banman.cpp:174
void ClearBanned() EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Definition: banman.cpp:72
bool Unban(const CNetAddr &net_addr) EXCLUSIVE_LOCKS_REQUIRED(!m_banned_mutex)
Definition: banman.cpp:156
A CService with information about it as peer.
Definition: protocol.h:387
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
Definition: protocol.h:479
NodeSeconds nTime
Always included in serialization. The behavior is unspecified if the value is not representable as ui...
Definition: protocol.h:477
Definition: net_types.h:15
int64_t nCreateTime
Definition: net_types.h:19
int64_t nBanUntil
Definition: net_types.h:20
ChainType GetChainType() const
Return the chain type.
Definition: chainparams.h:111
Definition: net.h:1085
bool GetNetworkActive() const
Definition: net.h:1183
bool OutboundTargetReached(bool historicalBlockServingLimit) const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
Definition: net.cpp:4016
uint64_t GetMaxOutboundTarget() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
Definition: net.cpp:3982
bool AddConnection(const std::string &address, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex
Attempts to open a connection.
Definition: net.cpp:1894
std::chrono::seconds GetMaxOutboundTimeframe() const
Definition: net.cpp:3989
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
Definition: net.cpp:4059
bool AddNode(const AddedNodeParams &add) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:3833
std::vector< AddedNodeInfo > GetAddedNodeInfo(bool include_connected) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
Definition: net.cpp:2991
uint32_t GetMappedAS(const CNetAddr &addr) const
Definition: net.cpp:3893
uint64_t GetTotalBytesRecv() const
Definition: net.cpp:4047
bool OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CountingSemaphoreGrant<> &&grant_outbound, const char *pszDest, ConnectionType conn_type, bool use_v2transport, const std::optional< Proxy > &proxy_override) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex
Open a new P2P connection and initialize it with the PeerManager at m_msgproc.
Definition: net.cpp:3091
void SetNetworkActive(bool active)
Definition: net.cpp:3453
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
Definition: net.cpp:3994
void GetNodeStats(std::vector< CNodeStats > &vstats) const EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
Definition: net.cpp:3898
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
Definition: net.cpp:4224
std::vector< CAddress > GetAddressesUnsafe(size_t max_addresses, size_t max_pct, std::optional< Network > network, bool filtered=true) const
Return randomly selected addresses.
Definition: net.cpp:3784
bool DisconnectNode(std::string_view node) EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
Definition: net.cpp:3912
uint64_t GetTotalBytesSent() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
Definition: net.cpp:4052
size_t GetNodeCount(ConnectionDirection) const EXCLUSIVE_LOCKS_REQUIRED(!m_nodes_mutex)
Definition: net.cpp:3870
uint64_t GetOutboundTargetBytesLeft() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
Definition: net.cpp:4037
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
Definition: net.cpp:4164
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
Definition: feerate.h:71
static constexpr size_t MESSAGE_TYPE_SIZE
Definition: protocol.h:31
Network address.
Definition: netaddress.h:113
Network GetNetClass() const
Definition: netaddress.cpp:680
std::string ToStringAddr() const
Definition: netaddress.cpp:586
bool IsValid() const
Definition: netaddress.cpp:430
Information about a peer.
Definition: net.h:683
std::atomic< NodeClock::duration > m_min_ping_time
Lowest measured round-trip duration.
Definition: net.h:912
RPC command dispatcher.
Definition: server.h:89
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:531
uint16_t GetPort() const
Definition: netaddress.cpp:841
bool IsValid() const
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:187
const Options m_opts
Definition: txmempool.h:301
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:109
uint256 GetSHA256()
Compute the SHA256 hash of all data written to this object.
Definition: hash.h:134
void write(std::span< const std::byte > src)
Definition: hash.h:114
static std::vector< std::string > ToStrings(NetPermissionFlags flags)
virtual void SendPings()=0
Send ping message to all peers.
virtual PeerManagerInfo GetInfo() const =0
Get peer manager info.
virtual bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) const =0
Get statistics from node state.
auto MaybeArg(std::string_view key) const
Helper to get an optional request argument.
Definition: util.h:502
std::string ToString() const
Definition: util.cpp:779
auto Arg(std::string_view key) const
Helper to get a required or default-valued request argument.
Definition: util.h:470
bool Contains(Network net) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Definition: netbase.h:134
void push_back(UniValue val)
Definition: univalue.cpp:103
@ VNULL
Definition: univalue.h:24
@ VOBJ
Definition: univalue.h:24
@ VARR
Definition: univalue.h:24
void pushKVEnd(std::string key, UniValue val)
Definition: univalue.cpp:117
Int getInt() const
Definition: univalue.h:143
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:125
constexpr int CLIENT_VERSION
Definition: clientversion.h:26
std::string TransportTypeAsString(TransportProtocolType transport_type)
Convert TransportProtocolType enum to a string value.
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
ConnectionType
Different types of connections to a peer.
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
UniValue ValueFromAmount(const CAmount amount)
Definition: core_io.cpp:283
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:8
const std::string CURRENCY_UNIT
Definition: feerate.h:19
static path u8path(std::string_view utf8_str)
Definition: fs.h:80
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:160
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:30
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:23
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:32
Definition: messages.h:21
UniValue GetWarningsForRpc(const Warnings &warnings, bool use_deprecated)
RPC helper function that wraps warnings.GetMessages().
Definition: warnings.cpp:54
std::string_view TrimStringView(std::string_view str LIFETIMEBOUND, std::string_view pattern=" \f\n\r\t\v")
Definition: string.h:163
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition: string.h:209
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:121
const std::string NET_MESSAGE_TYPE_OTHER
Definition: net.cpp:109
GlobalMutex g_maplocalhost_mutex
Definition: net.cpp:119
constexpr int MAX_ADDNODE_CONNECTIONS
Maximum number of addnode outgoing nodes.
Definition: net.h:71
int64_t NodeId
Definition: net.h:105
const std::vector< std::string > NET_PERMISSIONS_DOC
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:41
Network
A network type.
Definition: netaddress.h:33
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:57
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:35
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:54
CSubNet LookupSubNet(const std::string &subnet_str)
Parse and resolve a specified subnet string into the appropriate internal representation.
Definition: netbase.cpp:831
std::vector< CNetAddr > LookupHost(const std::string &name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
Definition: netbase.cpp:173
std::string GetNetworkName(enum Network net)
Definition: netbase.cpp:114
enum Network ParseNetwork(const std::string &net_in)
Definition: netbase.cpp:100
CService MaybeFlipIPv6toCJDNS(const CService &service)
If an IPv6 address belongs to the address range used by the CJDNS network and the CJDNS network is re...
Definition: netbase.cpp:961
ReachableNets g_reachable_nets
Definition: netbase.cpp:43
std::optional< Proxy > GetProxy(enum Network net)
Definition: netbase.cpp:726
std::vector< std::string > GetNetworkNames(bool append_unroutable)
Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE.
Definition: netbase.cpp:130
std::vector< std::string > serviceFlagsToStr(uint64_t flags)
Convert service flags (a bitmask of NODE_*) to human readable strings.
Definition: protocol.cpp:108
ServiceFlags
nServices flags
Definition: protocol.h:321
@ NODE_P2P_V2
Definition: protocol.h:342
@ NODE_WITNESS
Definition: protocol.h:332
@ NODE_NETWORK
Definition: protocol.h:327
constexpr int PROTOCOL_VERSION
network protocol versioning
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:75
const std::vector< std::string > CONNECTION_TYPE_DOC
Definition: net.cpp:69
void RegisterNetRPCCommands(CRPCTable &t)
Definition: net.cpp:1302
static RPCMethod disconnectnode()
Definition: net.cpp:477
static RPCMethod addpeeraddress()
Definition: net.cpp:1025
static RPCMethod addnode()
Definition: net.cpp:339
static RPCMethod getrawaddrman()
Definition: net.cpp:1262
static RPCMethod getaddednodeinfo()
Definition: net.cpp:523
static RPCMethod getnetworkinfo()
Definition: net.cpp:669
static RPCMethod getaddrmaninfo()
Definition: net.cpp:1133
static RPCMethod listbanned()
Definition: net.cpp:872
static UniValue GetNetworksInfo()
Definition: net.cpp:647
static RPCMethod clearbanned()
Definition: net.cpp:920
UniValue AddrmanTableToJSON(const std::vector< std::pair< AddrInfo, AddressPosition > > &tableInfos, const CConnman &connman)
Definition: net.cpp:1246
static RPCMethod exportasmap()
Definition: net.cpp:1172
const std::vector< std::string > TRANSPORT_TYPE_DOC
Definition: net.cpp:79
static UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: net.cpp:134
static RPCMethod sendmsgtopeer()
Definition: net.cpp:1085
static RPCMethod getconnectioncount()
Definition: net.cpp:85
static RPCMethod getnodeaddresses()
Definition: net.cpp:964
static RPCMethod setban()
Definition: net.cpp:792
static RPCMethod getnettotals()
Definition: net.cpp:597
static RPCMethod addconnection()
Definition: net.cpp:414
static RPCMethod setnetworkactive()
Definition: net.cpp:942
UniValue AddrmanEntryToJSON(const AddrInfo &info, const CConnman &connman)
Definition: net.cpp:1225
static RPCMethod ping()
Definition: net.cpp:108
static RPCMethod getpeerinfo()
Definition: net.cpp:145
@ RPC_CLIENT_NODE_NOT_CONNECTED
Node to disconnect not found in connected nodes.
Definition: protocol.h:88
@ RPC_CLIENT_INVALID_IP_OR_SUBNET
Invalid IP/Subnet.
Definition: protocol.h:89
@ RPC_MISC_ERROR
General application defined errors.
Definition: protocol.h:65
@ RPC_CLIENT_NODE_ALREADY_ADDED
Node is already added.
Definition: protocol.h:86
@ RPC_INVALID_PARAMS
Definition: protocol.h:58
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:69
@ RPC_CLIENT_NODE_NOT_ADDED
Node has not been added before.
Definition: protocol.h:87
@ RPC_CLIENT_NODE_CAPACITY_REACHED
Max number of outbound or block-relay connections already open.
Definition: protocol.h:91
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:188
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:206
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:48
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:716
static RPCMethod help()
Definition: server.cpp:127
BanMan & EnsureBanman(const NodeContext &node)
Definition: server_util.cpp:51
AddrMan & EnsureAnyAddrman(const std::any &context)
NodeContext & EnsureAnyNodeContext(const std::any &context)
Definition: server_util.cpp:28
BanMan & EnsureAnyBanman(const std::any &context)
Definition: server_util.cpp:59
PeerManager & EnsurePeerman(const NodeContext &node)
CTxMemPool & EnsureAnyMemPool(const std::any &context)
Definition: server_util.cpp:45
CConnman & EnsureConnman(const NodeContext &node)
ArgsManager & EnsureAnyArgsman(const std::any &context)
Definition: server_util.cpp:72
Location information for an address in AddrMan.
Definition: addrman.h:59
const int bucket
Definition: addrman.h:72
const int position
Definition: addrman.h:73
NodeClock::duration m_ping_wait
std::vector< int > vHeightInFlight
CAmount m_fee_filter_received
std::chrono::seconds time_offset
uint64_t m_addr_rate_limited
uint64_t m_last_inv_seq
uint64_t m_addr_processed
int64_t presync_height
ServiceFlags their_services
std::string m_type
Definition: net.h:139
std::vector< unsigned char > data
Definition: net.h:138
@ STR_HEX
Special type that is a STR with only hex chars.
std::string DefaultHint
Hint for default value.
Definition: util.h:220
@ NO
Required arg.
@ NUM_TIME
Special numeric to denote unix epoch time.
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
@ STR_AMOUNT
Special string to represent a floating point amount.
CFeeRate incremental_relay_feerate
CFeeRate min_relay_feerate
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
NodeContext struct containing references to chain state and connection state.
Definition: context.h:59
#define LOCK(cs)
Definition: sync.h:268
static int count
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
bool CheckStandardAsmap(const std::span< const std::byte > data)
Provides a safe interface for validating ASMap data before use.
Definition: asmap.cpp:308
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition: time.cpp:88
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:97