6 #if defined(HAVE_CONFIG_H)
43 #include <event2/buffer.h>
44 #include <event2/keyvalq_struct.h>
61 static constexpr std::array
NETWORKS{
"not_publicly_routable",
"ipv4",
"ipv6",
"onion",
"i2p",
"cjdns",
"internal"};
62 static constexpr std::array
NETWORK_SHORT_NAMES{
"npr",
"ipv4",
"ipv6",
"onion",
"i2p",
"cjdns",
"int"};
83 argsman.
AddArg(
"-generate",
84 strprintf(
"Generate blocks, equivalent to RPC getnewaddress followed by RPC generatetoaddress. Optional positional integer "
85 "arguments are number of blocks to generate (default: %s) and maximum iterations to try (default: %s), equivalent to "
86 "RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000",
90 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);
91 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);
100 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);
104 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);
105 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);
106 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);
114 if (severity >= EVENT_LOG_ERR) {
115 throw std::runtime_error(
strprintf(
"libevent error: %s",
msg));
142 tfm::format(std::cerr,
"Error parsing command line arguments: %s\n", error);
152 "Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n"
153 "or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n"
154 "or: bitcoin-cli [options] help List commands\n"
155 "or: bitcoin-cli [options] help <command> Get help for a command\n";
161 tfm::format(std::cerr,
"Error: too few parameters\n");
167 tfm::format(std::cerr,
"Error: Specified data directory \"%s\" does not exist.\n",
gArgs.
GetArg(
"-datadir",
""));
171 tfm::format(std::cerr,
"Error reading configuration file: %s\n", error);
177 }
catch (
const std::exception& e) {
198 case EVREQ_HTTP_TIMEOUT:
199 return "timeout reached";
201 return "EOF reached";
202 case EVREQ_HTTP_INVALID_HEADER:
203 return "error while reading header, or invalid header";
204 case EVREQ_HTTP_BUFFER_ERROR:
205 return "error encountered while reading or writing";
206 case EVREQ_HTTP_REQUEST_CANCEL:
207 return "request was canceled";
208 case EVREQ_HTTP_DATA_TOO_LONG:
209 return "response body is larger than allowed";
219 if (req ==
nullptr) {
227 reply->
status = evhttp_request_get_response_code(req);
229 struct evbuffer *buf = evhttp_request_get_input_buffer(req);
232 size_t size = evbuffer_get_length(buf);
233 const char *data = (
const char*)evbuffer_pullup(buf, size);
235 reply->
body = std::string(data, size);
236 evbuffer_drain(buf, size);
263 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
273 throw std::runtime_error(
"-addrinfo takes no arguments");
281 if (!reply[
"error"].isNull())
return reply;
282 const std::vector<UniValue>& nodes{reply[
"result"].
getValues()};
283 if (!nodes.empty() && nodes.at(0)[
"network"].isNull()) {
284 throw std::runtime_error(
"-addrinfo requires bitcoind server to be running v22.0 and up");
287 std::array<uint64_t,
NETWORKS.size()> counts{{}};
289 std::string network_name{
node[
"network"].get_str()};
292 ++counts.at(network_id);
297 for (
size_t i = 1; i <
NETWORKS.size() - 1; ++i) {
298 addresses.pushKV(
NETWORKS[i], counts.at(i));
299 total += counts.at(i);
301 addresses.pushKV(
"total", total);
302 result.pushKV(
"addresses_known", addresses);
320 throw std::runtime_error(
"-getinfo takes no arguments");
353 result.
pushKV(
"connections", connections);
359 result.
pushKV(
"has_wallet",
true);
362 if (!batch[
ID_WALLETINFO][
"result"][
"unlocked_until"].isNull()) {
386 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
443 if (seconds < 0)
return "";
444 const double milliseconds{round(1000 * seconds)};
445 return milliseconds > 999999 ?
"-" :
ToString(milliseconds);
449 if (conn_type ==
"outbound-full-relay")
return "full";
450 if (conn_type ==
"block-relay-only")
return "block";
451 if (conn_type ==
"manual" || conn_type ==
"feeler")
return conn_type;
452 if (conn_type ==
"addr-fetch")
return "addr";
467 throw std::runtime_error(
strprintf(
"invalid -netinfo argument: %s\nFor more information, run: bitcoin-cli -netinfo help",
args.at(0)));
483 if (networkinfo[
"version"].getInt<int>() < 209900) {
484 throw std::runtime_error(
"-netinfo requires bitcoind server to be running v0.21.0 and up");
486 const int64_t time_now{TicksSinceEpoch<std::chrono::seconds>(CliClock::now())};
490 const std::string network{peer[
"network"].get_str()};
493 const bool is_outbound{!peer[
"inbound"].get_bool()};
494 const bool is_tx_relay{peer[
"relaytxes"].isNull() ? true : peer[
"relaytxes"].get_bool()};
495 const std::string conn_type{peer[
"connection_type"].get_str()};
496 ++
m_counts.at(is_outbound).at(network_id);
504 const int peer_id{peer[
"id"].getInt<
int>()};
505 const int mapped_as{peer[
"mapped_as"].isNull() ? 0 : peer[
"mapped_as"].getInt<
int>()};
506 const int version{peer[
"version"].getInt<
int>()};
507 const int64_t addr_processed{peer[
"addr_processed"].isNull() ? 0 : peer[
"addr_processed"].getInt<int64_t>()};
508 const int64_t addr_rate_limited{peer[
"addr_rate_limited"].isNull() ? 0 : peer[
"addr_rate_limited"].getInt<int64_t>()};
509 const int64_t conn_time{peer[
"conntime"].getInt<int64_t>()};
510 const int64_t last_blck{peer[
"last_block"].getInt<int64_t>()};
511 const int64_t last_recv{peer[
"lastrecv"].getInt<int64_t>()};
512 const int64_t last_send{peer[
"lastsend"].getInt<int64_t>()};
513 const int64_t last_trxn{peer[
"last_transaction"].getInt<int64_t>()};
514 const double min_ping{peer[
"minping"].isNull() ? -1 : peer[
"minping"].get_real()};
515 const double ping{peer[
"pingtime"].isNull() ? -1 : peer[
"pingtime"].get_real()};
516 const std::string addr{peer[
"addr"].get_str()};
517 const std::string age{conn_time == 0 ?
"" :
ToString((time_now - conn_time) / 60)};
518 const std::string sub_version{peer[
"subver"].get_str()};
519 const std::string transport{peer[
"transport_protocol_type"].isNull() ?
"v1" : peer[
"transport_protocol_type"].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, 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});
539 result +=
strprintf(
"<-> type net v mping ping send recv txn blk hb %*s%*s%*s ",
546 std::string version{
ToString(peer.version) + peer.sub_version};
548 "%3s %6s %5s %2s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
549 peer.is_outbound ?
"out" :
"in",
552 (peer.transport_protocol_type.size() == 2 && peer.transport_protocol_type[0] ==
'v') ? peer.transport_protocol_type[1] :
' ',
555 peer.last_send ?
ToString(time_now - peer.last_send) :
"",
556 peer.last_recv ?
ToString(time_now - peer.last_recv) :
"",
557 peer.last_trxn ?
ToString((time_now - peer.last_trxn) / 60) : peer.is_tx_relay ?
"" :
"*",
558 peer.last_blck ?
ToString((time_now - peer.last_blck) / 60) :
"",
559 strprintf(
"%s%s", peer.is_bip152_hb_to ?
"." :
" ", peer.is_bip152_hb_from ?
"*" :
" "),
561 peer.addr_processed ?
ToString(peer.addr_processed) : peer.is_addr_relay_enabled ?
"" :
".",
563 peer.addr_rate_limited ?
ToString(peer.addr_rate_limited) :
"",
579 std::vector<int8_t> reachable_networks;
580 for (
const UniValue& network : networkinfo[
"networks"].getValues()) {
581 if (network[
"reachable"].get_bool()) {
582 const std::string& network_name{network[
"name"].get_str()};
585 result +=
strprintf(
"%8s", network_name);
586 reachable_networks.push_back(network_id);
591 if (
m_counts.at(2).at(network_id) == 0)
continue;
593 reachable_networks.push_back(network_id);
596 result +=
" total block";
599 const std::array rows{
"in",
"out",
"total"};
600 for (
size_t i = 0; i < rows.size(); ++i) {
602 for (int8_t n : reachable_networks) {
613 result +=
"\n\nLocal addresses";
614 const std::vector<UniValue>& local_addrs{networkinfo[
"localaddresses"].getValues()};
615 if (local_addrs.empty()) {
618 size_t max_addr_size{0};
619 for (
const UniValue& addr : local_addrs) {
620 max_addr_size = std::max(addr[
"address"].get_str().length() + 1, max_addr_size);
622 for (
const UniValue& addr : local_addrs) {
623 result +=
strprintf(
"\n%-*s port %6i score %6i", max_addr_size, addr[
"address"].get_str(), addr[
"port"].getInt<int>(), addr[
"score"].getInt<int>());
631 "-netinfo level|\"help\" \n\n"
632 "Returns a network peer connections dashboard with information from the remote server.\n"
633 "This human-readable interface will change regularly and is not intended to be a stable API.\n"
634 "Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n"
636 "Pass \"help\" to see this detailed help documentation.\n"
637 "If more than one argument is passed, only the first one is read and parsed.\n"
638 "Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n"
640 +
strprintf(
"1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n",
MAX_DETAIL_LEVEL) +
641 " 0 - Peer counts for each reachable network as well as for block relay peers\n"
642 " and manual peers, and the list of local addresses and ports\n"
643 " 1 - Like 0 but preceded by a peers listing (without address and version columns)\n"
644 " 2 - Like 1 but with an address column\n"
645 " 3 - Like 1 but with a version column\n"
646 " 4 - Like 1 but with both address and version columns\n"
647 "2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n"
649 +
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) +
650 " Column Description\n"
651 " ------ -----------\n"
653 " \"in\" - inbound connections are those initiated by the peer\n"
654 " \"out\" - outbound connections are those initiated by us\n"
655 " type Type of peer connection\n"
656 " \"full\" - full relay, the default\n"
657 " \"block\" - block relay; like full relay but does not relay transactions or addresses\n"
658 " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n"
659 " \"feeler\" - short-lived connection for testing addresses\n"
660 " \"addr\" - address fetch; short-lived connection for requesting addresses\n"
661 " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", \"cjdns\", or \"npr\" (not publicly routable))\n"
662 " v Version of transport protocol used for the connection\n"
663 " mping Minimum observed ping time, in milliseconds (ms)\n"
664 " ping Last observed ping time, in milliseconds (ms)\n"
665 " send Time since last message sent to the peer, in seconds\n"
666 " recv Time since last message received from the peer, in seconds\n"
667 " txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n"
668 " \"*\" - we do not relay transactions to this peer (relaytxes is false)\n"
669 " blk Time since last novel block passing initial validity checks received from the peer, in minutes\n"
670 " hb High-bandwidth BIP152 compact block relay\n"
671 " \".\" (to) - we selected the peer as a high-bandwidth peer\n"
672 " \"*\" (from) - the peer selected us as a high-bandwidth peer\n"
673 " addrp Total number of addresses processed, excluding those dropped due to rate limiting\n"
674 " \".\" - we do not relay addresses to this peer (addr_relay_enabled is false)\n"
675 " addrl Total number of addresses dropped due to rate limiting\n"
676 " age Duration of connection to the peer, in minutes\n"
677 " asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n"
678 " peer selection (only displayed if the -asmap config option is set)\n"
679 " id Peer index, in increasing order of peer connections since node startup\n"
680 " address IP address and port of the peer\n"
681 " version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n"
682 "* The peer counts table displays the number of peers for each reachable network as well as\n"
683 " the number of block relay peers and manual peers.\n\n"
684 "* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n"
686 "Peer counts table of reachable networks and list of local addresses\n"
687 "> bitcoin-cli -netinfo\n\n"
688 "The same, preceded by a peers listing without address and version columns\n"
689 "> bitcoin-cli -netinfo 1\n\n"
692 "Full live dashboard, adjust --interval or --no-title as needed (Linux)\n"
695 "> bitcoin-cli -netinfo help\n"};
761 evhttp_connection_set_timeout(evcon.get(), timeout);
766 constexpr
int YEAR_IN_SECONDS = 31556952;
767 evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
773 if (req ==
nullptr) {
774 throw std::runtime_error(
"create http request failed");
781 bool failedToGetAuthCookie =
false;
785 failedToGetAuthCookie =
true;
791 struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get());
793 evhttp_add_header(output_headers,
"Host", host.c_str());
794 evhttp_add_header(output_headers,
"Connection",
"close");
795 evhttp_add_header(output_headers,
"Content-Type",
"application/json");
800 struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get());
802 evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
805 std::string endpoint =
"/";
807 char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(),
false);
809 endpoint =
"/wallet/" + std::string(encodedURI);
815 int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, endpoint.c_str());
821 event_base_dispatch(base.get());
823 if (response.
status == 0) {
824 std::string responseErrorMessage;
825 if (response.
error != -1) {
829 "Make sure the bitcoind server is running and that you are connecting to the correct RPC port.\n"
830 "Use \"bitcoin-cli -help\" for more info.",
831 host, port, responseErrorMessage));
833 if (failedToGetAuthCookie) {
835 "Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)",
838 throw std::runtime_error(
"Authorization failed: Incorrect rpcuser or rpcpassword");
841 throw std::runtime_error(
strprintf(
"Server response: %s", response.
body));
843 throw std::runtime_error(
strprintf(
"server returned HTTP error %d", response.
status));
844 else if (response.
body.empty())
845 throw std::runtime_error(
"no response from server");
849 if (!valReply.read(response.
body))
850 throw std::runtime_error(
"couldn't parse reply from server");
853 throw std::runtime_error(
"expected reply to have result, error and id properties");
873 const auto deadline{std::chrono::steady_clock::now() + 1s * timeout};
877 response =
CallRPC(rh, strMethod,
args, rpcwallet);
879 const UniValue& error = response.find_value(
"error");
886 if (fWait && (timeout <= 0 || std::chrono::steady_clock::now() < deadline)) {
899 if (result.
isNull())
return;
912 if (err_msg.
isStr()) {
916 strPrint +=
"\nTry adding \"-rpcwallet=<filename>\" option to bitcoin-cli command line.";
921 nRet = abs(error[
"code"].getInt<int>());
934 if (!
listwallets.find_value(
"error").isNull())
return;
936 if (wallets.
size() <= 1)
return;
940 const std::string& wallet_name =
wallet.get_str();
943 balances.
pushKV(wallet_name, balance);
945 result.
pushKV(
"balances", balances);
956 if (progress < 0 || progress > 1)
return;
958 static constexpr
double INCREMENT{0.05};
959 static const std::string COMPLETE_BAR{
"\u2592"};
960 static const std::string INCOMPLETE_BAR{
"\u2591"};
962 for (
int i = 0; i < progress / INCREMENT; ++i) {
963 progress_bar += COMPLETE_BAR;
966 for (
int i = 0; i < (1 - progress) / INCREMENT; ++i) {
967 progress_bar += INCOMPLETE_BAR;
980 std::string RESET, GREEN, BLUE, YELLOW, MAGENTA, CYAN;
981 bool should_colorize =
false;
984 if (isatty(fileno(stdout))) {
986 should_colorize =
true;
992 if (color ==
"always") {
993 should_colorize =
true;
994 }
else if (color ==
"never") {
995 should_colorize =
false;
996 }
else if (color !=
"auto") {
997 throw std::runtime_error(
"Invalid value for -color option. Valid values: always, auto, never.");
1001 if (should_colorize) {
1005 YELLOW =
"\x1B[33m";
1006 MAGENTA =
"\x1B[35m";
1010 std::string result_string =
strprintf(
"%sChain: %s%s\n", BLUE, result[
"chain"].getValStr(), RESET);
1011 result_string +=
strprintf(
"Blocks: %s\n", result[
"blocks"].getValStr());
1012 result_string +=
strprintf(
"Headers: %s\n", result[
"headers"].getValStr());
1014 const double ibd_progress{result[
"verificationprogress"].
get_real()};
1015 std::string ibd_progress_bar;
1017 if (ibd_progress < 0.99) {
1020 ibd_progress_bar +=
" ";
1023 result_string +=
strprintf(
"Verification progress: %s%.4f%%\n", ibd_progress_bar, ibd_progress * 100);
1024 result_string +=
strprintf(
"Difficulty: %s\n\n", result[
"difficulty"].getValStr());
1027 "%sNetwork: in %s, out %s, total %s%s\n",
1029 result[
"connections"][
"in"].getValStr(),
1030 result[
"connections"][
"out"].getValStr(),
1031 result[
"connections"][
"total"].getValStr(),
1033 result_string +=
strprintf(
"Version: %s\n", result[
"version"].getValStr());
1034 result_string +=
strprintf(
"Time offset (s): %s\n", result[
"timeoffset"].getValStr());
1037 std::map<std::string, std::vector<std::string>> proxy_networks;
1038 std::vector<std::string> ordered_proxies;
1040 for (
const UniValue& network : result[
"networks"].getValues()) {
1041 const std::string proxy = network[
"proxy"].getValStr();
1042 if (proxy.empty())
continue;
1044 if (proxy_networks.find(proxy) == proxy_networks.end()) ordered_proxies.push_back(proxy);
1046 proxy_networks[proxy].push_back(network[
"name"].getValStr());
1049 std::vector<std::string> formatted_proxies;
1050 formatted_proxies.reserve(ordered_proxies.size());
1051 for (
const std::string& proxy : ordered_proxies) {
1052 formatted_proxies.emplace_back(
strprintf(
"%s (%s)", proxy,
Join(proxy_networks.find(proxy)->second,
", ")));
1054 result_string +=
strprintf(
"Proxies: %s\n", formatted_proxies.empty() ?
"n/a" :
Join(formatted_proxies,
", "));
1056 result_string +=
strprintf(
"Min tx relay fee rate (%s/kvB): %s\n\n",
CURRENCY_UNIT, result[
"relayfee"].getValStr());
1058 if (!result[
"has_wallet"].isNull()) {
1059 const std::string walletname = result[
"walletname"].
getValStr();
1060 result_string +=
strprintf(
"%sWallet: %s%s\n", MAGENTA, walletname.empty() ?
"\"\"" : walletname, RESET);
1062 result_string +=
strprintf(
"Keypool size: %s\n", result[
"keypoolsize"].getValStr());
1063 if (!result[
"unlocked_until"].isNull()) {
1064 result_string +=
strprintf(
"Unlocked until: %s\n", result[
"unlocked_until"].getValStr());
1066 result_string +=
strprintf(
"Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n",
CURRENCY_UNIT, result[
"paytxfee"].getValStr());
1068 if (!result[
"balance"].isNull()) {
1069 result_string +=
strprintf(
"%sBalance:%s %s\n\n", CYAN, RESET, result[
"balance"].getValStr());
1072 if (!result[
"balances"].isNull()) {
1073 result_string +=
strprintf(
"%sBalances%s\n", CYAN, RESET);
1075 size_t max_balance_length{10};
1077 for (
const std::string&
wallet : result[
"balances"].getKeys()) {
1078 max_balance_length = std::max(result[
"balances"][
wallet].getValStr().length(), max_balance_length);
1081 for (
const std::string&
wallet : result[
"balances"].getKeys()) {
1084 result[
"balances"][
wallet].getValStr(),
1087 result_string +=
"\n";
1090 const std::string warnings{result[
"warnings"].
getValStr()};
1091 result_string +=
strprintf(
"%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ?
"(none)" : warnings);
1093 result.
setStr(result_string);
1102 std::optional<std::string> wallet_name{};
1115 if (
args.size() > 2)
throw std::runtime_error(
"too many arguments (maximum 2 for nblocks and maxtries)");
1116 if (
args.size() == 0) {
1118 }
else if (
args.at(0) ==
"0") {
1119 throw std::runtime_error(
"the first argument (number of blocks to generate, default: " +
DEFAULT_NBLOCKS +
") must be an integer value greater than zero");
1121 args.emplace(
args.begin() + 1, address);
1134 std::string rpcPass;
1138 fputs(
"RPC password> ", stderr);
1141 if (!std::getline(std::cin, rpcPass)) {
1142 throw std::runtime_error(
"-stdinrpcpass specified but failed to read from standard input");
1145 fputc(
'\n', stdout);
1149 std::vector<std::string>
args = std::vector<std::string>(&argv[1], &argv[argc]);
1152 std::string walletPass;
1153 if (
args.size() < 1 ||
args[0].substr(0, 16) !=
"walletpassphrase") {
1154 throw std::runtime_error(
"-stdinwalletpassphrase is only applicable for walletpassphrase(change)");
1157 fputs(
"Wallet passphrase> ", stderr);
1160 if (!std::getline(std::cin, walletPass)) {
1161 throw std::runtime_error(
"-stdinwalletpassphrase specified but failed to read from standard input");
1164 fputc(
'\n', stdout);
1166 args.insert(
args.begin() + 1, walletPass);
1171 while (std::getline(std::cin, line)) {
1172 args.push_back(line);
1175 fputc(
'\n', stdout);
1178 std::unique_ptr<BaseRequestHandler> rh;
1183 if (!
args.empty() &&
args.at(0) ==
"help") {
1201 if (
args.size() < 1) {
1202 throw std::runtime_error(
"too few parameters (need at least command)");
1209 std::optional<std::string> wallet_name{};
1229 }
catch (
const std::exception& e) {
1230 strPrint = std::string(
"error: ") + e.what();
1231 nRet = EXIT_FAILURE;
1246 common::WinCmdLineArgs winArgs;
1247 std::tie(argc, argv) = winArgs.get();
1251 tfm::format(std::cerr,
"Error: Initializing networking failed\n");
1252 return EXIT_FAILURE;
1261 catch (
const std::exception& e) {
1263 return EXIT_FAILURE;
1266 return EXIT_FAILURE;
1273 catch (
const std::exception& e) {
bool HelpRequested(const ArgsManager &args)
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
bool CheckDataDirOption(const ArgsManager &args)
const char *const BITCOIN_CONF_FILENAME
bool IsSwitchChar(char c)
static const char DEFAULT_RPCCONNECT[]
static constexpr int8_t UNKNOWN_NETWORK
static constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT
static const int CONTINUE_EXECUTION
static int AppInitRPC(int argc, char *argv[])
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 std::array UNREACHABLE_NETWORK_IDS
static void http_error_cb(enum evhttp_request_error err, void *ctx)
static int CommandLineRPC(int argc, char *argv[])
static const int DEFAULT_HTTP_CLIENT_TIMEOUT
static void ParseGetInfoResult(UniValue &result)
ParseGetInfoResult takes in -getinfo result in UniValue object and parses it into a user friendly Uni...
static void http_request_done(struct evhttp_request *req, void *ctx)
static void ParseResult(const UniValue &result, std::string &strPrint)
Parse UniValue result to update the message to print to std::cout.
static const std::string DEFAULT_NBLOCKS
Default number of blocks to generate for RPC generatetoaddress.
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.
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 GetWalletBalances(UniValue &result)
GetWalletBalances calls listwallets; if more than one wallet is loaded, it then fetches mine....
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
static constexpr std::array NETWORKS
static void SetupCliArgs(ArgsManager &argsman)
static const std::string DEFAULT_COLOR_SETTING
Default -color setting.
std::chrono::system_clock CliClock
static constexpr std::array NETWORK_SHORT_NAMES
static std::string http_errorstring(int code)
static const bool DEFAULT_NAMED
static void GetProgressBar(double progress, std::string &progress_bar)
GetProgressBar constructs a progress bar with 5% intervals.
static UniValue CallRPC(BaseRequestHandler *rh, const std::string &strMethod, const std::vector< std::string > &args, const std::optional< std::string > &rpcwallet={})
event_set_log_callback & libevent_log_cb
static UniValue GetNewAddress()
Call RPC getnewaddress.
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
void SelectBaseParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain.
std::unique_ptr< CBaseChainParams > CreateBaseChainParams(const ChainType chain)
Port numbers for incoming Tor connections (8334, 18334, 38334, 18445) have been chosen arbitrarily to...
Process addrinfo requests.
UniValue ProcessReply(const UniValue &reply) override
int8_t NetworkStringToId(const std::string &str) const
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
@ ALLOW_ANY
disable validation
@ DISALLOW_NEGATION
disallow -nofoo syntax
ChainType GetChainType() const
Returns the appropriate chain type from the program arguments.
void ForceSetArg(const std::string &strArg, const std::string &strValue)
bool ParseParameters(int argc, const char *const argv[], std::string &error)
std::string GetHelpMessage() const
Get the help string.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
fs::path GetConfigFilePath() const
Return config file path (read-only)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Class that handles the conversion from a command-line to a JSON-RPC request, as well as converting ba...
virtual UniValue ProcessReply(const UniValue &batch_in)=0
virtual ~BaseRequestHandler()=default
virtual UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args)=0
CConnectionFailed(const std::string &msg)
Process default single requests.
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
UniValue ProcessReply(const UniValue &reply) override
Process RPC generatetoaddress request.
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
UniValue ProcessReply(const UniValue &reply) override
Process getinfo requests.
const int ID_BLOCKCHAININFO
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Create a simulated getinfo request.
UniValue ProcessReply(const UniValue &batch_in) override
Collect values from the batch and form a simulated getinfo reply.
Process netinfo requests.
uint8_t m_block_relay_peers_count
static constexpr uint8_t MAX_DETAIL_LEVEL
bool DetailsRequested() const
std::vector< Peer > m_peers
UniValue ProcessReply(const UniValue &batch_in) override
uint8_t m_details_level
Optional user-supplied arg to set dashboard details level.
size_t m_max_addr_rate_limited_length
size_t m_max_addr_processed_length
bool IsAddressSelected() const
std::string ConnectionTypeForNetinfo(const std::string &conn_type) const
bool IsVersionSelected() const
uint8_t m_manual_peers_count
const std::string m_help_doc
int8_t NetworkStringToId(const std::string &str) const
static constexpr int ID_PEERINFO
std::string ChainToString() const
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
std::array< std::array< uint16_t, NETWORKS.size()+1 >, 3 > m_counts
Peer counts by (in/out/total, networks/total)
static constexpr int ID_NETWORKINFO
std::string PingTimeToString(double seconds) const
void push_back(UniValue val)
const std::string & get_str() const
const UniValue & find_value(std::string_view key) const
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const UniValue & get_obj() const
const std::string & getValStr() const
const std::vector< UniValue > & getValues() const
void setStr(std::string str)
void pushKV(std::string key, UniValue val)
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert positional arguments to command-specific RPC representation.
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert named arguments to command-specific RPC representation.
std::string FormatFullVersion()
std::string LicenseInfo()
Returns licensing information (for -version)
raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg)
raii_evhttp_connection obtain_evhttp_connection_base(struct event_base *base, std::string host, uint16_t port)
raii_event_base obtain_event_base()
void PrintExceptionContinue(const std::exception *pex, std::string_view thread_name)
const std::string CURRENCY_UNIT
static std::string strRPCUserColonPass
static std::string PathToString(const path &path)
Convert path object to a byte string.
static RPCHelpMan listwallets()
RPCHelpMan getnewaddress()
std::vector< UniValue > JSONRPCProcessBatchReply(const UniValue &in)
Parse JSON-RPC batch reply into a vector.
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
UniValue JSONRPCRequestObj(const std::string &strMethod, const UniValue ¶ms, const UniValue &id)
JSON-RPC protocol.
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
static const uint64_t DEFAULT_MAX_TRIES
Default max iterations to try in RPC generatetodescriptor, generatetoaddress, and generateblock.
@ HTTP_SERVICE_UNAVAILABLE
@ HTTP_INTERNAL_SERVER_ERROR
@ RPC_WALLET_NOT_SPECIFIED
No wallet specified (error when there are multiple wallets loaded)
@ RPC_IN_WARMUP
Client still warming up.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Reply structure for request_done to fill in.
bool is_addr_relay_enabled
std::string transport_protocol_type
int64_t addr_rate_limited
bool operator<(const Peer &rhs) const
void UninterruptibleSleep(const std::chrono::microseconds &n)
const UniValue NullUniValue
std::string EncodeBase64(Span< const unsigned char > input)
bool ParseUInt8(std::string_view str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
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.
bool SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)
Splits socket address string into host string and port value.