6 #include <bitcoin-build-config.h> 41 #include <event2/buffer.h> 42 #include <event2/keyvalq_struct.h> 63 static constexpr std::array
NETWORKS{
"not_publicly_routable",
"ipv4",
"ipv6",
"onion",
"i2p",
"cjdns",
"internal"};
64 static constexpr std::array
NETWORK_SHORT_NAMES{
"npr",
"ipv4",
"ipv6",
"onion",
"i2p",
"cjdns",
"int"};
86 argsman.
AddArg(
"-generate",
87 strprintf(
"Generate blocks, equivalent to RPC getnewaddress followed by RPC generatetoaddress. Optional positional integer " 88 "arguments are number of blocks to generate (default: %s) and maximum iterations to try (default: %s), equivalent to " 89 "RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000",
93 argsman.
AddArg(
"-getinfo",
"Get general information from the remote server. Note that unlike server-side RPC calls, the output of -getinfo is the result of multiple non-atomic requests. Some entries in the output may represent results from different states (e.g. wallet balance may be as of a different block from the chain state reported)",
ArgsManager::ALLOW_ANY,
OptionsCategory::CLI_COMMANDS);
94 argsman.
AddArg(
"-netinfo",
strprintf(
"Get network peer connection information from the remote server. An optional argument from 0 to %d can be passed for different peers listings (default: 0). If a non-zero value is passed, an additional \"outonly\" (or \"o\") argument can be passed to see outbound peers only. Pass \"help\" (or \"h\") for detailed help documentation.",
NETINFO_MAX_LEVEL),
ArgsManager::ALLOW_ANY,
OptionsCategory::CLI_COMMANDS);
103 argsman.
AddArg(
"-rpcport=<port>",
strprintf(
"Connect to JSON-RPC on <port> (default: %u, testnet: %u, testnet4: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), testnet4BaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()),
ArgsManager::ALLOW_ANY |
ArgsManager::NETWORK_ONLY,
OptionsCategory::OPTIONS);
107 argsman.
AddArg(
"-rpcwallet=<walletname>",
"Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to bitcoind). This changes the RPC endpoint used, e.g. http://127.0.0.1:8332/wallet/<walletname>",
ArgsManager::ALLOW_ANY,
OptionsCategory::OPTIONS);
108 argsman.
AddArg(
"-stdin",
"Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). When combined with -stdinrpcpass, the first line from standard input is used for the RPC password.",
ArgsManager::ALLOW_ANY,
OptionsCategory::OPTIONS);
109 argsman.
AddArg(
"-stdinrpcpass",
"Read RPC password from standard input as a single line. When combined with -stdin, the first line from standard input is used for the RPC password. When combined with -stdinwalletpassphrase, -stdinrpcpass consumes the first line, and -stdinwalletpassphrase consumes the second.",
ArgsManager::ALLOW_ANY,
OptionsCategory::OPTIONS);
124 if (severity >= EVENT_LOG_ERR) {
125 throw std::runtime_error(
strprintf(
"libevent error: %s",
msg));
152 tfm::format(std::cerr,
"Error parsing command line arguments: %s\n", error);
156 std::string strUsage = CLIENT_NAME
" RPC client version " +
FormatFullVersion() +
"\n";
162 "The bitcoin-cli utility provides a command line interface to interact with a " CLIENT_NAME
" RPC server.\n" 163 "\nIt can be used to query network information, manage wallets, create or broadcast transactions, and control the " CLIENT_NAME
" server.\n" 164 "\nUse the \"help\" command to list all commands. Use \"help <command>\" to show help for that command.\n" 165 "The -named option allows you to specify parameters using the key=value format, eliminating the need to pass unused positional parameters.\n" 167 "Usage: bitcoin-cli [options] <command> [params]\n" 168 "or: bitcoin-cli [options] -named <command> [name=value]...\n" 169 "or: bitcoin-cli [options] help\n" 170 "or: bitcoin-cli [options] help <command>\n" 177 tfm::format(std::cerr,
"Error: too few parameters\n");
183 tfm::format(std::cerr,
"Error: Specified data directory \"%s\" does not exist.\n",
gArgs.
GetArg(
"-datadir",
""));
187 tfm::format(std::cerr,
"Error reading configuration file: %s\n", error);
193 }
catch (
const std::exception& e) {
214 case EVREQ_HTTP_TIMEOUT:
215 return "timeout reached";
217 return "EOF reached";
218 case EVREQ_HTTP_INVALID_HEADER:
219 return "error while reading header, or invalid header";
220 case EVREQ_HTTP_BUFFER_ERROR:
221 return "error encountered while reading or writing";
222 case EVREQ_HTTP_REQUEST_CANCEL:
223 return "request was canceled";
224 case EVREQ_HTTP_DATA_TOO_LONG:
225 return "response body is larger than allowed";
235 if (req ==
nullptr) {
243 reply->
status = evhttp_request_get_response_code(req);
245 struct evbuffer *buf = evhttp_request_get_input_buffer(req);
248 size_t size = evbuffer_get_length(buf);
249 const char *
data = (
const char*)evbuffer_pullup(buf, size);
251 reply->
body = std::string(
data, size);
252 evbuffer_drain(buf, size);
279 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
289 throw std::runtime_error(
"-addrinfo takes no arguments");
297 if (!reply[
"error"].isNull())
return reply;
298 const std::vector<UniValue>& nodes{reply[
"result"].
getValues()};
299 if (!nodes.empty() && nodes.at(0)[
"network"].isNull()) {
300 throw std::runtime_error(
"-addrinfo requires bitcoind server to be running v22.0 and up");
303 std::array<uint64_t,
NETWORKS.size()> counts{{}};
305 std::string network_name{
node[
"network"].get_str()};
308 ++counts.at(network_id);
313 for (
size_t i = 1; i <
NETWORKS.size() - 1; ++i) {
314 addresses.pushKV(
NETWORKS[i], counts.at(i));
315 total += counts.at(i);
317 addresses.pushKV(
"total", total);
318 result.pushKV(
"addresses_known", std::move(addresses));
336 throw std::runtime_error(
"-getinfo takes no arguments");
369 result.pushKV(
"connections", std::move(connections));
375 result.pushKV(
"has_wallet",
true);
378 if (!batch[
ID_WALLETINFO][
"result"][
"unlocked_until"].isNull()) {
401 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
463 if (seconds < 0)
return "";
464 const double milliseconds{round(1000 * seconds)};
465 return milliseconds > 999999 ?
"-" :
ToString(milliseconds);
469 if (conn_type ==
"outbound-full-relay")
return "full";
470 if (conn_type ==
"block-relay-only")
return "block";
471 if (conn_type ==
"manual" || conn_type ==
"feeler")
return conn_type;
472 if (conn_type ==
"addr-fetch")
return "addr";
478 for (
size_t i = 0; i < services.
size(); ++i) {
479 const std::string
s{services[i].
get_str()};
480 str +=
s ==
"NETWORK_LIMITED" ?
'l' :
s ==
"P2P_V2" ?
'2' :
ToLower(
s[0]);
496 throw std::runtime_error(
strprintf(
"invalid -netinfo level argument: %s\nFor more information, run: bitcoin-cli -netinfo help",
args.at(0)));
498 if (
args.size() > 1) {
499 if (std::string_view
s{
args.at(1)}; n && (
s ==
"o" ||
s ==
"outonly")) {
502 throw std::runtime_error(
strprintf(
"invalid -netinfo outonly argument: %s\nFor more information, run: bitcoin-cli -netinfo help",
s));
504 throw std::runtime_error(
strprintf(
"invalid -netinfo outonly argument: %s\nThe outonly argument is only valid for a level greater than 0 (the first argument). For more information, run: bitcoin-cli -netinfo help",
s));
521 if (networkinfo[
"version"].getInt<int>() < 209900) {
522 throw std::runtime_error(
"-netinfo requires bitcoind server to be running v0.21.0 and up");
524 const int64_t time_now{TicksSinceEpoch<std::chrono::seconds>(CliClock::now())};
528 const std::string network{peer[
"network"].get_str()};
531 const bool is_outbound{!peer[
"inbound"].get_bool()};
532 const bool is_tx_relay{peer[
"relaytxes"].isNull() ? true : peer[
"relaytxes"].get_bool()};
533 const std::string conn_type{peer[
"connection_type"].get_str()};
534 ++
m_counts.at(is_outbound).at(network_id);
543 const int peer_id{peer[
"id"].getInt<
int>()};
544 const int mapped_as{peer[
"mapped_as"].isNull() ? 0 : peer[
"mapped_as"].getInt<
int>()};
545 const int version{peer[
"version"].getInt<
int>()};
546 const int64_t addr_processed{peer[
"addr_processed"].isNull() ? 0 : peer[
"addr_processed"].getInt<int64_t>()};
547 const int64_t addr_rate_limited{peer[
"addr_rate_limited"].isNull() ? 0 : peer[
"addr_rate_limited"].getInt<int64_t>()};
548 const int64_t conn_time{peer[
"conntime"].getInt<int64_t>()};
549 const int64_t last_blck{peer[
"last_block"].getInt<int64_t>()};
550 const int64_t last_recv{peer[
"lastrecv"].getInt<int64_t>()};
551 const int64_t last_send{peer[
"lastsend"].getInt<int64_t>()};
552 const int64_t last_trxn{peer[
"last_transaction"].getInt<int64_t>()};
553 const double min_ping{peer[
"minping"].isNull() ? -1 : peer[
"minping"].get_real()};
554 const double ping{peer[
"pingtime"].isNull() ? -1 : peer[
"pingtime"].get_real()};
555 const std::string addr{peer[
"addr"].get_str()};
556 const std::string age{conn_time == 0 ?
"" :
ToString((time_now - conn_time) / 60)};
557 const std::string services{
FormatServices(peer[
"servicesnames"])};
558 const std::string sub_version{peer[
"subver"].get_str()};
559 const std::string transport{peer[
"transport_protocol_type"].isNull() ?
"v1" : peer[
"transport_protocol_type"].get_str()};
560 const bool is_addr_relay_enabled{peer[
"addr_relay_enabled"].isNull() ? false : peer[
"addr_relay_enabled"].get_bool()};
561 const bool is_bip152_hb_from{peer[
"bip152_hb_from"].get_bool()};
562 const bool is_bip152_hb_to{peer[
"bip152_hb_to"].get_bool()};
563 m_peers.push_back({addr, sub_version, conn_type,
NETWORK_SHORT_NAMES[network_id], age, services, transport, min_ping,
ping, addr_processed, addr_rate_limited, last_blck, last_recv, last_send, last_trxn, peer_id, mapped_as, version, is_addr_relay_enabled, is_bip152_hb_from, is_bip152_hb_to, is_outbound, is_tx_relay});
580 result +=
strprintf(
"<-> type net %*s v mping ping send recv txn blk hb %*s%*s%*s ",
588 std::string version{
ToString(peer.version) + peer.sub_version};
590 "%3s %6s %5s %*s %2s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
591 peer.is_outbound ?
"out" :
"in",
596 (peer.transport_protocol_type.size() == 2 && peer.transport_protocol_type[0] ==
'v') ? peer.transport_protocol_type[1] :
' ',
599 peer.last_send ?
ToString(time_now - peer.last_send) :
"",
600 peer.last_recv ?
ToString(time_now - peer.last_recv) :
"",
601 peer.last_trxn ?
ToString((time_now - peer.last_trxn) / 60) : peer.is_tx_relay ?
"" :
"*",
602 peer.last_blck ?
ToString((time_now - peer.last_blck) / 60) :
"",
603 strprintf(
"%s%s", peer.is_bip152_hb_to ?
"." :
" ", peer.is_bip152_hb_from ?
"*" :
" "),
605 peer.addr_processed ?
ToString(peer.addr_processed) : peer.is_addr_relay_enabled ?
"" :
".",
607 peer.addr_rate_limited ?
ToString(peer.addr_rate_limited) :
"",
623 std::vector<int8_t> reachable_networks;
624 for (
const UniValue& network : networkinfo[
"networks"].getValues()) {
625 if (network[
"reachable"].get_bool()) {
626 const std::string& network_name{network[
"name"].get_str()};
630 reachable_networks.push_back(network_id);
635 if (
m_counts.at(2).at(network_id) == 0)
continue;
637 reachable_networks.push_back(network_id);
643 const std::array rows{
"in",
"out",
"total"};
644 for (
size_t i = 0; i < rows.size(); ++i) {
646 for (int8_t n : reachable_networks) {
657 result +=
"\n\nLocal addresses";
658 const std::vector<UniValue>& local_addrs{networkinfo[
"localaddresses"].getValues()};
659 if (local_addrs.empty()) {
662 size_t max_addr_size{0};
663 for (
const UniValue& addr : local_addrs) {
664 max_addr_size = std::max(addr[
"address"].get_str().length() + 1, max_addr_size);
666 for (
const UniValue& addr : local_addrs) {
667 result +=
strprintf(
"\n%-*s port %6i score %6i", max_addr_size, addr[
"address"].get_str(), addr[
"port"].getInt<int>(), addr[
"score"].getInt<int>());
675 "-netinfo (level [outonly]) | help\n\n" 676 "Returns a network peer connections dashboard with information from the remote server.\n" 677 "This human-readable interface will change regularly and is not intended to be a stable API.\n" 678 "Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n" 680 "If that argument is passed, an optional additional \"outonly\" argument may be passed to obtain the listing with outbound peers only.\n" 681 "Pass \"help\" or \"h\" to see this detailed help documentation.\n" 682 "If more than two arguments are passed, only the first two are read and parsed.\n" 683 "Suggestion: use -netinfo with the Linux watch(1) command for a live dashboard; see example below.\n\n" 685 +
strprintf(
"1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n",
NETINFO_MAX_LEVEL) +
686 " 0 - Peer counts for each reachable network as well as for block relay peers\n" 687 " and manual peers, and the list of local addresses and ports\n" 688 " 1 - Like 0 but preceded by a peers listing (without address and version columns)\n" 689 " 2 - Like 1 but with an address column\n" 690 " 3 - Like 1 but with a version column\n" 691 " 4 - Like 1 but with both address and version columns\n" 692 "2. outonly (\"outonly\" or \"o\", optional) Return the peers listing with outbound peers only, i.e. to save screen space\n" 693 " when a node has many inbound peers. Only valid if a level is passed.\n\n" 694 "help (\"help\" or \"h\", optional) Print this help documentation instead of the dashboard.\n\n" 696 +
strprintf(
"* The peers listing in levels 1-%d displays all of the peers sorted by direction and minimum ping time:\n\n",
NETINFO_MAX_LEVEL) +
697 " Column Description\n" 698 " ------ -----------\n" 700 " \"in\" - inbound connections are those initiated by the peer\n" 701 " \"out\" - outbound connections are those initiated by us\n" 702 " type Type of peer connection\n" 703 " \"full\" - full relay, the default\n" 704 " \"block\" - block relay; like full relay but does not relay transactions or addresses\n" 705 " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n" 706 " \"feeler\" - short-lived connection for testing addresses\n" 707 " \"addr\" - address fetch; short-lived connection for requesting addresses\n" 708 " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", \"cjdns\", or \"npr\" (not publicly routable))\n" 709 " serv Services offered by the peer\n" 710 " \"n\" - NETWORK: peer can serve the full block chain\n" 711 " \"b\" - BLOOM: peer can handle bloom-filtered connections (see BIP 111)\n" 712 " \"w\" - WITNESS: peer can be asked for blocks and transactions with witness data (SegWit)\n" 713 " \"c\" - COMPACT_FILTERS: peer can handle basic block filter requests (see BIPs 157 and 158)\n" 714 " \"l\" - NETWORK_LIMITED: peer limited to serving only the last 288 blocks (~2 days)\n" 715 " \"2\" - P2P_V2: peer supports version 2 P2P transport protocol, as defined in BIP 324\n" 716 " \"u\" - UNKNOWN: unrecognized bit flag\n" 717 " v Version of transport protocol used for the connection\n" 718 " mping Minimum observed ping time, in milliseconds (ms)\n" 719 " ping Last observed ping time, in milliseconds (ms)\n" 720 " send Time since last message sent to the peer, in seconds\n" 721 " recv Time since last message received from the peer, in seconds\n" 722 " txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n" 723 " \"*\" - we do not relay transactions to this peer (getpeerinfo \"relaytxes\" is false)\n" 724 " blk Time since last novel block passing initial validity checks received from the peer, in minutes\n" 725 " hb High-bandwidth BIP152 compact block relay\n" 726 " \".\" (to) - we selected the peer as a high-bandwidth peer\n" 727 " \"*\" (from) - the peer selected us as a high-bandwidth peer\n" 728 " addrp Total number of addresses processed, excluding those dropped due to rate limiting\n" 729 " \".\" - we do not relay addresses to this peer (getpeerinfo \"addr_relay_enabled\" is false)\n" 730 " addrl Total number of addresses dropped due to rate limiting\n" 731 " age Duration of connection to the peer, in minutes\n" 732 " asmap Mapped AS (Autonomous System) number at the end of the BGP route to the peer, used for diversifying\n" 733 " peer selection (only displayed if the -asmap config option is set)\n" 734 " id Peer index, in increasing order of peer connections since node startup\n" 735 " address IP address and port of the peer\n" 736 " version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n" 737 "* The peer counts table displays the number of peers for each reachable network as well as\n" 738 " the number of block relay peers and manual peers.\n\n" 739 "* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n" 741 "Peer counts table of reachable networks and list of local addresses\n" 742 "> bitcoin-cli -netinfo\n\n" 743 "The same, preceded by a peers listing without address and version columns\n" 744 "> bitcoin-cli -netinfo 1\n\n" 747 "Full dashboard, but with outbound peers only\n" 749 "Full live dashboard, adjust --interval or --no-title as needed (Linux)\n" 752 "> bitcoin-cli -netinfo help\n"};
806 uint16_t rpcconnect_port{0};
812 throw std::runtime_error(
strprintf(
"Invalid port provided in -rpcconnect: %s", rpcconnect_str));
814 if (rpcconnect_port != 0) {
816 port = rpcconnect_port;
820 if (std::optional<std::string> rpcport_arg =
gArgs.
GetArg(
"-rpcport")) {
822 const uint16_t rpcport_int{ToIntegral<uint16_t>(rpcport_arg.value()).value_or(0)};
823 if (rpcport_int == 0) {
827 throw std::runtime_error(
strprintf(
"Invalid port provided in -rpcport: %s", rpcport_arg.value()));
835 if (rpcconnect_port != 0) {
836 tfm::format(std::cerr,
"Warning: Port specified in both -rpcconnect and -rpcport. Using -rpcport %u\n", port);
851 evhttp_connection_set_timeout(evcon.get(), timeout);
856 constexpr
int YEAR_IN_SECONDS = 31556952;
857 evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
863 if (req ==
nullptr) {
864 throw std::runtime_error(
"create http request failed");
871 bool failedToGetAuthCookie =
false;
875 failedToGetAuthCookie =
true;
881 struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get());
883 evhttp_add_header(output_headers,
"Host", host.c_str());
884 evhttp_add_header(output_headers,
"Connection",
"close");
885 evhttp_add_header(output_headers,
"Content-Type",
"application/json");
890 struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get());
892 evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
895 std::string endpoint =
"/";
897 char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(),
false);
899 endpoint =
"/wallet/" + std::string(encodedURI);
905 int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, endpoint.c_str());
911 event_base_dispatch(base.get());
913 if (response.
status == 0) {
914 std::string responseErrorMessage;
915 if (response.
error != -1) {
919 "Make sure the bitcoind server is running and that you are connecting to the correct RPC port.\n" 920 "Use \"bitcoin-cli -help\" for more info.",
921 host, port, responseErrorMessage));
923 if (failedToGetAuthCookie) {
925 "Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)",
928 throw std::runtime_error(
"Authorization failed: Incorrect rpcuser or rpcpassword");
931 throw std::runtime_error(
strprintf(
"Server response: %s", response.
body));
933 throw std::runtime_error(
strprintf(
"server returned HTTP error %d", response.
status));
934 else if (response.
body.empty())
935 throw std::runtime_error(
"no response from server");
939 if (!valReply.read(response.
body))
940 throw std::runtime_error(
"couldn't parse reply from server");
943 throw std::runtime_error(
"expected reply to have result, error and id properties");
963 const auto deadline{std::chrono::steady_clock::now() + 1
s * timeout};
967 response =
CallRPC(rh, strMethod,
args, rpcwallet);
969 const UniValue& error = response.find_value(
"error");
976 if (fWait && (timeout <= 0 || std::chrono::steady_clock::now() < deadline)) {
989 if (
result.isNull())
return;
1002 if (err_msg.
isStr()) {
1006 strPrint +=
" Or for the CLI, specify the \"-rpcwallet=<walletname>\" option before the command";
1007 strPrint +=
" (run \"bitcoin-cli -h\" for help or \"bitcoin-cli listwallets\" to see which wallets are currently loaded).";
1012 nRet = abs(error[
"code"].getInt<int>());
1025 if (!
listwallets.find_value(
"error").isNull())
return;
1027 if (wallets.
size() <= 1)
return;
1031 const std::string& wallet_name =
wallet.get_str();
1034 balances.
pushKV(wallet_name, balance);
1036 result.pushKV(
"balances", std::move(balances));
1047 if (progress < 0 || progress > 1)
return;
1049 static constexpr
double INCREMENT{0.05};
1050 static const std::string COMPLETE_BAR{
"\u2592"};
1051 static const std::string INCOMPLETE_BAR{
"\u2591"};
1053 for (
int i = 0; i < progress / INCREMENT; ++i) {
1054 progress_bar += COMPLETE_BAR;
1057 for (
int i = 0; i < (1 - progress) / INCREMENT; ++i) {
1058 progress_bar += INCOMPLETE_BAR;
1069 if (!
result.find_value(
"error").isNull())
return;
1071 std::string RESET, GREEN, BLUE, YELLOW, MAGENTA, CYAN;
1072 bool should_colorize =
false;
1075 if (isatty(fileno(stdout))) {
1077 should_colorize =
true;
1083 if (color ==
"always") {
1084 should_colorize =
true;
1085 }
else if (color ==
"never") {
1086 should_colorize =
false;
1087 }
else if (color !=
"auto") {
1088 throw std::runtime_error(
"Invalid value for -color option. Valid values: always, auto, never.");
1092 if (should_colorize) {
1096 YELLOW =
"\x1B[33m";
1097 MAGENTA =
"\x1B[35m";
1101 std::string result_string =
strprintf(
"%sChain: %s%s\n", BLUE,
result[
"chain"].getValStr(), RESET);
1102 result_string +=
strprintf(
"Blocks: %s\n",
result[
"blocks"].getValStr());
1103 result_string +=
strprintf(
"Headers: %s\n",
result[
"headers"].getValStr());
1105 const double ibd_progress{
result[
"verificationprogress"].get_real()};
1106 std::string ibd_progress_bar;
1108 if (ibd_progress < 0.99) {
1111 ibd_progress_bar +=
" ";
1114 result_string +=
strprintf(
"Verification progress: %s%.4f%%\n", ibd_progress_bar, ibd_progress * 100);
1115 result_string +=
strprintf(
"Difficulty: %s\n\n",
result[
"difficulty"].getValStr());
1118 "%sNetwork: in %s, out %s, total %s%s\n",
1120 result[
"connections"][
"in"].getValStr(),
1121 result[
"connections"][
"out"].getValStr(),
1122 result[
"connections"][
"total"].getValStr(),
1124 result_string +=
strprintf(
"Version: %s\n",
result[
"version"].getValStr());
1125 result_string +=
strprintf(
"Time offset (s): %s\n",
result[
"timeoffset"].getValStr());
1128 std::map<std::string, std::vector<std::string>> proxy_networks;
1129 std::vector<std::string> ordered_proxies;
1132 const std::string proxy = network[
"proxy"].getValStr();
1133 if (proxy.empty())
continue;
1135 if (proxy_networks.find(proxy) == proxy_networks.end()) ordered_proxies.push_back(proxy);
1137 proxy_networks[proxy].push_back(network[
"name"].getValStr());
1140 std::vector<std::string> formatted_proxies;
1141 formatted_proxies.reserve(ordered_proxies.size());
1142 for (
const std::string& proxy : ordered_proxies) {
1143 formatted_proxies.emplace_back(
strprintf(
"%s (%s)", proxy,
Join(proxy_networks.find(proxy)->second,
", ")));
1145 result_string +=
strprintf(
"Proxies: %s\n", formatted_proxies.empty() ?
"n/a" :
Join(formatted_proxies,
", "));
1149 if (!
result[
"has_wallet"].isNull()) {
1150 const std::string walletname =
result[
"walletname"].getValStr();
1151 result_string +=
strprintf(
"%sWallet: %s%s\n", MAGENTA, walletname.empty() ?
"\"\"" : walletname, RESET);
1153 result_string +=
strprintf(
"Keypool size: %s\n",
result[
"keypoolsize"].getValStr());
1154 if (!
result[
"unlocked_until"].isNull()) {
1155 result_string +=
strprintf(
"Unlocked until: %s\n",
result[
"unlocked_until"].getValStr());
1159 if (!
result[
"balance"].isNull()) {
1160 result_string +=
strprintf(
"%sBalance:%s %s\n\n", CYAN, RESET,
result[
"balance"].getValStr());
1163 if (!
result[
"balances"].isNull()) {
1164 result_string +=
strprintf(
"%sBalances%s\n", CYAN, RESET);
1166 size_t max_balance_length{10};
1168 for (
const std::string&
wallet :
result[
"balances"].getKeys()) {
1169 max_balance_length = std::max(
result[
"balances"][
wallet].getValStr().length(), max_balance_length);
1172 for (
const std::string&
wallet :
result[
"balances"].getKeys()) {
1178 result_string +=
"\n";
1181 const std::string warnings{
result[
"warnings"].getValStr()};
1182 result_string +=
strprintf(
"%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ?
"(none)" : warnings);
1184 result.setStr(result_string);
1204 if (
args.size() > 2)
throw std::runtime_error(
"too many arguments (maximum 2 for nblocks and maxtries)");
1205 if (
args.size() == 0) {
1207 }
else if (
args.at(0) ==
"0") {
1208 throw std::runtime_error(
"the first argument (number of blocks to generate, default: " +
DEFAULT_NBLOCKS +
") must be an integer value greater than zero");
1210 args.emplace(
args.begin() + 1, address);
1223 std::string rpcPass;
1227 fputs(
"RPC password> ", stderr);
1230 if (!std::getline(std::cin, rpcPass)) {
1231 throw std::runtime_error(
"-stdinrpcpass specified but failed to read from standard input");
1234 fputc(
'\n', stdout);
1238 std::vector<std::string>
args = std::vector<std::string>(&argv[1], &argv[argc]);
1241 std::string walletPass;
1242 if (
args.size() < 1 ||
args[0].substr(0, 16) !=
"walletpassphrase") {
1243 throw std::runtime_error(
"-stdinwalletpassphrase is only applicable for walletpassphrase(change)");
1246 fputs(
"Wallet passphrase> ", stderr);
1249 if (!std::getline(std::cin, walletPass)) {
1250 throw std::runtime_error(
"-stdinwalletpassphrase specified but failed to read from standard input");
1253 fputc(
'\n', stdout);
1255 args.insert(
args.begin() + 1, walletPass);
1260 while (std::getline(std::cin, line)) {
1261 args.push_back(line);
1264 fputc(
'\n', stdout);
1268 std::unique_ptr<BaseRequestHandler> rh;
1273 if (!
args.empty() && (
args.at(0) ==
"h" ||
args.at(0) ==
"help")) {
1291 if (
args.size() < 1) {
1292 throw std::runtime_error(
"too few parameters (need at least command)");
1318 }
catch (
const std::exception& e) {
1319 strPrint = std::string(
"error: ") + e.what();
1320 nRet = EXIT_FAILURE;
1335 common::WinCmdLineArgs winArgs;
1336 std::tie(argc, argv) = winArgs.get();
1340 tfm::format(std::cerr,
"Error: Initializing networking failed\n");
1341 return EXIT_FAILURE;
1350 catch (
const std::exception& e) {
1352 return EXIT_FAILURE;
1355 return EXIT_FAILURE;
1362 catch (
const std::exception& e) {
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
No wallet specified (error when there are multiple wallets loaded)
std::string ChainToString() const
std::string transport_protocol_type
static const std::string DEFAULT_NBLOCKS
Default number of blocks to generate for RPC generatetoaddress.
bool DetailsRequested() const
uint8_t m_block_relay_peers_count
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
static int CommandLineRPC(int argc, char *argv[])
raii_event_base obtain_event_base()
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
const std::vector< UniValue > & getValues() const
fs::path GetConfigFilePath() const
Return config file path (read-only)
static constexpr std::array UNREACHABLE_NETWORK_IDS
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
static int AppInitRPC(int argc, char *argv[])
bool SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)
Splits socket address string into host string and port value.
std::chrono::system_clock CliClock
static std::string strRPCUserColonPass
static constexpr int ID_NETWORKINFO
bool m_outbound_only_selected
static const std::string DEFAULT_COLOR_SETTING
Default -color setting.
UniValue ProcessReply(const UniValue &reply) override
int8_t NetworkStringToId(const std::string &str) const
static const int DEFAULT_HTTP_CLIENT_TIMEOUT
static void http_error_cb(enum evhttp_request_error err, void *ctx)
static constexpr int ID_PEERINFO
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
std::string EncodeBase64(Span< const unsigned char > input)
int8_t NetworkStringToId(const std::string &str) const
const std::string & get_str() const
size_t m_max_addr_rate_limited_length
raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg)
bool ParseParameters(int argc, const char *const argv[], std::string &error)
std::vector< Peer > m_peers
static std::string http_errorstring(int code)
uint8_t m_details_level
Optional user-supplied arg to set dashboard details level.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
std::string LicenseInfo()
Returns licensing information (for -version)
const int ID_BLOCKCHAININFO
void ForceSetArg(const std::string &strArg, const std::string &strValue)
static constexpr int8_t UNKNOWN_NETWORK
void PrintExceptionContinue(const std::exception *pex, std::string_view thread_name)
ChainType GetChainType() const
Returns the appropriate chain type from the program arguments.
const std::string & getValStr() const
bool operator<(const Peer &rhs) const
virtual UniValue ProcessReply(const UniValue &batch_in)=0
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Create a simulated getinfo request.
std::string GetHelpMessage() const
Get the help string.
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert positional arguments to command-specific RPC representation.
event_set_log_callback & libevent_log_cb
const UniValue & find_value(std::string_view key) const
std::vector< UniValue > JSONRPCProcessBatchReply(const UniValue &in)
Parse JSON-RPC batch reply into a vector.
static void ParseGetInfoResult(UniValue &result)
ParseGetInfoResult takes in -getinfo result in UniValue object and parses it into a user friendly Uni...
static const char DEFAULT_RPCCONNECT[]
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
UniValue ProcessReply(const UniValue &reply) override
static std::string PathToString(const path &path)
Convert path object to a byte string.
static void GetProgressBar(double progress, std::string &progress_bar)
GetProgressBar constructs a progress bar with 5% intervals.
static constexpr uint8_t NETINFO_MAX_LEVEL
size_t m_max_addr_processed_length
static const uint64_t DEFAULT_MAX_TRIES
Default max iterations to try in RPC generatetodescriptor, generatetoaddress, and generateblock...
static UniValue CallRPC(BaseRequestHandler *rh, const std::string &strMethod, const std::vector< std::string > &args, const std::optional< std::string > &rpcwallet={})
static void ParseError(const UniValue &error, std::string &strPrint, int &nRet)
Parse UniValue error to update the message to print to std::cerr and the code to return.
static constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT
std::function< std::string(const char *)> TranslateFn
Translate a message to the native language of the user.
Process netinfo requests.
Process addrinfo requests.
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
std::unique_ptr< CBaseChainParams > CreateBaseChainParams(const ChainType chain)
Port numbers for incoming Tor connections (8334, 18334, 38334, 48334, 18445) have been chosen arbitra...
static const int CONTINUE_EXECUTION
bool ParseUInt8(std::string_view str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
virtual UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args)=0
raii_evhttp_connection obtain_evhttp_connection_base(struct event_base *base, std::string host, uint16_t port)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const std::string CURRENCY_UNIT
static void GetWalletBalances(UniValue &result)
GetWalletBalances calls listwallets; if more than one wallet is loaded, it then fetches mine...
void CheckMultipleCLIArgs() const
Check CLI command args.
std::string ConnectionTypeForNetinfo(const std::string &conn_type) const
std::string FormatParagraph(std::string_view in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line...
UniValue ProcessReply(const UniValue &batch_in) override
Collect values from the batch and form a simulated getinfo reply.
std::optional< std::string > RpcWalletName(const ArgsManager &args)
UniValue JSONRPCReplyObj(UniValue result, UniValue error, std::optional< UniValue > id, JSONRPCVersion jsonrpc_version)
Class that handles the conversion from a command-line to a JSON-RPC request, as well as converting ba...
std::string FormatFullVersion()
int64_t addr_rate_limited
static void SetupCliArgs(ArgsManager &argsman)
std::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.
bool IsVersionSelected() const
static constexpr std::array NETWORKS
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
static void ParseResult(const UniValue &result, std::string &strPrint)
Parse UniValue result to update the message to print to std::cout.
CConnectionFailed(const std::string &msg)
std::array< std::array< uint16_t, NETWORKS.size()+1 >, 3 > m_counts
Peer counts by (in/out/total, networks/total)
void UninterruptibleSleep(const std::chrono::microseconds &n)
void SelectBaseParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain.
void pushKV(std::string key, UniValue val)
virtual ~BaseRequestHandler()=default
uint8_t m_manual_peers_count
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
const UniValue & get_obj() const
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Process RPC generatetoaddress request.
std::string FormatServices(const UniValue &services)
static constexpr std::array NETWORK_SHORT_NAMES
const std::string m_help_doc
bool HelpRequested(const ArgsManager &args)
Process default single requests.
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
UniValue JSONRPCRequestObj(const std::string &strMethod, const UniValue ¶ms, const UniValue &id)
JSON-RPC protocol.
const UniValue NullUniValue
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
const char *const BITCOIN_CONF_FILENAME
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert named arguments to command-specific RPC representation.
static const bool DEFAULT_NAMED
static UniValue GetNewAddress()
Call RPC getnewaddress.
static UniValue ConnectAndCallRPC(BaseRequestHandler *rh, const std::string &strMethod, const std::vector< std::string > &args, const std::optional< std::string > &rpcwallet={})
ConnectAndCallRPC wraps CallRPC with -rpcwait and an exception handler.
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
size_t m_max_services_length
UniValue ProcessReply(const UniValue &batch_in) override
RPCHelpMan getnewaddress()
bool IsAddressSelected() const
bool is_addr_relay_enabled
static RPCHelpMan listwallets()
std::string PingTimeToString(double seconds) const
Process getinfo requests.
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
static void SetGenerateToAddressArgs(const std::string &address, std::vector< std::string > &args)
Check bounds and set up args for RPC generatetoaddress params: nblocks, address, maxtries.
static void http_request_done(struct evhttp_request *req, void *ctx)
bool IsSwitchChar(char c)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Reply structure for request_done to fill in.
UniValue ProcessReply(const UniValue &reply) override
bool CheckDataDirOption(const ArgsManager &args)
const TranslateFn G_TRANSLATION_FUN
Translate string to current locale using Qt.