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