6 #if defined(HAVE_CONFIG_H) 44 #include <event2/buffer.h> 45 #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"};
85 argsman.
AddArg(
"-generate",
86 strprintf(
"Generate blocks, equivalent to RPC getnewaddress followed by RPC generatetoaddress. Optional positional integer " 87 "arguments are number of blocks to generate (default: %s) and maximum iterations to try (default: %s), equivalent to " 88 "RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000",
92 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::OPTIONS);
93 argsman.
AddArg(
"-netinfo",
"Get network peer connection information from the remote server. An optional integer argument from 0 to 4 can be passed for different peers listings (default: 0). Pass \"help\" for detailed help documentation.",
ArgsManager::ALLOW_ANY,
OptionsCategory::OPTIONS);
102 argsman.
AddArg(
"-rpcport=<port>",
strprintf(
"Connect to JSON-RPC on <port> (default: %u, testnet: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()),
ArgsManager::ALLOW_ANY |
ArgsManager::NETWORK_ONLY,
OptionsCategory::OPTIONS);
106 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);
107 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);
108 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);
116 if (severity >= EVENT_LOG_ERR) {
117 throw std::runtime_error(
strprintf(
"libevent error: %s",
msg));
144 tfm::format(std::cerr,
"Error parsing command line arguments: %s\n",
error);
154 "Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n" 155 "or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n" 156 "or: bitcoin-cli [options] help List commands\n" 157 "or: bitcoin-cli [options] help <command> Get help for a command\n";
163 tfm::format(std::cerr,
"Error: too few parameters\n");
169 tfm::format(std::cerr,
"Error: Specified data directory \"%s\" does not exist.\n",
gArgs.
GetArg(
"-datadir",
""));
179 }
catch (
const std::exception& e) {
200 case EVREQ_HTTP_TIMEOUT:
201 return "timeout reached";
203 return "EOF reached";
204 case EVREQ_HTTP_INVALID_HEADER:
205 return "error while reading header, or invalid header";
206 case EVREQ_HTTP_BUFFER_ERROR:
207 return "error encountered while reading or writing";
208 case EVREQ_HTTP_REQUEST_CANCEL:
209 return "request was canceled";
210 case EVREQ_HTTP_DATA_TOO_LONG:
211 return "response body is larger than allowed";
221 if (req ==
nullptr) {
229 reply->
status = evhttp_request_get_response_code(req);
231 struct evbuffer *buf = evhttp_request_get_input_buffer(req);
234 size_t size = evbuffer_get_length(buf);
235 const char *data = (
const char*)evbuffer_pullup(buf, size);
237 reply->
body = std::string(data, size);
238 evbuffer_drain(buf, size);
265 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
275 throw std::runtime_error(
"-addrinfo takes no arguments");
283 if (!reply[
"error"].isNull())
return reply;
284 const std::vector<UniValue>& nodes{reply[
"result"].
getValues()};
285 if (!nodes.empty() && nodes.at(0)[
"network"].isNull()) {
286 throw std::runtime_error(
"-addrinfo requires bitcoind server to be running v22.0 and up");
289 std::array<uint64_t,
NETWORKS.size()> counts{{}};
291 std::string network_name{
node[
"network"].get_str()};
294 ++counts.at(network_id);
299 for (
size_t i = 1; i <
NETWORKS.size() - 1; ++i) {
300 addresses.pushKV(
NETWORKS[i], counts.at(i));
301 total += counts.at(i);
303 addresses.pushKV(
"total", total);
304 result.pushKV(
"addresses_known", addresses);
322 throw std::runtime_error(
"-getinfo takes no arguments");
355 result.
pushKV(
"connections", connections);
361 result.
pushKV(
"has_wallet",
true);
364 if (!batch[
ID_WALLETINFO][
"result"][
"unlocked_until"].isNull()) {
388 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
444 if (seconds < 0)
return "";
445 const double milliseconds{round(1000 * seconds)};
446 return milliseconds > 999999 ?
"-" :
ToString(milliseconds);
450 if (conn_type ==
"outbound-full-relay")
return "full";
451 if (conn_type ==
"block-relay-only")
return "block";
452 if (conn_type ==
"manual" || conn_type ==
"feeler")
return conn_type;
453 if (conn_type ==
"addr-fetch")
return "addr";
468 throw std::runtime_error(
strprintf(
"invalid -netinfo argument: %s\nFor more information, run: bitcoin-cli -netinfo help",
args.at(0)));
484 if (networkinfo[
"version"].getInt<int>() < 209900) {
485 throw std::runtime_error(
"-netinfo requires bitcoind server to be running v0.21.0 and up");
487 const int64_t time_now{TicksSinceEpoch<std::chrono::seconds>(CliClock::now())};
491 const std::string network{peer[
"network"].get_str()};
494 const bool is_outbound{!peer[
"inbound"].get_bool()};
495 const bool is_tx_relay{peer[
"relaytxes"].isNull() ? true : peer[
"relaytxes"].get_bool()};
496 const std::string conn_type{peer[
"connection_type"].get_str()};
497 ++
m_counts.at(is_outbound).at(network_id);
505 const int peer_id{peer[
"id"].getInt<
int>()};
506 const int mapped_as{peer[
"mapped_as"].isNull() ? 0 : peer[
"mapped_as"].getInt<
int>()};
507 const int version{peer[
"version"].getInt<
int>()};
508 const int64_t addr_processed{peer[
"addr_processed"].isNull() ? 0 : peer[
"addr_processed"].getInt<int64_t>()};
509 const int64_t addr_rate_limited{peer[
"addr_rate_limited"].isNull() ? 0 : peer[
"addr_rate_limited"].getInt<int64_t>()};
510 const int64_t conn_time{peer[
"conntime"].getInt<int64_t>()};
511 const int64_t last_blck{peer[
"last_block"].getInt<int64_t>()};
512 const int64_t last_recv{peer[
"lastrecv"].getInt<int64_t>()};
513 const int64_t last_send{peer[
"lastsend"].getInt<int64_t>()};
514 const int64_t last_trxn{peer[
"last_transaction"].getInt<int64_t>()};
515 const double min_ping{peer[
"minping"].isNull() ? -1 : peer[
"minping"].get_real()};
516 const double ping{peer[
"pingtime"].isNull() ? -1 : peer[
"pingtime"].get_real()};
517 const std::string addr{peer[
"addr"].get_str()};
518 const std::string age{conn_time == 0 ?
"" :
ToString((time_now - conn_time) / 60)};
519 const std::string sub_version{peer[
"subver"].get_str()};
520 const bool is_addr_relay_enabled{peer[
"addr_relay_enabled"].isNull() ? false : peer[
"addr_relay_enabled"].get_bool()};
521 const bool is_bip152_hb_from{peer[
"bip152_hb_from"].get_bool()};
522 const bool is_bip152_hb_to{peer[
"bip152_hb_to"].get_bool()};
523 m_peers.push_back({addr, sub_version, conn_type,
NETWORK_SHORT_NAMES[network_id], age, 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});
539 result +=
strprintf(
"<-> type net mping ping send recv txn blk hb %*s%*s%*s ",
546 std::string version{
ToString(peer.version) + peer.sub_version};
548 "%3s %6s %5s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
549 peer.is_outbound ?
"out" :
"in",
554 peer.last_send ?
ToString(time_now - peer.last_send) :
"",
555 peer.last_recv ?
ToString(time_now - peer.last_recv) :
"",
556 peer.last_trxn ?
ToString((time_now - peer.last_trxn) / 60) : peer.is_tx_relay ?
"" :
"*",
557 peer.last_blck ?
ToString((time_now - peer.last_blck) / 60) :
"",
558 strprintf(
"%s%s", peer.is_bip152_hb_to ?
"." :
" ", peer.is_bip152_hb_from ?
"*" :
" "),
560 peer.addr_processed ?
ToString(peer.addr_processed) : peer.is_addr_relay_enabled ?
"" :
".",
562 peer.addr_rate_limited ?
ToString(peer.addr_rate_limited) :
"",
578 std::vector<int8_t> reachable_networks;
579 for (
const UniValue& network : networkinfo[
"networks"].getValues()) {
580 if (network[
"reachable"].get_bool()) {
581 const std::string& network_name{network[
"name"].get_str()};
584 result +=
strprintf(
"%8s", network_name);
585 reachable_networks.push_back(network_id);
590 if (
m_counts.at(2).at(network_id) == 0)
continue;
592 reachable_networks.push_back(network_id);
595 result +=
" total block";
598 const std::array rows{
"in",
"out",
"total"};
599 for (
size_t i = 0; i < rows.size(); ++i) {
601 for (int8_t n : reachable_networks) {
612 result +=
"\n\nLocal addresses";
613 const std::vector<UniValue>& local_addrs{networkinfo[
"localaddresses"].getValues()};
614 if (local_addrs.empty()) {
617 size_t max_addr_size{0};
618 for (
const UniValue& addr : local_addrs) {
619 max_addr_size = std::max(addr[
"address"].get_str().length() + 1, max_addr_size);
621 for (
const UniValue& addr : local_addrs) {
622 result +=
strprintf(
"\n%-*s port %6i score %6i", max_addr_size, addr[
"address"].get_str(), addr[
"port"].getInt<int>(), addr[
"score"].getInt<int>());
630 "-netinfo level|\"help\" \n\n" 631 "Returns a network peer connections dashboard with information from the remote server.\n" 632 "This human-readable interface will change regularly and is not intended to be a stable API.\n" 633 "Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n" 635 "Pass \"help\" to see this detailed help documentation.\n" 636 "If more than one argument is passed, only the first one is read and parsed.\n" 637 "Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n" 639 +
strprintf(
"1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n",
MAX_DETAIL_LEVEL) +
640 " 0 - Peer counts for each reachable network as well as for block relay peers\n" 641 " and manual peers, and the list of local addresses and ports\n" 642 " 1 - Like 0 but preceded by a peers listing (without address and version columns)\n" 643 " 2 - Like 1 but with an address column\n" 644 " 3 - Like 1 but with a version column\n" 645 " 4 - Like 1 but with both address and version columns\n" 646 "2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n" 648 +
strprintf(
"* The peers listing in levels 1-%d displays all of the peers sorted by direction and minimum ping time:\n\n",
MAX_DETAIL_LEVEL) +
649 " Column Description\n" 650 " ------ -----------\n" 652 " \"in\" - inbound connections are those initiated by the peer\n" 653 " \"out\" - outbound connections are those initiated by us\n" 654 " type Type of peer connection\n" 655 " \"full\" - full relay, the default\n" 656 " \"block\" - block relay; like full relay but does not relay transactions or addresses\n" 657 " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n" 658 " \"feeler\" - short-lived connection for testing addresses\n" 659 " \"addr\" - address fetch; short-lived connection for requesting addresses\n" 660 " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", \"cjdns\", or \"npr\" (not publicly routable))\n" 661 " mping Minimum observed ping time, in milliseconds (ms)\n" 662 " ping Last observed ping time, in milliseconds (ms)\n" 663 " send Time since last message sent to the peer, in seconds\n" 664 " recv Time since last message received from the peer, in seconds\n" 665 " txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n" 666 " \"*\" - we do not relay transactions to this peer (relaytxes is false)\n" 667 " blk Time since last novel block passing initial validity checks received from the peer, in minutes\n" 668 " hb High-bandwidth BIP152 compact block relay\n" 669 " \".\" (to) - we selected the peer as a high-bandwidth peer\n" 670 " \"*\" (from) - the peer selected us as a high-bandwidth peer\n" 671 " addrp Total number of addresses processed, excluding those dropped due to rate limiting\n" 672 " \".\" - we do not relay addresses to this peer (addr_relay_enabled is false)\n" 673 " addrl Total number of addresses dropped due to rate limiting\n" 674 " age Duration of connection to the peer, in minutes\n" 675 " asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n" 676 " peer selection (only displayed if the -asmap config option is set)\n" 677 " id Peer index, in increasing order of peer connections since node startup\n" 678 " address IP address and port of the peer\n" 679 " version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n" 680 "* The peer counts table displays the number of peers for each reachable network as well as\n" 681 " the number of block relay peers and manual peers.\n\n" 682 "* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n" 684 "Peer counts table of reachable networks and list of local addresses\n" 685 "> bitcoin-cli -netinfo\n\n" 686 "The same, preceded by a peers listing without address and version columns\n" 687 "> bitcoin-cli -netinfo 1\n\n" 690 "Full live dashboard, adjust --interval or --no-title as needed (Linux)\n" 693 "> bitcoin-cli -netinfo help\n"};
759 evhttp_connection_set_timeout(evcon.get(), timeout);
764 constexpr
int YEAR_IN_SECONDS = 31556952;
765 evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
771 if (req ==
nullptr) {
772 throw std::runtime_error(
"create http request failed");
779 bool failedToGetAuthCookie =
false;
783 failedToGetAuthCookie =
true;
789 struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get());
791 evhttp_add_header(output_headers,
"Host", host.c_str());
792 evhttp_add_header(output_headers,
"Connection",
"close");
793 evhttp_add_header(output_headers,
"Content-Type",
"application/json");
798 struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get());
800 evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
803 std::string endpoint =
"/";
805 char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(),
false);
807 endpoint =
"/wallet/" + std::string(encodedURI);
813 int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, endpoint.c_str());
819 event_base_dispatch(base.get());
821 if (response.
status == 0) {
822 std::string responseErrorMessage;
823 if (response.
error != -1) {
826 throw CConnectionFailed(
strprintf(
"Could not connect to the server %s:%d%s\n\nMake sure the bitcoind server is running and that you are connecting to the correct RPC port.", host, port, responseErrorMessage));
828 if (failedToGetAuthCookie) {
830 "Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)",
833 throw std::runtime_error(
"Authorization failed: Incorrect rpcuser or rpcpassword");
836 throw std::runtime_error(
strprintf(
"Server response: %s", response.
body));
838 throw std::runtime_error(
strprintf(
"server returned HTTP error %d", response.
status));
839 else if (response.
body.empty())
840 throw std::runtime_error(
"no response from server");
844 if (!valReply.read(response.
body))
845 throw std::runtime_error(
"couldn't parse reply from server");
848 throw std::runtime_error(
"expected reply to have result, error and id properties");
868 const auto deadline{std::chrono::steady_clock::now() + 1s * timeout};
872 response =
CallRPC(rh, strMethod,
args, rpcwallet);
881 if (fWait && (timeout <= 0 || std::chrono::steady_clock::now() < deadline)) {
894 if (result.
isNull())
return;
901 if (
error.isObject()) {
907 if (err_msg.
isStr()) {
911 strPrint +=
"\nTry adding \"-rpcwallet=<filename>\" option to bitcoin-cli command line.";
916 nRet = abs(
error[
"code"].getInt<int>());
929 if (!
listwallets.find_value(
"error").isNull())
return;
931 if (wallets.
size() <= 1)
return;
935 const std::string& wallet_name =
wallet.get_str();
938 balances.
pushKV(wallet_name, balance);
940 result.
pushKV(
"balances", balances);
951 if (progress < 0 || progress > 1)
return;
953 static constexpr
double INCREMENT{0.05};
954 static const std::string COMPLETE_BAR{
"\u2592"};
955 static const std::string INCOMPLETE_BAR{
"\u2591"};
957 for (
int i = 0; i < progress / INCREMENT; ++i) {
958 progress_bar += COMPLETE_BAR;
961 for (
int i = 0; i < (1 - progress) / INCREMENT; ++i) {
962 progress_bar += INCOMPLETE_BAR;
975 std::string RESET, GREEN, BLUE, YELLOW, MAGENTA, CYAN;
976 bool should_colorize =
false;
979 if (isatty(fileno(stdout))) {
981 should_colorize =
true;
987 if (color ==
"always") {
988 should_colorize =
true;
989 }
else if (color ==
"never") {
990 should_colorize =
false;
991 }
else if (color !=
"auto") {
992 throw std::runtime_error(
"Invalid value for -color option. Valid values: always, auto, never.");
996 if (should_colorize) {
1000 YELLOW =
"\x1B[33m";
1001 MAGENTA =
"\x1B[35m";
1005 std::string result_string =
strprintf(
"%sChain: %s%s\n", BLUE, result[
"chain"].getValStr(), RESET);
1006 result_string +=
strprintf(
"Blocks: %s\n", result[
"blocks"].getValStr());
1007 result_string +=
strprintf(
"Headers: %s\n", result[
"headers"].getValStr());
1009 const double ibd_progress{result[
"verificationprogress"].
get_real()};
1010 std::string ibd_progress_bar;
1012 if (ibd_progress < 0.99) {
1015 ibd_progress_bar +=
" ";
1018 result_string +=
strprintf(
"Verification progress: %s%.4f%%\n", ibd_progress_bar, ibd_progress * 100);
1019 result_string +=
strprintf(
"Difficulty: %s\n\n", result[
"difficulty"].getValStr());
1022 "%sNetwork: in %s, out %s, total %s%s\n",
1024 result[
"connections"][
"in"].getValStr(),
1025 result[
"connections"][
"out"].getValStr(),
1026 result[
"connections"][
"total"].getValStr(),
1028 result_string +=
strprintf(
"Version: %s\n", result[
"version"].getValStr());
1029 result_string +=
strprintf(
"Time offset (s): %s\n", result[
"timeoffset"].getValStr());
1032 std::map<std::string, std::vector<std::string>> proxy_networks;
1033 std::vector<std::string> ordered_proxies;
1035 for (
const UniValue& network : result[
"networks"].getValues()) {
1036 const std::string proxy = network[
"proxy"].getValStr();
1037 if (proxy.empty())
continue;
1039 if (proxy_networks.find(proxy) == proxy_networks.end()) ordered_proxies.push_back(proxy);
1041 proxy_networks[proxy].push_back(network[
"name"].getValStr());
1044 std::vector<std::string> formatted_proxies;
1045 formatted_proxies.reserve(ordered_proxies.size());
1046 for (
const std::string& proxy : ordered_proxies) {
1047 formatted_proxies.emplace_back(
strprintf(
"%s (%s)", proxy,
Join(proxy_networks.find(proxy)->second,
", ")));
1049 result_string +=
strprintf(
"Proxies: %s\n", formatted_proxies.empty() ?
"n/a" :
Join(formatted_proxies,
", "));
1051 result_string +=
strprintf(
"Min tx relay fee rate (%s/kvB): %s\n\n",
CURRENCY_UNIT, result[
"relayfee"].getValStr());
1053 if (!result[
"has_wallet"].isNull()) {
1054 const std::string walletname = result[
"walletname"].
getValStr();
1055 result_string +=
strprintf(
"%sWallet: %s%s\n", MAGENTA, walletname.empty() ?
"\"\"" : walletname, RESET);
1057 result_string +=
strprintf(
"Keypool size: %s\n", result[
"keypoolsize"].getValStr());
1058 if (!result[
"unlocked_until"].isNull()) {
1059 result_string +=
strprintf(
"Unlocked until: %s\n", result[
"unlocked_until"].getValStr());
1061 result_string +=
strprintf(
"Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n",
CURRENCY_UNIT, result[
"paytxfee"].getValStr());
1063 if (!result[
"balance"].isNull()) {
1064 result_string +=
strprintf(
"%sBalance:%s %s\n\n", CYAN, RESET, result[
"balance"].getValStr());
1067 if (!result[
"balances"].isNull()) {
1068 result_string +=
strprintf(
"%sBalances%s\n", CYAN, RESET);
1070 size_t max_balance_length{10};
1072 for (
const std::string&
wallet : result[
"balances"].getKeys()) {
1073 max_balance_length = std::max(result[
"balances"][
wallet].getValStr().length(), max_balance_length);
1076 for (
const std::string&
wallet : result[
"balances"].getKeys()) {
1079 result[
"balances"][
wallet].getValStr(),
1082 result_string +=
"\n";
1085 const std::string warnings{result[
"warnings"].
getValStr()};
1086 result_string +=
strprintf(
"%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ?
"(none)" : warnings);
1088 result.
setStr(result_string);
1097 std::optional<std::string> wallet_name{};
1110 if (
args.size() > 2)
throw std::runtime_error(
"too many arguments (maximum 2 for nblocks and maxtries)");
1111 if (
args.size() == 0) {
1113 }
else if (
args.at(0) ==
"0") {
1114 throw std::runtime_error(
"the first argument (number of blocks to generate, default: " +
DEFAULT_NBLOCKS +
") must be an integer value greater than zero");
1116 args.emplace(
args.begin() + 1, address);
1129 std::string rpcPass;
1133 fputs(
"RPC password> ", stderr);
1136 if (!std::getline(std::cin, rpcPass)) {
1137 throw std::runtime_error(
"-stdinrpcpass specified but failed to read from standard input");
1140 fputc(
'\n', stdout);
1144 std::vector<std::string>
args = std::vector<std::string>(&argv[1], &argv[argc]);
1147 std::string walletPass;
1148 if (
args.size() < 1 ||
args[0].substr(0, 16) !=
"walletpassphrase") {
1149 throw std::runtime_error(
"-stdinwalletpassphrase is only applicable for walletpassphrase(change)");
1152 fputs(
"Wallet passphrase> ", stderr);
1155 if (!std::getline(std::cin, walletPass)) {
1156 throw std::runtime_error(
"-stdinwalletpassphrase specified but failed to read from standard input");
1159 fputc(
'\n', stdout);
1161 args.insert(
args.begin() + 1, walletPass);
1166 while (std::getline(std::cin, line)) {
1167 args.push_back(line);
1170 fputc(
'\n', stdout);
1173 std::unique_ptr<BaseRequestHandler> rh;
1178 if (!
args.empty() &&
args.at(0) ==
"help") {
1186 if (
error.isNull()) {
1196 if (
args.size() < 1) {
1197 throw std::runtime_error(
"too few parameters (need at least command)");
1204 std::optional<std::string> wallet_name{};
1211 if (
error.isNull()) {
1224 }
catch (
const std::exception& e) {
1225 strPrint = std::string(
"error: ") + e.what();
1226 nRet = EXIT_FAILURE;
1241 common::WinCmdLineArgs winArgs;
1242 std::tie(argc, argv) = winArgs.get();
1246 tfm::format(std::cerr,
"Error: Initializing networking failed\n");
1247 return EXIT_FAILURE;
1256 catch (
const std::exception& e) {
1258 return EXIT_FAILURE;
1261 return EXIT_FAILURE;
1268 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
static const std::string DEFAULT_NBLOCKS
Default number of blocks to generate for RPC generatetoaddress.
bool DetailsRequested() const
void push_back(UniValue val)
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
static const std::string DEFAULT_COLOR_SETTING
Default -color setting.
UniValue ProcessReply(const UniValue &reply) override
static constexpr uint8_t MAX_DETAIL_LEVEL
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...
std::string ToString(const T &t)
Locale-independent version of std::to_string.
static const char DEFAULT_RPCCONNECT[]
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.
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
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, 18445) have been chosen arbitrarily to...
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...
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.
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)
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.
bool error(const char *fmt, const Args &... args)
void pushKV(std::string key, UniValue val)
virtual ~BaseRequestHandler()=default
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
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.
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
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
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
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
UrlDecodeFn *const URL_DECODE
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
std::shared_ptr< CWallet > wallet
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.
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)
void setStr(std::string str)
Reply structure for request_done to fill in.
UniValue ProcessReply(const UniValue &reply) override
std::string(const std::string &url_encoded) UrlDecodeFn
bool CheckDataDirOption(const ArgsManager &args)