6 #if defined(HAVE_CONFIG_H) 40 #include <event2/buffer.h> 41 #include <event2/keyvalq_struct.h> 58 static constexpr std::array
NETWORKS{
"ipv4",
"ipv6",
"onion",
"i2p",
"cjdns"};
78 argsman.
AddArg(
"-generate",
79 strprintf(
"Generate blocks, equivalent to RPC getnewaddress followed by RPC generatetoaddress. Optional positional integer " 80 "arguments are number of blocks to generate (default: %s) and maximum iterations to try (default: %s), equivalent to " 81 "RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000",
85 argsman.
AddArg(
"-getinfo",
"Get general information from the remote server. Note that unlike server-side RPC calls, the results of -getinfo is the result of multiple non-atomic requests. Some entries in the result 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);
86 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);
95 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);
99 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);
100 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);
101 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);
109 if (severity >= EVENT_LOG_ERR) {
110 throw std::runtime_error(
strprintf(
"libevent error: %s", msg));
123 std::runtime_error(msg)
137 tfm::format(std::cerr,
"Error parsing command line arguments: %s\n",
error);
147 "Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n" 148 "or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n" 149 "or: bitcoin-cli [options] help List commands\n" 150 "or: bitcoin-cli [options] help <command> Get help for a command\n";
156 tfm::format(std::cerr,
"Error: too few parameters\n");
162 tfm::format(std::cerr,
"Error: Specified data directory \"%s\" does not exist.\n",
gArgs.
GetArg(
"-datadir",
""));
172 }
catch (
const std::exception& e) {
193 case EVREQ_HTTP_TIMEOUT:
194 return "timeout reached";
196 return "EOF reached";
197 case EVREQ_HTTP_INVALID_HEADER:
198 return "error while reading header, or invalid header";
199 case EVREQ_HTTP_BUFFER_ERROR:
200 return "error encountered while reading or writing";
201 case EVREQ_HTTP_REQUEST_CANCEL:
202 return "request was canceled";
203 case EVREQ_HTTP_DATA_TOO_LONG:
204 return "response body is larger than allowed";
214 if (req ==
nullptr) {
222 reply->
status = evhttp_request_get_response_code(req);
224 struct evbuffer *buf = evhttp_request_get_input_buffer(req);
227 size_t size = evbuffer_get_length(buf);
228 const char *data = (
const char*)evbuffer_pullup(buf, size);
230 reply->
body = std::string(data, size);
231 evbuffer_drain(buf, size);
258 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
268 throw std::runtime_error(
"-addrinfo takes no arguments");
276 if (!reply[
"error"].isNull())
return reply;
277 const std::vector<UniValue>& nodes{reply[
"result"].
getValues()};
278 if (!nodes.empty() && nodes.at(0)[
"network"].isNull()) {
279 throw std::runtime_error(
"-addrinfo requires bitcoind server to be running v22.0 and up");
282 std::array<uint64_t,
NETWORKS.size()> counts{{}};
284 std::string network_name{
node[
"network"].get_str()};
287 ++counts.at(network_id);
292 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
293 addresses.pushKV(
NETWORKS[i], counts.at(i));
294 total += counts.at(i);
296 addresses.pushKV(
"total", total);
297 result.pushKV(
"addresses_known", addresses);
315 throw std::runtime_error(
"-getinfo takes no arguments");
348 result.
pushKV(
"connections", connections);
354 result.
pushKV(
"has_wallet",
true);
357 if (!batch[
ID_WALLETINFO][
"result"][
"unlocked_until"].isNull()) {
381 for (
size_t i = 0; i <
NETWORKS.size(); ++i) {
430 if (seconds < 0)
return "";
431 const double milliseconds{round(1000 * seconds)};
432 return milliseconds > 999999 ?
"-" :
ToString(milliseconds);
436 if (conn_type ==
"outbound-full-relay")
return "full";
437 if (conn_type ==
"block-relay-only")
return "block";
438 if (conn_type ==
"manual" || conn_type ==
"feeler")
return conn_type;
439 if (conn_type ==
"addr-fetch")
return "addr";
454 throw std::runtime_error(
strprintf(
"invalid -netinfo argument: %s\nFor more information, run: bitcoin-cli -netinfo help",
args.at(0)));
470 if (networkinfo[
"version"].getInt<int>() < 209900) {
471 throw std::runtime_error(
"-netinfo requires bitcoind server to be running v0.21.0 and up");
473 const int64_t time_now{TicksSinceEpoch<std::chrono::seconds>(CliClock::now())};
477 const std::string network{peer[
"network"].get_str()};
480 const bool is_outbound{!peer[
"inbound"].get_bool()};
481 const bool is_tx_relay{peer[
"relaytxes"].isNull() ? true : peer[
"relaytxes"].get_bool()};
482 const std::string conn_type{peer[
"connection_type"].get_str()};
483 ++
m_counts.at(is_outbound).at(network_id);
491 const int peer_id{peer[
"id"].getInt<
int>()};
492 const int mapped_as{peer[
"mapped_as"].isNull() ? 0 : peer[
"mapped_as"].getInt<
int>()};
493 const int version{peer[
"version"].getInt<
int>()};
494 const int64_t addr_processed{peer[
"addr_processed"].isNull() ? 0 : peer[
"addr_processed"].getInt<int64_t>()};
495 const int64_t addr_rate_limited{peer[
"addr_rate_limited"].isNull() ? 0 : peer[
"addr_rate_limited"].getInt<int64_t>()};
496 const int64_t conn_time{peer[
"conntime"].getInt<int64_t>()};
497 const int64_t last_blck{peer[
"last_block"].getInt<int64_t>()};
498 const int64_t last_recv{peer[
"lastrecv"].getInt<int64_t>()};
499 const int64_t last_send{peer[
"lastsend"].getInt<int64_t>()};
500 const int64_t last_trxn{peer[
"last_transaction"].getInt<int64_t>()};
501 const double min_ping{peer[
"minping"].isNull() ? -1 : peer[
"minping"].get_real()};
502 const double ping{peer[
"pingtime"].isNull() ? -1 : peer[
"pingtime"].get_real()};
503 const std::string addr{peer[
"addr"].get_str()};
504 const std::string age{conn_time == 0 ?
"" :
ToString((time_now - conn_time) / 60)};
505 const std::string sub_version{peer[
"subver"].get_str()};
506 const bool is_addr_relay_enabled{peer[
"addr_relay_enabled"].isNull() ? false : peer[
"addr_relay_enabled"].get_bool()};
507 const bool is_bip152_hb_from{peer[
"bip152_hb_from"].get_bool()};
508 const bool is_bip152_hb_to{peer[
"bip152_hb_to"].get_bool()};
509 m_peers.push_back({addr, sub_version, conn_type, network, 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});
525 result +=
strprintf(
"<-> type net mping ping send recv txn blk hb %*s%*s%*s ",
532 std::string version{
ToString(peer.version) + peer.sub_version};
534 "%3s %6s %5s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
535 peer.is_outbound ?
"out" :
"in",
540 peer.last_send ?
ToString(time_now - peer.last_send) :
"",
541 peer.last_recv ?
ToString(time_now - peer.last_recv) :
"",
542 peer.last_trxn ?
ToString((time_now - peer.last_trxn) / 60) : peer.is_tx_relay ?
"" :
"*",
543 peer.last_blck ?
ToString((time_now - peer.last_blck) / 60) :
"",
544 strprintf(
"%s%s", peer.is_bip152_hb_to ?
"." :
" ", peer.is_bip152_hb_from ?
"*" :
" "),
546 peer.addr_processed ?
ToString(peer.addr_processed) : peer.is_addr_relay_enabled ?
"" :
".",
548 peer.addr_rate_limited ?
ToString(peer.addr_rate_limited) :
"",
564 std::vector<int8_t> reachable_networks;
565 for (
const UniValue& network : networkinfo[
"networks"].getValues()) {
566 if (network[
"reachable"].get_bool()) {
567 const std::string& network_name{network[
"name"].get_str()};
570 result +=
strprintf(
"%8s", network_name);
571 reachable_networks.push_back(network_id);
574 result +=
" total block";
577 const std::array rows{
"in",
"out",
"total"};
578 for (
size_t i = 0; i < rows.size(); ++i) {
580 for (int8_t n : reachable_networks) {
591 result +=
"\n\nLocal addresses";
592 const std::vector<UniValue>& local_addrs{networkinfo[
"localaddresses"].getValues()};
593 if (local_addrs.empty()) {
596 size_t max_addr_size{0};
597 for (
const UniValue& addr : local_addrs) {
598 max_addr_size = std::max(addr[
"address"].get_str().length() + 1, max_addr_size);
600 for (
const UniValue& addr : local_addrs) {
601 result +=
strprintf(
"\n%-*s port %6i score %6i", max_addr_size, addr[
"address"].get_str(), addr[
"port"].getInt<int>(), addr[
"score"].getInt<int>());
609 "-netinfo level|\"help\" \n\n" 610 "Returns a network peer connections dashboard with information from the remote server.\n" 611 "This human-readable interface will change regularly and is not intended to be a stable API.\n" 612 "Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n" 614 "Pass \"help\" to see this detailed help documentation.\n" 615 "If more than one argument is passed, only the first one is read and parsed.\n" 616 "Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n" 618 +
strprintf(
"1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n",
MAX_DETAIL_LEVEL) +
619 " 0 - Peer counts for each reachable network as well as for block relay peers\n" 620 " and manual peers, and the list of local addresses and ports\n" 621 " 1 - Like 0 but preceded by a peers listing (without address and version columns)\n" 622 " 2 - Like 1 but with an address column\n" 623 " 3 - Like 1 but with a version column\n" 624 " 4 - Like 1 but with both address and version columns\n" 625 "2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n" 627 +
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) +
628 " Column Description\n" 629 " ------ -----------\n" 631 " \"in\" - inbound connections are those initiated by the peer\n" 632 " \"out\" - outbound connections are those initiated by us\n" 633 " type Type of peer connection\n" 634 " \"full\" - full relay, the default\n" 635 " \"block\" - block relay; like full relay but does not relay transactions or addresses\n" 636 " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n" 637 " \"feeler\" - short-lived connection for testing addresses\n" 638 " \"addr\" - address fetch; short-lived connection for requesting addresses\n" 639 " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", or \"cjdns\")\n" 640 " mping Minimum observed ping time, in milliseconds (ms)\n" 641 " ping Last observed ping time, in milliseconds (ms)\n" 642 " send Time since last message sent to the peer, in seconds\n" 643 " recv Time since last message received from the peer, in seconds\n" 644 " txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n" 645 " \"*\" - the peer requested we not relay transactions to it (relaytxes is false)\n" 646 " blk Time since last novel block passing initial validity checks received from the peer, in minutes\n" 647 " hb High-bandwidth BIP152 compact block relay\n" 648 " \".\" (to) - we selected the peer as a high-bandwidth peer\n" 649 " \"*\" (from) - the peer selected us as a high-bandwidth peer\n" 650 " addrp Total number of addresses processed, excluding those dropped due to rate limiting\n" 651 " \".\" - we do not relay addresses to this peer (addr_relay_enabled is false)\n" 652 " addrl Total number of addresses dropped due to rate limiting\n" 653 " age Duration of connection to the peer, in minutes\n" 654 " asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n" 655 " peer selection (only displayed if the -asmap config option is set)\n" 656 " id Peer index, in increasing order of peer connections since node startup\n" 657 " address IP address and port of the peer\n" 658 " version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n" 659 "* The peer counts table displays the number of peers for each reachable network as well as\n" 660 " the number of block relay peers and manual peers.\n\n" 661 "* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n" 663 "Peer counts table of reachable networks and list of local addresses\n" 664 "> bitcoin-cli -netinfo\n\n" 665 "The same, preceded by a peers listing without address and version columns\n" 666 "> bitcoin-cli -netinfo 1\n\n" 669 "Full live dashboard, adjust --interval or --no-title as needed (Linux)\n" 672 "> bitcoin-cli -netinfo help\n"};
738 evhttp_connection_set_timeout(evcon.get(), timeout);
743 constexpr
int YEAR_IN_SECONDS = 31556952;
744 evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
750 if (req ==
nullptr) {
751 throw std::runtime_error(
"create http request failed");
758 bool failedToGetAuthCookie =
false;
762 failedToGetAuthCookie =
true;
768 struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get());
770 evhttp_add_header(output_headers,
"Host", host.c_str());
771 evhttp_add_header(output_headers,
"Connection",
"close");
772 evhttp_add_header(output_headers,
"Content-Type",
"application/json");
777 struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get());
779 evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
782 std::string endpoint =
"/";
784 char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(),
false);
786 endpoint =
"/wallet/" + std::string(encodedURI);
792 int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, endpoint.c_str());
798 event_base_dispatch(base.get());
800 if (response.
status == 0) {
801 std::string responseErrorMessage;
802 if (response.
error != -1) {
805 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));
807 if (failedToGetAuthCookie) {
809 "Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)",
812 throw std::runtime_error(
"Authorization failed: Incorrect rpcuser or rpcpassword");
815 throw std::runtime_error(
strprintf(
"Server response: %s", response.
body));
817 throw std::runtime_error(
strprintf(
"server returned HTTP error %d", response.
status));
818 else if (response.
body.empty())
819 throw std::runtime_error(
"no response from server");
823 if (!valReply.read(response.
body))
824 throw std::runtime_error(
"couldn't parse reply from server");
827 throw std::runtime_error(
"expected reply to have result, error and id properties");
847 const auto deadline{std::chrono::steady_clock::now() + 1s * timeout};
851 response =
CallRPC(rh, strMethod,
args, rpcwallet);
860 if (fWait && (timeout <= 0 || std::chrono::steady_clock::now() < deadline)) {
873 if (result.
isNull())
return;
880 if (
error.isObject()) {
886 if (err_msg.
isStr()) {
890 strPrint +=
"\nTry adding \"-rpcwallet=<filename>\" option to bitcoin-cli command line.";
895 nRet = abs(
error[
"code"].getInt<int>());
910 if (wallets.
size() <= 1)
return;
914 const std::string& wallet_name =
wallet.get_str();
917 balances.
pushKV(wallet_name, balance);
919 result.
pushKV(
"balances", balances);
930 if (progress < 0 || progress > 1)
return;
932 static constexpr
double INCREMENT{0.05};
933 static const std::string COMPLETE_BAR{
"\u2592"};
934 static const std::string INCOMPLETE_BAR{
"\u2591"};
936 for (
int i = 0; i < progress / INCREMENT; ++i) {
937 progress_bar += COMPLETE_BAR;
940 for (
int i = 0; i < (1 - progress) / INCREMENT; ++i) {
941 progress_bar += INCOMPLETE_BAR;
952 if (!
find_value(result,
"error").isNull())
return;
954 std::string RESET, GREEN, BLUE, YELLOW, MAGENTA, CYAN;
955 bool should_colorize =
false;
958 if (isatty(fileno(stdout))) {
960 should_colorize =
true;
966 if (color ==
"always") {
967 should_colorize =
true;
968 }
else if (color ==
"never") {
969 should_colorize =
false;
970 }
else if (color !=
"auto") {
971 throw std::runtime_error(
"Invalid value for -color option. Valid values: always, auto, never.");
975 if (should_colorize) {
980 MAGENTA =
"\x1B[35m";
984 std::string result_string =
strprintf(
"%sChain: %s%s\n", BLUE, result[
"chain"].getValStr(), RESET);
985 result_string +=
strprintf(
"Blocks: %s\n", result[
"blocks"].getValStr());
986 result_string +=
strprintf(
"Headers: %s\n", result[
"headers"].getValStr());
988 const double ibd_progress{result[
"verificationprogress"].
get_real()};
989 std::string ibd_progress_bar;
991 if (ibd_progress < 0.99) {
994 ibd_progress_bar +=
" ";
997 result_string +=
strprintf(
"Verification progress: %s%.4f%%\n", ibd_progress_bar, ibd_progress * 100);
998 result_string +=
strprintf(
"Difficulty: %s\n\n", result[
"difficulty"].getValStr());
1001 "%sNetwork: in %s, out %s, total %s%s\n",
1003 result[
"connections"][
"in"].getValStr(),
1004 result[
"connections"][
"out"].getValStr(),
1005 result[
"connections"][
"total"].getValStr(),
1007 result_string +=
strprintf(
"Version: %s\n", result[
"version"].getValStr());
1008 result_string +=
strprintf(
"Time offset (s): %s\n", result[
"timeoffset"].getValStr());
1011 std::map<std::string, std::vector<std::string>> proxy_networks;
1012 std::vector<std::string> ordered_proxies;
1014 for (
const UniValue& network : result[
"networks"].getValues()) {
1015 const std::string proxy = network[
"proxy"].getValStr();
1016 if (proxy.empty())
continue;
1018 if (proxy_networks.find(proxy) == proxy_networks.end()) ordered_proxies.push_back(proxy);
1020 proxy_networks[proxy].push_back(network[
"name"].getValStr());
1023 std::vector<std::string> formatted_proxies;
1024 for (
const std::string& proxy : ordered_proxies) {
1025 formatted_proxies.emplace_back(
strprintf(
"%s (%s)", proxy,
Join(proxy_networks.find(proxy)->second,
", ")));
1027 result_string +=
strprintf(
"Proxies: %s\n", formatted_proxies.empty() ?
"n/a" :
Join(formatted_proxies,
", "));
1029 result_string +=
strprintf(
"Min tx relay fee rate (%s/kvB): %s\n\n",
CURRENCY_UNIT, result[
"relayfee"].getValStr());
1031 if (!result[
"has_wallet"].isNull()) {
1032 const std::string walletname = result[
"walletname"].
getValStr();
1033 result_string +=
strprintf(
"%sWallet: %s%s\n", MAGENTA, walletname.empty() ?
"\"\"" : walletname, RESET);
1035 result_string +=
strprintf(
"Keypool size: %s\n", result[
"keypoolsize"].getValStr());
1036 if (!result[
"unlocked_until"].isNull()) {
1037 result_string +=
strprintf(
"Unlocked until: %s\n", result[
"unlocked_until"].getValStr());
1039 result_string +=
strprintf(
"Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n",
CURRENCY_UNIT, result[
"paytxfee"].getValStr());
1041 if (!result[
"balance"].isNull()) {
1042 result_string +=
strprintf(
"%sBalance:%s %s\n\n", CYAN, RESET, result[
"balance"].getValStr());
1045 if (!result[
"balances"].isNull()) {
1046 result_string +=
strprintf(
"%sBalances%s\n", CYAN, RESET);
1048 size_t max_balance_length{10};
1050 for (
const std::string&
wallet : result[
"balances"].getKeys()) {
1051 max_balance_length = std::max(result[
"balances"][
wallet].getValStr().length(), max_balance_length);
1054 for (
const std::string&
wallet : result[
"balances"].getKeys()) {
1057 result[
"balances"][
wallet].getValStr(),
1060 result_string +=
"\n";
1063 const std::string warnings{result[
"warnings"].
getValStr()};
1064 result_string +=
strprintf(
"%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ?
"(none)" : warnings);
1066 result.
setStr(result_string);
1075 std::optional<std::string> wallet_name{};
1088 if (
args.size() > 2)
throw std::runtime_error(
"too many arguments (maximum 2 for nblocks and maxtries)");
1089 if (
args.size() == 0) {
1091 }
else if (
args.at(0) ==
"0") {
1092 throw std::runtime_error(
"the first argument (number of blocks to generate, default: " +
DEFAULT_NBLOCKS +
") must be an integer value greater than zero");
1094 args.emplace(
args.begin() + 1, address);
1107 std::string rpcPass;
1111 fputs(
"RPC password> ", stderr);
1114 if (!std::getline(std::cin, rpcPass)) {
1115 throw std::runtime_error(
"-stdinrpcpass specified but failed to read from standard input");
1118 fputc(
'\n', stdout);
1122 std::vector<std::string>
args = std::vector<std::string>(&argv[1], &argv[argc]);
1125 std::string walletPass;
1126 if (
args.size() < 1 ||
args[0].substr(0, 16) !=
"walletpassphrase") {
1127 throw std::runtime_error(
"-stdinwalletpassphrase is only applicable for walletpassphrase(change)");
1130 fputs(
"Wallet passphrase> ", stderr);
1133 if (!std::getline(std::cin, walletPass)) {
1134 throw std::runtime_error(
"-stdinwalletpassphrase specified but failed to read from standard input");
1137 fputc(
'\n', stdout);
1139 args.insert(
args.begin() + 1, walletPass);
1144 while (std::getline(std::cin, line)) {
1145 args.push_back(line);
1148 fputc(
'\n', stdout);
1151 std::unique_ptr<BaseRequestHandler> rh;
1156 if (!
args.empty() &&
args.at(0) ==
"help") {
1164 if (
error.isNull()) {
1174 if (
args.size() < 1) {
1175 throw std::runtime_error(
"too few parameters (need at least command)");
1182 std::optional<std::string> wallet_name{};
1189 if (
error.isNull()) {
1202 }
catch (
const std::exception& e) {
1203 strPrint = std::string(
"error: ") + e.what();
1204 nRet = EXIT_FAILURE;
1219 util::WinCmdLineArgs winArgs;
1220 std::tie(argc, argv) = winArgs.get();
1224 tfm::format(std::cerr,
"Error: Initializing networking failed\n");
1225 return EXIT_FAILURE;
1234 catch (
const std::exception& e) {
1236 return EXIT_FAILURE;
1239 return EXIT_FAILURE;
1246 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 setStr(const std::string &val)
std::unique_ptr< CBaseChainParams > CreateBaseChainParams(const std::string &chain)
Port numbers for incoming Tor connections (8334, 18334, 38334, 18445) have been chosen arbitrarily to...
fs::path GetPathArg(std::string arg, const fs::path &default_value={}) const
Return path argument or default value.
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
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
static int AppInitRPC(int argc, char *argv[])
static const std::string REGTEST
std::chrono::system_clock CliClock
static std::string strRPCUserColonPass
static constexpr int ID_NETWORKINFO
bool HelpRequested(const ArgsManager &args)
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
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.
const UniValue & find_value(const UniValue &obj, const std::string &name)
std::string GetHelpMessage() const
Get the help string.
static const std::string MAIN
Chain name strings.
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
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[]
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
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.
bool CheckDataDirOption()
static constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT
static secp256k1_context * ctx
Process netinfo requests.
Process addrinfo requests.
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
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 PrintExceptionContinue(const std::exception *pex, std::string_view thread_name)
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...
std::string getnewaddress(wallet::CWallet &w)
Returns a new address from the wallet.
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)
const char *const BITCOIN_CONF_FILENAME
bool IsVersionSelected() const
static constexpr std::array NETWORKS
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 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)
const std::string m_help_doc
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
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 std::string TESTNET
static const bool DEFAULT_NAMED
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
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.
bool IsSwitchChar(char c)
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
void SelectBaseParams(const std::string &chain)
Sets the params returned by Params() to those for the given network.
bool IsAddressSelected() const
bool is_addr_relay_enabled
static RPCHelpMan listwallets()
std::string PingTimeToString(double seconds) const
Process getinfo requests.
bool error(const char *fmt, const Args &... args)
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
static const std::string SIGNET
fs::path GetConfigFile(const fs::path &configuration_file_path)
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)
Reply structure for request_done to fill in.
UniValue ProcessReply(const UniValue &reply) override
std::string(const std::string &url_encoded) UrlDecodeFn
void SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)