Bitcoin Core  22.99.0
P2P Digital Currency
bitcoin-cli.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
8 #endif
9 
10 #include <chainparamsbase.h>
11 #include <clientversion.h>
12 #include <policy/feerate.h>
13 #include <rpc/client.h>
14 #include <rpc/mining.h>
15 #include <rpc/protocol.h>
16 #include <rpc/request.h>
17 #include <tinyformat.h>
18 #include <util/strencodings.h>
19 #include <util/system.h>
20 #include <util/translation.h>
21 #include <util/url.h>
22 
23 #include <algorithm>
24 #include <cmath>
25 #include <functional>
26 #include <memory>
27 #include <optional>
28 #include <stdio.h>
29 #include <string>
30 #include <tuple>
31 
32 #ifndef WIN32
33 #include <unistd.h>
34 #endif
35 
36 #include <event2/buffer.h>
37 #include <event2/keyvalq_struct.h>
38 #include <support/events.h>
39 
40 #include <univalue.h>
41 #include <compat/stdin.h>
42 
43 const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
45 
46 static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
47 static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
48 static constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT = 0;
49 static const bool DEFAULT_NAMED=false;
50 static const int CONTINUE_EXECUTION=-1;
51 static constexpr int8_t UNKNOWN_NETWORK{-1};
52 static constexpr std::array NETWORKS{"ipv4", "ipv6", "onion", "i2p", "cjdns"};
53 
55 static const std::string DEFAULT_NBLOCKS = "1";
56 
58 static const std::string DEFAULT_COLOR_SETTING{"auto"};
59 
60 static void SetupCliArgs(ArgsManager& argsman)
61 {
62  SetupHelpOptions(argsman);
63 
64  const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
65  const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
66  const auto signetBaseParams = CreateBaseChainParams(CBaseChainParams::SIGNET);
67  const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
68 
69  argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
70  argsman.AddArg("-conf=<file>", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
71  argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
72  argsman.AddArg("-generate", strprintf("Generate blocks immediately, equivalent to RPC getnewaddress followed by RPC generatetoaddress. Optional positional integer arguments are number of blocks to generate (default: %s) and maximum iterations to try (default: %s), equivalent to RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000", DEFAULT_NBLOCKS, DEFAULT_MAX_TRIES), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
73  argsman.AddArg("-addrinfo", "Get the number of addresses known to the node, per network and total.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
74  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);
75  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);
76 
78  argsman.AddArg("-color=<when>", strprintf("Color setting for CLI output (default: %s). Valid values: always, auto (add color codes when standard output is connected to a terminal and OS is not WIN32), never.", DEFAULT_COLOR_SETTING), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
79  argsman.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
80  argsman.AddArg("-rpcclienttimeout=<n>", strprintf("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
81  argsman.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
82  argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
83  argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
84  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);
85  argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
86  argsman.AddArg("-rpcwait", "Wait for RPC server to start", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
87  argsman.AddArg("-rpcwaittimeout=<n>", strprintf("Timeout in seconds to wait for the RPC server to start, or 0 for no timeout. (default: %d)", DEFAULT_WAIT_CLIENT_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
88  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);
89  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);
90  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);
91  argsman.AddArg("-stdinwalletpassphrase", "Read wallet passphrase from standard input as a single line. When combined with -stdin, the first line from standard input is used for the wallet passphrase.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
92 }
93 
95 static void libevent_log_cb(int severity, const char *msg)
96 {
97  // Ignore everything other than errors
98  if (severity >= EVENT_LOG_ERR) {
99  throw std::runtime_error(strprintf("libevent error: %s", msg));
100  }
101 }
102 
103 //
104 // Exception thrown on connection error. This error is used to determine
105 // when to wait if -rpcwait is given.
106 //
107 class CConnectionFailed : public std::runtime_error
108 {
109 public:
110 
111  explicit inline CConnectionFailed(const std::string& msg) :
112  std::runtime_error(msg)
113  {}
114 
115 };
116 
117 //
118 // This function returns either one of EXIT_ codes when it's expected to stop the process or
119 // CONTINUE_EXECUTION when it's expected to continue further.
120 //
121 static int AppInitRPC(int argc, char* argv[])
122 {
124  std::string error;
125  if (!gArgs.ParseParameters(argc, argv, error)) {
126  tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);
127  return EXIT_FAILURE;
128  }
129  if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
130  std::string strUsage = PACKAGE_NAME " RPC client version " + FormatFullVersion() + "\n";
131  if (!gArgs.IsArgSet("-version")) {
132  strUsage += "\n"
133  "Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n"
134  "or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n"
135  "or: bitcoin-cli [options] help List commands\n"
136  "or: bitcoin-cli [options] help <command> Get help for a command\n";
137  strUsage += "\n" + gArgs.GetHelpMessage();
138  }
139 
140  tfm::format(std::cout, "%s", strUsage);
141  if (argc < 2) {
142  tfm::format(std::cerr, "Error: too few parameters\n");
143  return EXIT_FAILURE;
144  }
145  return EXIT_SUCCESS;
146  }
147  if (!CheckDataDirOption()) {
148  tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""));
149  return EXIT_FAILURE;
150  }
151  if (!gArgs.ReadConfigFiles(error, true)) {
152  tfm::format(std::cerr, "Error reading configuration file: %s\n", error);
153  return EXIT_FAILURE;
154  }
155  // Check for chain settings (BaseParams() calls are only valid after this clause)
156  try {
158  } catch (const std::exception& e) {
159  tfm::format(std::cerr, "Error: %s\n", e.what());
160  return EXIT_FAILURE;
161  }
162  return CONTINUE_EXECUTION;
163 }
164 
165 
167 struct HTTPReply
168 {
169  HTTPReply(): status(0), error(-1) {}
170 
171  int status;
172  int error;
173  std::string body;
174 };
175 
176 static std::string http_errorstring(int code)
177 {
178  switch(code) {
179 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
180  case EVREQ_HTTP_TIMEOUT:
181  return "timeout reached";
182  case EVREQ_HTTP_EOF:
183  return "EOF reached";
184  case EVREQ_HTTP_INVALID_HEADER:
185  return "error while reading header, or invalid header";
186  case EVREQ_HTTP_BUFFER_ERROR:
187  return "error encountered while reading or writing";
188  case EVREQ_HTTP_REQUEST_CANCEL:
189  return "request was canceled";
190  case EVREQ_HTTP_DATA_TOO_LONG:
191  return "response body is larger than allowed";
192 #endif
193  default:
194  return "unknown";
195  }
196 }
197 
198 static void http_request_done(struct evhttp_request *req, void *ctx)
199 {
200  HTTPReply *reply = static_cast<HTTPReply*>(ctx);
201 
202  if (req == nullptr) {
203  /* If req is nullptr, it means an error occurred while connecting: the
204  * error code will have been passed to http_error_cb.
205  */
206  reply->status = 0;
207  return;
208  }
209 
210  reply->status = evhttp_request_get_response_code(req);
211 
212  struct evbuffer *buf = evhttp_request_get_input_buffer(req);
213  if (buf)
214  {
215  size_t size = evbuffer_get_length(buf);
216  const char *data = (const char*)evbuffer_pullup(buf, size);
217  if (data)
218  reply->body = std::string(data, size);
219  evbuffer_drain(buf, size);
220  }
221 }
222 
223 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
224 static void http_error_cb(enum evhttp_request_error err, void *ctx)
225 {
226  HTTPReply *reply = static_cast<HTTPReply*>(ctx);
227  reply->error = err;
228 }
229 #endif
230 
235 {
236 public:
237  virtual ~BaseRequestHandler() {}
238  virtual UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) = 0;
239  virtual UniValue ProcessReply(const UniValue &batch_in) = 0;
240 };
241 
244 {
245 private:
246  int8_t NetworkStringToId(const std::string& str) const
247  {
248  for (size_t i = 0; i < NETWORKS.size(); ++i) {
249  if (str == NETWORKS[i]) return i;
250  }
251  return UNKNOWN_NETWORK;
252  }
253 
254 public:
255  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
256  {
257  if (!args.empty()) {
258  throw std::runtime_error("-addrinfo takes no arguments");
259  }
260  UniValue params{RPCConvertValues("getnodeaddresses", std::vector<std::string>{{"0"}})};
261  return JSONRPCRequestObj("getnodeaddresses", params, 1);
262  }
263 
264  UniValue ProcessReply(const UniValue& reply) override
265  {
266  if (!reply["error"].isNull()) return reply;
267  const std::vector<UniValue>& nodes{reply["result"].getValues()};
268  if (!nodes.empty() && nodes.at(0)["network"].isNull()) {
269  throw std::runtime_error("-addrinfo requires bitcoind server to be running v22.0 and up");
270  }
271  // Count the number of peers known to our node, by network.
272  std::array<uint64_t, NETWORKS.size()> counts{{}};
273  for (const UniValue& node : nodes) {
274  std::string network_name{node["network"].get_str()};
275  const int8_t network_id{NetworkStringToId(network_name)};
276  if (network_id == UNKNOWN_NETWORK) continue;
277  ++counts.at(network_id);
278  }
279  // Prepare result to return to user.
280  UniValue result{UniValue::VOBJ}, addresses{UniValue::VOBJ};
281  uint64_t total{0}; // Total address count
282  for (size_t i = 0; i < NETWORKS.size(); ++i) {
283  addresses.pushKV(NETWORKS[i], counts.at(i));
284  total += counts.at(i);
285  }
286  addresses.pushKV("total", total);
287  result.pushKV("addresses_known", addresses);
288  return JSONRPCReplyObj(result, NullUniValue, 1);
289  }
290 };
291 
294 {
295 public:
296  const int ID_NETWORKINFO = 0;
297  const int ID_BLOCKCHAININFO = 1;
298  const int ID_WALLETINFO = 2;
299  const int ID_BALANCES = 3;
300 
302  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
303  {
304  if (!args.empty()) {
305  throw std::runtime_error("-getinfo takes no arguments");
306  }
307  UniValue result(UniValue::VARR);
308  result.push_back(JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
309  result.push_back(JSONRPCRequestObj("getblockchaininfo", NullUniValue, ID_BLOCKCHAININFO));
310  result.push_back(JSONRPCRequestObj("getwalletinfo", NullUniValue, ID_WALLETINFO));
311  result.push_back(JSONRPCRequestObj("getbalances", NullUniValue, ID_BALANCES));
312  return result;
313  }
314 
316  UniValue ProcessReply(const UniValue &batch_in) override
317  {
318  UniValue result(UniValue::VOBJ);
319  const std::vector<UniValue> batch = JSONRPCProcessBatchReply(batch_in);
320  // Errors in getnetworkinfo() and getblockchaininfo() are fatal, pass them on;
321  // getwalletinfo() and getbalances() are allowed to fail if there is no wallet.
322  if (!batch[ID_NETWORKINFO]["error"].isNull()) {
323  return batch[ID_NETWORKINFO];
324  }
325  if (!batch[ID_BLOCKCHAININFO]["error"].isNull()) {
326  return batch[ID_BLOCKCHAININFO];
327  }
328  result.pushKV("version", batch[ID_NETWORKINFO]["result"]["version"]);
329  result.pushKV("blocks", batch[ID_BLOCKCHAININFO]["result"]["blocks"]);
330  result.pushKV("headers", batch[ID_BLOCKCHAININFO]["result"]["headers"]);
331  result.pushKV("verificationprogress", batch[ID_BLOCKCHAININFO]["result"]["verificationprogress"]);
332  result.pushKV("timeoffset", batch[ID_NETWORKINFO]["result"]["timeoffset"]);
333 
334  UniValue connections(UniValue::VOBJ);
335  connections.pushKV("in", batch[ID_NETWORKINFO]["result"]["connections_in"]);
336  connections.pushKV("out", batch[ID_NETWORKINFO]["result"]["connections_out"]);
337  connections.pushKV("total", batch[ID_NETWORKINFO]["result"]["connections"]);
338  result.pushKV("connections", connections);
339 
340  result.pushKV("networks", batch[ID_NETWORKINFO]["result"]["networks"]);
341  result.pushKV("difficulty", batch[ID_BLOCKCHAININFO]["result"]["difficulty"]);
342  result.pushKV("chain", UniValue(batch[ID_BLOCKCHAININFO]["result"]["chain"]));
343  if (!batch[ID_WALLETINFO]["result"].isNull()) {
344  result.pushKV("has_wallet", true);
345  result.pushKV("keypoolsize", batch[ID_WALLETINFO]["result"]["keypoolsize"]);
346  result.pushKV("walletname", batch[ID_WALLETINFO]["result"]["walletname"]);
347  if (!batch[ID_WALLETINFO]["result"]["unlocked_until"].isNull()) {
348  result.pushKV("unlocked_until", batch[ID_WALLETINFO]["result"]["unlocked_until"]);
349  }
350  result.pushKV("paytxfee", batch[ID_WALLETINFO]["result"]["paytxfee"]);
351  }
352  if (!batch[ID_BALANCES]["result"].isNull()) {
353  result.pushKV("balance", batch[ID_BALANCES]["result"]["mine"]["trusted"]);
354  }
355  result.pushKV("relayfee", batch[ID_NETWORKINFO]["result"]["relayfee"]);
356  result.pushKV("warnings", batch[ID_NETWORKINFO]["result"]["warnings"]);
357  return JSONRPCReplyObj(result, NullUniValue, 1);
358  }
359 };
360 
363 {
364 private:
365  static constexpr uint8_t MAX_DETAIL_LEVEL{4};
366  std::array<std::array<uint16_t, NETWORKS.size() + 1>, 3> m_counts{{{}}};
369  int8_t NetworkStringToId(const std::string& str) const
370  {
371  for (size_t i = 0; i < NETWORKS.size(); ++i) {
372  if (str == NETWORKS[i]) return i;
373  }
374  return UNKNOWN_NETWORK;
375  }
376  uint8_t m_details_level{0};
377  bool DetailsRequested() const { return m_details_level > 0 && m_details_level < 5; }
378  bool IsAddressSelected() const { return m_details_level == 2 || m_details_level == 4; }
379  bool IsVersionSelected() const { return m_details_level == 3 || m_details_level == 4; }
380  bool m_is_asmap_on{false};
381  size_t m_max_addr_length{0};
384  size_t m_max_age_length{5};
385  size_t m_max_id_length{2};
386  struct Peer {
387  std::string addr;
388  std::string sub_version;
389  std::string conn_type;
390  std::string network;
391  std::string age;
392  double min_ping;
393  double ping;
394  int64_t addr_processed;
396  int64_t last_blck;
397  int64_t last_recv;
398  int64_t last_send;
399  int64_t last_trxn;
400  int id;
402  int version;
408  bool operator<(const Peer& rhs) const { return std::tie(is_outbound, min_ping) < std::tie(rhs.is_outbound, rhs.min_ping); }
409  };
410  std::vector<Peer> m_peers;
411  std::string ChainToString() const
412  {
413  if (gArgs.GetChainName() == CBaseChainParams::TESTNET) return " testnet";
414  if (gArgs.GetChainName() == CBaseChainParams::SIGNET) return " signet";
415  if (gArgs.GetChainName() == CBaseChainParams::REGTEST) return " regtest";
416  return "";
417  }
418  std::string PingTimeToString(double seconds) const
419  {
420  if (seconds < 0) return "";
421  const double milliseconds{round(1000 * seconds)};
422  return milliseconds > 999999 ? "-" : ToString(milliseconds);
423  }
424  std::string ConnectionTypeForNetinfo(const std::string& conn_type) const
425  {
426  if (conn_type == "outbound-full-relay") return "full";
427  if (conn_type == "block-relay-only") return "block";
428  if (conn_type == "manual" || conn_type == "feeler") return conn_type;
429  if (conn_type == "addr-fetch") return "addr";
430  return "";
431  }
432  const int64_t m_time_now{GetTimeSeconds()};
433 
434 public:
435  static constexpr int ID_PEERINFO = 0;
436  static constexpr int ID_NETWORKINFO = 1;
437 
438  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
439  {
440  if (!args.empty()) {
441  uint8_t n{0};
442  if (ParseUInt8(args.at(0), &n)) {
443  m_details_level = std::min(n, MAX_DETAIL_LEVEL);
444  } else {
445  throw std::runtime_error(strprintf("invalid -netinfo argument: %s\nFor more information, run: bitcoin-cli -netinfo help", args.at(0)));
446  }
447  }
448  UniValue result(UniValue::VARR);
449  result.push_back(JSONRPCRequestObj("getpeerinfo", NullUniValue, ID_PEERINFO));
450  result.push_back(JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
451  return result;
452  }
453 
454  UniValue ProcessReply(const UniValue& batch_in) override
455  {
456  const std::vector<UniValue> batch{JSONRPCProcessBatchReply(batch_in)};
457  if (!batch[ID_PEERINFO]["error"].isNull()) return batch[ID_PEERINFO];
458  if (!batch[ID_NETWORKINFO]["error"].isNull()) return batch[ID_NETWORKINFO];
459 
460  const UniValue& networkinfo{batch[ID_NETWORKINFO]["result"]};
461  if (networkinfo["version"].get_int() < 209900) {
462  throw std::runtime_error("-netinfo requires bitcoind server to be running v0.21.0 and up");
463  }
464 
465  // Count peer connection totals, and if DetailsRequested(), store peer data in a vector of structs.
466  for (const UniValue& peer : batch[ID_PEERINFO]["result"].getValues()) {
467  const std::string network{peer["network"].get_str()};
468  const int8_t network_id{NetworkStringToId(network)};
469  if (network_id == UNKNOWN_NETWORK) continue;
470  const bool is_outbound{!peer["inbound"].get_bool()};
471  const bool is_block_relay{!peer["relaytxes"].get_bool()};
472  const std::string conn_type{peer["connection_type"].get_str()};
473  ++m_counts.at(is_outbound).at(network_id); // in/out by network
474  ++m_counts.at(is_outbound).at(NETWORKS.size()); // in/out overall
475  ++m_counts.at(2).at(network_id); // total by network
476  ++m_counts.at(2).at(NETWORKS.size()); // total overall
477  if (conn_type == "block-relay-only") ++m_block_relay_peers_count;
478  if (conn_type == "manual") ++m_manual_peers_count;
479  if (DetailsRequested()) {
480  // Push data for this peer to the peers vector.
481  const int peer_id{peer["id"].get_int()};
482  const int mapped_as{peer["mapped_as"].isNull() ? 0 : peer["mapped_as"].get_int()};
483  const int version{peer["version"].get_int()};
484  const int64_t addr_processed{peer["addr_processed"].isNull() ? 0 : peer["addr_processed"].get_int64()};
485  const int64_t addr_rate_limited{peer["addr_rate_limited"].isNull() ? 0 : peer["addr_rate_limited"].get_int64()};
486  const int64_t conn_time{peer["conntime"].get_int64()};
487  const int64_t last_blck{peer["last_block"].get_int64()};
488  const int64_t last_recv{peer["lastrecv"].get_int64()};
489  const int64_t last_send{peer["lastsend"].get_int64()};
490  const int64_t last_trxn{peer["last_transaction"].get_int64()};
491  const double min_ping{peer["minping"].isNull() ? -1 : peer["minping"].get_real()};
492  const double ping{peer["pingtime"].isNull() ? -1 : peer["pingtime"].get_real()};
493  const std::string addr{peer["addr"].get_str()};
494  const std::string age{conn_time == 0 ? "" : ToString((m_time_now - conn_time) / 60)};
495  const std::string sub_version{peer["subver"].get_str()};
496  const bool is_addr_relay_enabled{peer["addr_relay_enabled"].isNull() ? false : peer["addr_relay_enabled"].get_bool()};
497  const bool is_bip152_hb_from{peer["bip152_hb_from"].get_bool()};
498  const bool is_bip152_hb_to{peer["bip152_hb_to"].get_bool()};
499  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_block_relay, is_outbound});
500  m_max_addr_length = std::max(addr.length() + 1, m_max_addr_length);
501  m_max_addr_processed_length = std::max(ToString(addr_processed).length(), m_max_addr_processed_length);
502  m_max_addr_rate_limited_length = std::max(ToString(addr_rate_limited).length(), m_max_addr_rate_limited_length);
503  m_max_age_length = std::max(age.length(), m_max_age_length);
504  m_max_id_length = std::max(ToString(peer_id).length(), m_max_id_length);
505  m_is_asmap_on |= (mapped_as != 0);
506  }
507  }
508 
509  // Generate report header.
510  std::string result{strprintf("%s client %s%s - server %i%s\n\n", PACKAGE_NAME, FormatFullVersion(), ChainToString(), networkinfo["protocolversion"].get_int(), networkinfo["subversion"].get_str())};
511 
512  // Report detailed peer connections list sorted by direction and minimum ping time.
513  if (DetailsRequested() && !m_peers.empty()) {
514  std::sort(m_peers.begin(), m_peers.end());
515  result += strprintf("<-> type net mping ping send recv txn blk hb %*s%*s%*s ",
518  m_max_age_length, "age");
519  if (m_is_asmap_on) result += " asmap ";
520  result += strprintf("%*s %-*s%s\n", m_max_id_length, "id", IsAddressSelected() ? m_max_addr_length : 0, IsAddressSelected() ? "address" : "", IsVersionSelected() ? "version" : "");
521  for (const Peer& peer : m_peers) {
522  std::string version{ToString(peer.version) + peer.sub_version};
523  result += strprintf(
524  "%3s %6s %5s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
525  peer.is_outbound ? "out" : "in",
526  ConnectionTypeForNetinfo(peer.conn_type),
527  peer.network,
528  PingTimeToString(peer.min_ping),
529  PingTimeToString(peer.ping),
530  peer.last_send ? ToString(m_time_now - peer.last_send) : "",
531  peer.last_recv ? ToString(m_time_now - peer.last_recv) : "",
532  peer.last_trxn ? ToString((m_time_now - peer.last_trxn) / 60) : peer.is_block_relay ? "*" : "",
533  peer.last_blck ? ToString((m_time_now - peer.last_blck) / 60) : "",
534  strprintf("%s%s", peer.is_bip152_hb_to ? "." : " ", peer.is_bip152_hb_from ? "*" : " "),
535  m_max_addr_processed_length, // variable spacing
536  peer.addr_processed ? ToString(peer.addr_processed) : peer.is_addr_relay_enabled ? "" : ".",
537  m_max_addr_rate_limited_length, // variable spacing
538  peer.addr_rate_limited ? ToString(peer.addr_rate_limited) : "",
539  m_max_age_length, // variable spacing
540  peer.age,
541  m_is_asmap_on ? 7 : 0, // variable spacing
542  m_is_asmap_on && peer.mapped_as ? ToString(peer.mapped_as) : "",
543  m_max_id_length, // variable spacing
544  peer.id,
545  IsAddressSelected() ? m_max_addr_length : 0, // variable spacing
546  IsAddressSelected() ? peer.addr : "",
547  IsVersionSelected() && version != "0" ? version : "");
548  }
549  result += strprintf(" ms ms sec sec min min %*s\n\n", m_max_age_length, "min");
550  }
551 
552  // Report peer connection totals by type.
553  result += " ";
554  std::vector<int8_t> reachable_networks;
555  for (const UniValue& network : networkinfo["networks"].getValues()) {
556  if (network["reachable"].get_bool()) {
557  const std::string& network_name{network["name"].get_str()};
558  const int8_t network_id{NetworkStringToId(network_name)};
559  if (network_id == UNKNOWN_NETWORK) continue;
560  result += strprintf("%8s", network_name); // column header
561  reachable_networks.push_back(network_id);
562  }
563  };
564  result += " total block";
565  if (m_manual_peers_count) result += " manual";
566 
567  const std::array rows{"in", "out", "total"};
568  for (size_t i = 0; i < rows.size(); ++i) {
569  result += strprintf("\n%-5s", rows[i]); // row header
570  for (int8_t n : reachable_networks) {
571  result += strprintf("%8i", m_counts.at(i).at(n)); // network peers count
572  }
573  result += strprintf(" %5i", m_counts.at(i).at(NETWORKS.size())); // total peers count
574  if (i == 1) { // the outbound row has two extra columns for block relay and manual peer counts
575  result += strprintf(" %5i", m_block_relay_peers_count);
576  if (m_manual_peers_count) result += strprintf(" %5i", m_manual_peers_count);
577  }
578  }
579 
580  // Report local addresses, ports, and scores.
581  result += "\n\nLocal addresses";
582  const std::vector<UniValue>& local_addrs{networkinfo["localaddresses"].getValues()};
583  if (local_addrs.empty()) {
584  result += ": n/a\n";
585  } else {
586  size_t max_addr_size{0};
587  for (const UniValue& addr : local_addrs) {
588  max_addr_size = std::max(addr["address"].get_str().length() + 1, max_addr_size);
589  }
590  for (const UniValue& addr : local_addrs) {
591  result += strprintf("\n%-*s port %6i score %6i", max_addr_size, addr["address"].get_str(), addr["port"].get_int(), addr["score"].get_int());
592  }
593  }
594 
595  return JSONRPCReplyObj(UniValue{result}, NullUniValue, 1);
596  }
597 
598  const std::string m_help_doc{
599  "-netinfo level|\"help\" \n\n"
600  "Returns a network peer connections dashboard with information from the remote server.\n"
601  "This human-readable interface will change regularly and is not intended to be a stable API.\n"
602  "Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n"
603  + strprintf("An optional integer argument from 0 to %d can be passed for different peers listings; %d to 255 are parsed as %d.\n", MAX_DETAIL_LEVEL, MAX_DETAIL_LEVEL, MAX_DETAIL_LEVEL) +
604  "Pass \"help\" to see this detailed help documentation.\n"
605  "If more than one argument is passed, only the first one is read and parsed.\n"
606  "Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n"
607  "Arguments:\n"
608  + strprintf("1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n", MAX_DETAIL_LEVEL) +
609  " 0 - Connection counts and local addresses\n"
610  " 1 - Like 0 but with a peers listing (without address or version columns)\n"
611  " 2 - Like 1 but with an address column\n"
612  " 3 - Like 1 but with a version column\n"
613  " 4 - Like 1 but with both address and version columns\n"
614  "2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n"
615  "Result:\n\n"
616  + 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) +
617  " Column Description\n"
618  " ------ -----------\n"
619  " <-> Direction\n"
620  " \"in\" - inbound connections are those initiated by the peer\n"
621  " \"out\" - outbound connections are those initiated by us\n"
622  " type Type of peer connection\n"
623  " \"full\" - full relay, the default\n"
624  " \"block\" - block relay; like full relay but does not relay transactions or addresses\n"
625  " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n"
626  " \"feeler\" - short-lived connection for testing addresses\n"
627  " \"addr\" - address fetch; short-lived connection for requesting addresses\n"
628  " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", or \"cjdns\")\n"
629  " mping Minimum observed ping time, in milliseconds (ms)\n"
630  " ping Last observed ping time, in milliseconds (ms)\n"
631  " send Time since last message sent to the peer, in seconds\n"
632  " recv Time since last message received from the peer, in seconds\n"
633  " txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n"
634  " \"*\" - the peer requested we not relay transactions to it (relaytxes is false)\n"
635  " blk Time since last novel block passing initial validity checks received from the peer, in minutes\n"
636  " hb High-bandwidth BIP152 compact block relay\n"
637  " \".\" (to) - we selected the peer as a high-bandwidth peer\n"
638  " \"*\" (from) - the peer selected us as a high-bandwidth peer\n"
639  " addrp Total number of addresses processed, excluding those dropped due to rate limiting\n"
640  " \".\" - we do not relay addresses to this peer (addr_relay_enabled is false)\n"
641  " addrl Total number of addresses dropped due to rate limiting\n"
642  " age Duration of connection to the peer, in minutes\n"
643  " asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n"
644  " peer selection (only displayed if the -asmap config option is set)\n"
645  " id Peer index, in increasing order of peer connections since node startup\n"
646  " address IP address and port of the peer\n"
647  " version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n"
648  "* The connection counts table displays the number of peers by direction, network, and the totals\n"
649  " for each, as well as two special outbound columns for block relay peers and manual peers.\n\n"
650  "* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n"
651  "Examples:\n\n"
652  "Connection counts and local addresses only\n"
653  "> bitcoin-cli -netinfo\n\n"
654  "Compact peers listing\n"
655  "> bitcoin-cli -netinfo 1\n\n"
656  "Full dashboard\n"
657  + strprintf("> bitcoin-cli -netinfo %d\n\n", MAX_DETAIL_LEVEL) +
658  "Full live dashboard, adjust --interval or --no-title as needed (Linux)\n"
659  + strprintf("> watch --interval 1 --no-title bitcoin-cli -netinfo %d\n\n", MAX_DETAIL_LEVEL) +
660  "See this help\n"
661  "> bitcoin-cli -netinfo help\n"};
662 };
663 
666 {
667 public:
668  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
669  {
670  address_str = args.at(1);
671  UniValue params{RPCConvertValues("generatetoaddress", args)};
672  return JSONRPCRequestObj("generatetoaddress", params, 1);
673  }
674 
675  UniValue ProcessReply(const UniValue &reply) override
676  {
677  UniValue result(UniValue::VOBJ);
678  result.pushKV("address", address_str);
679  result.pushKV("blocks", reply.get_obj()["result"]);
680  return JSONRPCReplyObj(result, NullUniValue, 1);
681  }
682 protected:
683  std::string address_str;
684 };
685 
688 public:
689  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
690  {
691  UniValue params;
692  if(gArgs.GetBoolArg("-named", DEFAULT_NAMED)) {
693  params = RPCConvertNamedValues(method, args);
694  } else {
695  params = RPCConvertValues(method, args);
696  }
697  return JSONRPCRequestObj(method, params, 1);
698  }
699 
700  UniValue ProcessReply(const UniValue &reply) override
701  {
702  return reply.get_obj();
703  }
704 };
705 
706 static UniValue CallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const std::optional<std::string>& rpcwallet = {})
707 {
708  std::string host;
709  // In preference order, we choose the following for the port:
710  // 1. -rpcport
711  // 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6)
712  // 3. default port for chain
713  uint16_t port{BaseParams().RPCPort()};
714  SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host);
715  port = static_cast<uint16_t>(gArgs.GetIntArg("-rpcport", port));
716 
717  // Obtain event base
718  raii_event_base base = obtain_event_base();
719 
720  // Synchronously look up hostname
721  raii_evhttp_connection evcon = obtain_evhttp_connection_base(base.get(), host, port);
722 
723  // Set connection timeout
724  {
725  const int timeout = gArgs.GetIntArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT);
726  if (timeout > 0) {
727  evhttp_connection_set_timeout(evcon.get(), timeout);
728  } else {
729  // Indefinite request timeouts are not possible in libevent-http, so we
730  // set the timeout to a very long time period instead.
731 
732  constexpr int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
733  evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
734  }
735  }
736 
737  HTTPReply response;
738  raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response);
739  if (req == nullptr)
740  throw std::runtime_error("create http request failed");
741 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
742  evhttp_request_set_error_cb(req.get(), http_error_cb);
743 #endif
744 
745  // Get credentials
746  std::string strRPCUserColonPass;
747  bool failedToGetAuthCookie = false;
748  if (gArgs.GetArg("-rpcpassword", "") == "") {
749  // Try fall back to cookie-based authentication if no password is provided
751  failedToGetAuthCookie = true;
752  }
753  } else {
754  strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" + gArgs.GetArg("-rpcpassword", "");
755  }
756 
757  struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get());
758  assert(output_headers);
759  evhttp_add_header(output_headers, "Host", host.c_str());
760  evhttp_add_header(output_headers, "Connection", "close");
761  evhttp_add_header(output_headers, "Content-Type", "application/json");
762  evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());
763 
764  // Attach request data
765  std::string strRequest = rh->PrepareRequest(strMethod, args).write() + "\n";
766  struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get());
767  assert(output_buffer);
768  evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
769 
770  // check if we should use a special wallet endpoint
771  std::string endpoint = "/";
772  if (rpcwallet) {
773  char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(), false);
774  if (encodedURI) {
775  endpoint = "/wallet/" + std::string(encodedURI);
776  free(encodedURI);
777  } else {
778  throw CConnectionFailed("uri-encode failed");
779  }
780  }
781  int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, endpoint.c_str());
782  req.release(); // ownership moved to evcon in above call
783  if (r != 0) {
784  throw CConnectionFailed("send http request failed");
785  }
786 
787  event_base_dispatch(base.get());
788 
789  if (response.status == 0) {
790  std::string responseErrorMessage;
791  if (response.error != -1) {
792  responseErrorMessage = strprintf(" (error code %d - \"%s\")", response.error, http_errorstring(response.error));
793  }
794  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));
795  } else if (response.status == HTTP_UNAUTHORIZED) {
796  if (failedToGetAuthCookie) {
797  throw std::runtime_error(strprintf(
798  "Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)",
800  } else {
801  throw std::runtime_error("Authorization failed: Incorrect rpcuser or rpcpassword");
802  }
803  } else if (response.status == HTTP_SERVICE_UNAVAILABLE) {
804  throw std::runtime_error(strprintf("Server response: %s", response.body));
805  } else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
806  throw std::runtime_error(strprintf("server returned HTTP error %d", response.status));
807  else if (response.body.empty())
808  throw std::runtime_error("no response from server");
809 
810  // Parse reply
811  UniValue valReply(UniValue::VSTR);
812  if (!valReply.read(response.body))
813  throw std::runtime_error("couldn't parse reply from server");
814  const UniValue reply = rh->ProcessReply(valReply);
815  if (reply.empty())
816  throw std::runtime_error("expected reply to have result, error and id properties");
817 
818  return reply;
819 }
820 
830 static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const std::optional<std::string>& rpcwallet = {})
831 {
832  UniValue response(UniValue::VOBJ);
833  // Execute and handle connection failures with -rpcwait.
834  const bool fWait = gArgs.GetBoolArg("-rpcwait", false);
835  const int timeout = gArgs.GetIntArg("-rpcwaittimeout", DEFAULT_WAIT_CLIENT_TIMEOUT);
836  const auto deadline{GetTime<std::chrono::microseconds>() + 1s * timeout};
837 
838  do {
839  try {
840  response = CallRPC(rh, strMethod, args, rpcwallet);
841  if (fWait) {
842  const UniValue& error = find_value(response, "error");
843  if (!error.isNull() && error["code"].get_int() == RPC_IN_WARMUP) {
844  throw CConnectionFailed("server in warmup");
845  }
846  }
847  break; // Connection succeeded, no need to retry.
848  } catch (const CConnectionFailed& e) {
849  const auto now{GetTime<std::chrono::microseconds>()};
850  if (fWait && (timeout <= 0 || now < deadline)) {
852  } else {
853  throw CConnectionFailed(strprintf("timeout on transient error: %s", e.what()));
854  }
855  }
856  } while (fWait);
857  return response;
858 }
859 
861 static void ParseResult(const UniValue& result, std::string& strPrint)
862 {
863  if (result.isNull()) return;
864  strPrint = result.isStr() ? result.get_str() : result.write(2);
865 }
866 
868 static void ParseError(const UniValue& error, std::string& strPrint, int& nRet)
869 {
870  if (error.isObject()) {
871  const UniValue& err_code = find_value(error, "code");
872  const UniValue& err_msg = find_value(error, "message");
873  if (!err_code.isNull()) {
874  strPrint = "error code: " + err_code.getValStr() + "\n";
875  }
876  if (err_msg.isStr()) {
877  strPrint += ("error message:\n" + err_msg.get_str());
878  }
879  if (err_code.isNum() && err_code.get_int() == RPC_WALLET_NOT_SPECIFIED) {
880  strPrint += "\nTry adding \"-rpcwallet=<filename>\" option to bitcoin-cli command line.";
881  }
882  } else {
883  strPrint = "error: " + error.write();
884  }
885  nRet = abs(error["code"].get_int());
886 }
887 
894 static void GetWalletBalances(UniValue& result)
895 {
897  const UniValue listwallets = ConnectAndCallRPC(&rh, "listwallets", /* args=*/{});
898  if (!find_value(listwallets, "error").isNull()) return;
899  const UniValue& wallets = find_value(listwallets, "result");
900  if (wallets.size() <= 1) return;
901 
902  UniValue balances(UniValue::VOBJ);
903  for (const UniValue& wallet : wallets.getValues()) {
904  const std::string wallet_name = wallet.get_str();
905  const UniValue getbalances = ConnectAndCallRPC(&rh, "getbalances", /* args=*/{}, wallet_name);
906  const UniValue& balance = find_value(getbalances, "result")["mine"]["trusted"];
907  balances.pushKV(wallet_name, balance);
908  }
909  result.pushKV("balances", balances);
910 }
911 
918 static void GetProgressBar(double progress, std::string& progress_bar)
919 {
920  if (progress < 0 || progress > 1) return;
921 
922  static constexpr double INCREMENT{0.05};
923  static const std::string COMPLETE_BAR{"\u2592"};
924  static const std::string INCOMPLETE_BAR{"\u2591"};
925 
926  for (int i = 0; i < progress / INCREMENT; ++i) {
927  progress_bar += COMPLETE_BAR;
928  }
929 
930  for (int i = 0; i < (1 - progress) / INCREMENT; ++i) {
931  progress_bar += INCOMPLETE_BAR;
932  }
933 }
934 
940 static void ParseGetInfoResult(UniValue& result)
941 {
942  if (!find_value(result, "error").isNull()) return;
943 
944  std::string RESET, GREEN, BLUE, YELLOW, MAGENTA, CYAN;
945  bool should_colorize = false;
946 
947 #ifndef WIN32
948  if (isatty(fileno(stdout))) {
949  // By default, only print colored text if OS is not WIN32 and stdout is connected to a terminal.
950  should_colorize = true;
951  }
952 #endif
953 
954  if (gArgs.IsArgSet("-color")) {
955  const std::string color{gArgs.GetArg("-color", DEFAULT_COLOR_SETTING)};
956  if (color == "always") {
957  should_colorize = true;
958  } else if (color == "never") {
959  should_colorize = false;
960  } else if (color != "auto") {
961  throw std::runtime_error("Invalid value for -color option. Valid values: always, auto, never.");
962  }
963  }
964 
965  if (should_colorize) {
966  RESET = "\x1B[0m";
967  GREEN = "\x1B[32m";
968  BLUE = "\x1B[34m";
969  YELLOW = "\x1B[33m";
970  MAGENTA = "\x1B[35m";
971  CYAN = "\x1B[36m";
972  }
973 
974  std::string result_string = strprintf("%sChain: %s%s\n", BLUE, result["chain"].getValStr(), RESET);
975  result_string += strprintf("Blocks: %s\n", result["blocks"].getValStr());
976  result_string += strprintf("Headers: %s\n", result["headers"].getValStr());
977 
978  const double ibd_progress{result["verificationprogress"].get_real()};
979  std::string ibd_progress_bar;
980  // Display the progress bar only if IBD progress is less than 99%
981  if (ibd_progress < 0.99) {
982  GetProgressBar(ibd_progress, ibd_progress_bar);
983  // Add padding between progress bar and IBD progress
984  ibd_progress_bar += " ";
985  }
986 
987  result_string += strprintf("Verification progress: %s%.4f%%\n", ibd_progress_bar, ibd_progress * 100);
988  result_string += strprintf("Difficulty: %s\n\n", result["difficulty"].getValStr());
989 
990  result_string += strprintf(
991  "%sNetwork: in %s, out %s, total %s%s\n",
992  GREEN,
993  result["connections"]["in"].getValStr(),
994  result["connections"]["out"].getValStr(),
995  result["connections"]["total"].getValStr(),
996  RESET);
997  result_string += strprintf("Version: %s\n", result["version"].getValStr());
998  result_string += strprintf("Time offset (s): %s\n", result["timeoffset"].getValStr());
999 
1000  // proxies
1001  std::map<std::string, std::vector<std::string>> proxy_networks;
1002  std::vector<std::string> ordered_proxies;
1003 
1004  for (const UniValue& network : result["networks"].getValues()) {
1005  const std::string proxy = network["proxy"].getValStr();
1006  if (proxy.empty()) continue;
1007  // Add proxy to ordered_proxy if has not been processed
1008  if (proxy_networks.find(proxy) == proxy_networks.end()) ordered_proxies.push_back(proxy);
1009 
1010  proxy_networks[proxy].push_back(network["name"].getValStr());
1011  }
1012 
1013  std::vector<std::string> formatted_proxies;
1014  for (const std::string& proxy : ordered_proxies) {
1015  formatted_proxies.emplace_back(strprintf("%s (%s)", proxy, Join(proxy_networks.find(proxy)->second, ", ")));
1016  }
1017  result_string += strprintf("Proxies: %s\n", formatted_proxies.empty() ? "n/a" : Join(formatted_proxies, ", "));
1018 
1019  result_string += strprintf("Min tx relay fee rate (%s/kvB): %s\n\n", CURRENCY_UNIT, result["relayfee"].getValStr());
1020 
1021  if (!result["has_wallet"].isNull()) {
1022  const std::string walletname = result["walletname"].getValStr();
1023  result_string += strprintf("%sWallet: %s%s\n", MAGENTA, walletname.empty() ? "\"\"" : walletname, RESET);
1024 
1025  result_string += strprintf("Keypool size: %s\n", result["keypoolsize"].getValStr());
1026  if (!result["unlocked_until"].isNull()) {
1027  result_string += strprintf("Unlocked until: %s\n", result["unlocked_until"].getValStr());
1028  }
1029  result_string += strprintf("Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n", CURRENCY_UNIT, result["paytxfee"].getValStr());
1030  }
1031  if (!result["balance"].isNull()) {
1032  result_string += strprintf("%sBalance:%s %s\n\n", CYAN, RESET, result["balance"].getValStr());
1033  }
1034 
1035  if (!result["balances"].isNull()) {
1036  result_string += strprintf("%sBalances%s\n", CYAN, RESET);
1037 
1038  size_t max_balance_length{10};
1039 
1040  for (const std::string& wallet : result["balances"].getKeys()) {
1041  max_balance_length = std::max(result["balances"][wallet].getValStr().length(), max_balance_length);
1042  }
1043 
1044  for (const std::string& wallet : result["balances"].getKeys()) {
1045  result_string += strprintf("%*s %s\n",
1046  max_balance_length,
1047  result["balances"][wallet].getValStr(),
1048  wallet.empty() ? "\"\"" : wallet);
1049  }
1050  result_string += "\n";
1051  }
1052 
1053  result_string += strprintf("%sWarnings:%s %s", YELLOW, RESET, result["warnings"].getValStr());
1054  result.setStr(result_string);
1055 }
1056 
1062 {
1063  std::optional<std::string> wallet_name{};
1064  if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");
1066  return ConnectAndCallRPC(&rh, "getnewaddress", /* args=*/{}, wallet_name);
1067 }
1068 
1074 static void SetGenerateToAddressArgs(const std::string& address, std::vector<std::string>& args)
1075 {
1076  if (args.size() > 2) throw std::runtime_error("too many arguments (maximum 2 for nblocks and maxtries)");
1077  if (args.size() == 0) {
1078  args.emplace_back(DEFAULT_NBLOCKS);
1079  } else if (args.at(0) == "0") {
1080  throw std::runtime_error("the first argument (number of blocks to generate, default: " + DEFAULT_NBLOCKS + ") must be an integer value greater than zero");
1081  }
1082  args.emplace(args.begin() + 1, address);
1083 }
1084 
1085 static int CommandLineRPC(int argc, char *argv[])
1086 {
1087  std::string strPrint;
1088  int nRet = 0;
1089  try {
1090  // Skip switches
1091  while (argc > 1 && IsSwitchChar(argv[1][0])) {
1092  argc--;
1093  argv++;
1094  }
1095  std::string rpcPass;
1096  if (gArgs.GetBoolArg("-stdinrpcpass", false)) {
1097  NO_STDIN_ECHO();
1098  if (!StdinReady()) {
1099  fputs("RPC password> ", stderr);
1100  fflush(stderr);
1101  }
1102  if (!std::getline(std::cin, rpcPass)) {
1103  throw std::runtime_error("-stdinrpcpass specified but failed to read from standard input");
1104  }
1105  if (StdinTerminal()) {
1106  fputc('\n', stdout);
1107  }
1108  gArgs.ForceSetArg("-rpcpassword", rpcPass);
1109  }
1110  std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
1111  if (gArgs.GetBoolArg("-stdinwalletpassphrase", false)) {
1112  NO_STDIN_ECHO();
1113  std::string walletPass;
1114  if (args.size() < 1 || args[0].substr(0, 16) != "walletpassphrase") {
1115  throw std::runtime_error("-stdinwalletpassphrase is only applicable for walletpassphrase(change)");
1116  }
1117  if (!StdinReady()) {
1118  fputs("Wallet passphrase> ", stderr);
1119  fflush(stderr);
1120  }
1121  if (!std::getline(std::cin, walletPass)) {
1122  throw std::runtime_error("-stdinwalletpassphrase specified but failed to read from standard input");
1123  }
1124  if (StdinTerminal()) {
1125  fputc('\n', stdout);
1126  }
1127  args.insert(args.begin() + 1, walletPass);
1128  }
1129  if (gArgs.GetBoolArg("-stdin", false)) {
1130  // Read one arg per line from stdin and append
1131  std::string line;
1132  while (std::getline(std::cin, line)) {
1133  args.push_back(line);
1134  }
1135  if (StdinTerminal()) {
1136  fputc('\n', stdout);
1137  }
1138  }
1139  std::unique_ptr<BaseRequestHandler> rh;
1140  std::string method;
1141  if (gArgs.IsArgSet("-getinfo")) {
1142  rh.reset(new GetinfoRequestHandler());
1143  } else if (gArgs.GetBoolArg("-netinfo", false)) {
1144  if (!args.empty() && args.at(0) == "help") {
1145  tfm::format(std::cout, "%s\n", NetinfoRequestHandler().m_help_doc);
1146  return 0;
1147  }
1148  rh.reset(new NetinfoRequestHandler());
1149  } else if (gArgs.GetBoolArg("-generate", false)) {
1151  const UniValue& error{find_value(getnewaddress, "error")};
1152  if (error.isNull()) {
1153  SetGenerateToAddressArgs(find_value(getnewaddress, "result").get_str(), args);
1154  rh.reset(new GenerateToAddressRequestHandler());
1155  } else {
1156  ParseError(error, strPrint, nRet);
1157  }
1158  } else if (gArgs.GetBoolArg("-addrinfo", false)) {
1159  rh.reset(new AddrinfoRequestHandler());
1160  } else {
1161  rh.reset(new DefaultRequestHandler());
1162  if (args.size() < 1) {
1163  throw std::runtime_error("too few parameters (need at least command)");
1164  }
1165  method = args[0];
1166  args.erase(args.begin()); // Remove trailing method name from arguments vector
1167  }
1168  if (nRet == 0) {
1169  // Perform RPC call
1170  std::optional<std::string> wallet_name{};
1171  if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");
1172  const UniValue reply = ConnectAndCallRPC(rh.get(), method, args, wallet_name);
1173 
1174  // Parse reply
1175  UniValue result = find_value(reply, "result");
1176  const UniValue& error = find_value(reply, "error");
1177  if (error.isNull()) {
1178  if (gArgs.GetBoolArg("-getinfo", false)) {
1179  if (!gArgs.IsArgSet("-rpcwallet")) {
1180  GetWalletBalances(result); // fetch multiwallet balances and append to result
1181  }
1182  ParseGetInfoResult(result);
1183  }
1184 
1185  ParseResult(result, strPrint);
1186  } else {
1187  ParseError(error, strPrint, nRet);
1188  }
1189  }
1190  } catch (const std::exception& e) {
1191  strPrint = std::string("error: ") + e.what();
1192  nRet = EXIT_FAILURE;
1193  } catch (...) {
1194  PrintExceptionContinue(nullptr, "CommandLineRPC()");
1195  throw;
1196  }
1197 
1198  if (strPrint != "") {
1199  tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint);
1200  }
1201  return nRet;
1202 }
1203 
1204 #ifdef WIN32
1205 // Export main() and ensure working ASLR on Windows.
1206 // Exporting a symbol will prevent the linker from stripping
1207 // the .reloc section from the binary, which is a requirement
1208 // for ASLR. This is a temporary workaround until a fixed
1209 // version of binutils is used for releases.
1210 __declspec(dllexport) int main(int argc, char* argv[])
1211 {
1212  util::WinCmdLineArgs winArgs;
1213  std::tie(argc, argv) = winArgs.get();
1214 #else
1215 int main(int argc, char* argv[])
1216 {
1217 #endif
1218  SetupEnvironment();
1219  if (!SetupNetworking()) {
1220  tfm::format(std::cerr, "Error: Initializing networking failed\n");
1221  return EXIT_FAILURE;
1222  }
1223  event_set_log_callback(&libevent_log_cb);
1224 
1225  try {
1226  int ret = AppInitRPC(argc, argv);
1227  if (ret != CONTINUE_EXECUTION)
1228  return ret;
1229  }
1230  catch (const std::exception& e) {
1231  PrintExceptionContinue(&e, "AppInitRPC()");
1232  return EXIT_FAILURE;
1233  } catch (...) {
1234  PrintExceptionContinue(nullptr, "AppInitRPC()");
1235  return EXIT_FAILURE;
1236  }
1237 
1238  int ret = EXIT_FAILURE;
1239  try {
1240  ret = CommandLineRPC(argc, argv);
1241  }
1242  catch (const std::exception& e) {
1243  PrintExceptionContinue(&e, "CommandLineRPC()");
1244  } catch (...) {
1245  PrintExceptionContinue(nullptr, "CommandLineRPC()");
1246  }
1247  return ret;
1248 }
DefaultRequestHandler
Process default single requests.
Definition: bitcoin-cli.cpp:687
GenerateToAddressRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:668
urlDecode
UrlDecodeFn urlDecode
Definition: url.h:11
NetinfoRequestHandler::ConnectionTypeForNetinfo
std::string ConnectionTypeForNetinfo(const std::string &conn_type) const
Definition: bitcoin-cli.cpp:424
NetinfoRequestHandler::Peer::addr_processed
int64_t addr_processed
Definition: bitcoin-cli.cpp:394
NetinfoRequestHandler::m_peers
std::vector< Peer > m_peers
Definition: bitcoin-cli.cpp:410
NetinfoRequestHandler::Peer
Definition: bitcoin-cli.cpp:386
HTTPReply
Reply structure for request_done to fill in.
Definition: bitcoin-cli.cpp:167
feerate.h
NetinfoRequestHandler::m_is_asmap_on
bool m_is_asmap_on
Definition: bitcoin-cli.cpp:380
NetinfoRequestHandler
Process netinfo requests.
Definition: bitcoin-cli.cpp:362
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:597
NetinfoRequestHandler::m_max_id_length
size_t m_max_id_length
Definition: bitcoin-cli.cpp:385
HTTP_SERVICE_UNAVAILABLE
@ HTTP_SERVICE_UNAVAILABLE
Definition: protocol.h:19
ToString
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:87
DEFAULT_NBLOCKS
static const std::string DEFAULT_NBLOCKS
Default number of blocks to generate for RPC generatetoaddress.
Definition: bitcoin-cli.cpp:55
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:19
assert
assert(!tx.IsCoinBase())
tinyformat::format
void format(std::ostream &out, const char *fmt, const Args &... args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1062
NetinfoRequestHandler::IsVersionSelected
bool IsVersionSelected() const
Definition: bitcoin-cli.cpp:379
NetinfoRequestHandler::Peer::mapped_as
int mapped_as
Definition: bitcoin-cli.cpp:401
NetinfoRequestHandler::m_max_addr_processed_length
size_t m_max_addr_processed_length
Definition: bitcoin-cli.cpp:382
NetinfoRequestHandler::m_time_now
const int64_t m_time_now
Definition: bitcoin-cli.cpp:432
DEFAULT_COLOR_SETTING
static const std::string DEFAULT_COLOR_SETTING
Default -color setting.
Definition: bitcoin-cli.cpp:58
GenerateToAddressRequestHandler::address_str
std::string address_str
Definition: bitcoin-cli.cpp:683
NetinfoRequestHandler::m_details_level
uint8_t m_details_level
Optional user-supplied arg to set dashboard details level.
Definition: bitcoin-cli.cpp:376
ArgsManager::GetHelpMessage
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:665
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
NetinfoRequestHandler::Peer::addr
std::string addr
Definition: bitcoin-cli.cpp:387
libevent_log_cb
static void libevent_log_cb(int severity, const char *msg)
libevent event log callback
Definition: bitcoin-cli.cpp:95
NetinfoRequestHandler::Peer::is_addr_relay_enabled
bool is_addr_relay_enabled
Definition: bitcoin-cli.cpp:403
GetinfoRequestHandler
Process getinfo requests.
Definition: bitcoin-cli.cpp:293
AppInitRPC
static int AppInitRPC(int argc, char *argv[])
Definition: bitcoin-cli.cpp:121
NetinfoRequestHandler::ID_PEERINFO
static constexpr int ID_PEERINFO
Definition: bitcoin-cli.cpp:435
NetinfoRequestHandler::MAX_DETAIL_LEVEL
static constexpr uint8_t MAX_DETAIL_LEVEL
Definition: bitcoin-cli.cpp:365
chainparamsbase.h
HTTP_BAD_REQUEST
@ HTTP_BAD_REQUEST
Definition: protocol.h:13
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
disable validation
Definition: system.h:166
SetupChainParamsBaseOptions
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
Definition: chainparamsbase.cpp:18
ArgsManager::DISALLOW_NEGATION
@ DISALLOW_NEGATION
disallow -nofoo syntax
Definition: system.h:171
ArgsManager::GetChainName
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:984
NetinfoRequestHandler::NetworkStringToId
int8_t NetworkStringToId(const std::string &str) const
Definition: bitcoin-cli.cpp:369
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:491
HTTPReply::body
std::string body
Definition: bitcoin-cli.cpp:173
AddrinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:255
CBaseChainParams::TESTNET
static const std::string TESTNET
Definition: chainparamsbase.h:23
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1291
NetinfoRequestHandler::m_counts
std::array< std::array< uint16_t, NETWORKS.size()+1 >, 3 > m_counts
Peer counts by (in/out/total, networks/total)
Definition: bitcoin-cli.cpp:366
SelectBaseParams
void SelectBaseParams(const std::string &chain)
Sets the params returned by Params() to those for the given network.
Definition: chainparamsbase.cpp:57
DEFAULT_MAX_TRIES
static const uint64_t DEFAULT_MAX_TRIES
Default max iterations to try in RPC generatetodescriptor, generatetoaddress, and generateblock.
Definition: mining.h:9
NetinfoRequestHandler::Peer::id
int id
Definition: bitcoin-cli.cpp:400
protocol.h
GenerateToAddressRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:675
GetAuthCookie
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
Definition: request.cpp:108
clientversion.h
NetinfoRequestHandler::m_max_addr_rate_limited_length
size_t m_max_addr_rate_limited_length
Definition: bitcoin-cli.cpp:383
wallet
Definition: node.h:38
UniValue::isNull
bool isNull() const
Definition: univalue.h:75
DEFAULT_HTTP_CLIENT_TIMEOUT
static const int DEFAULT_HTTP_CLIENT_TIMEOUT
Definition: bitcoin-cli.cpp:47
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:734
JSONRPCReplyObj
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:33
fs::PathToString
static std::string PathToString(const path &path)
Convert path object to byte string.
Definition: fs.h:120
RPCConvertValues
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert positional arguments to command-specific RPC representation.
Definition: client.cpp:246
NetinfoRequestHandler::Peer::addr_rate_limited
int64_t addr_rate_limited
Definition: bitcoin-cli.cpp:395
EncodeBase64
std::string EncodeBase64(Span< const unsigned char > input)
Definition: strencodings.cpp:131
bitcoin-config.h
UniValue::write
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Definition: univalue_write.cpp:28
UniValue::isNum
bool isNum() const
Definition: univalue.h:80
SetupHelpOptions
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:739
CConnectionFailed::CConnectionFailed
CConnectionFailed(const std::string &msg)
Definition: bitcoin-cli.cpp:111
NetinfoRequestHandler::m_max_addr_length
size_t m_max_addr_length
Definition: bitcoin-cli.cpp:381
NetinfoRequestHandler::Peer::age
std::string age
Definition: bitcoin-cli.cpp:391
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
BITCOIN_CONF_FILENAME
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:77
NetinfoRequestHandler::Peer::is_block_relay
bool is_block_relay
Definition: bitcoin-cli.cpp:406
http_errorstring
static std::string http_errorstring(int code)
Definition: bitcoin-cli.cpp:176
UniValue
Definition: univalue.h:17
tinyformat.h
NetinfoRequestHandler::Peer::is_bip152_hb_to
bool is_bip152_hb_to
Definition: bitcoin-cli.cpp:405
UNKNOWN_NETWORK
static constexpr int8_t UNKNOWN_NETWORK
Definition: bitcoin-cli.cpp:51
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:98
NetinfoRequestHandler::IsAddressSelected
bool IsAddressSelected() const
Definition: bitcoin-cli.cpp:378
strencodings.h
UniValue::isStr
bool isStr() const
Definition: univalue.h:79
DefaultRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:689
DEFAULT_RPCCONNECT
static const char DEFAULT_RPCCONNECT[]
Definition: bitcoin-cli.cpp:46
events.h
NetinfoRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &batch_in) override
Definition: bitcoin-cli.cpp:454
getnewaddress
std::string getnewaddress(wallet::CWallet &w)
Returns a new address from the wallet.
AddrinfoRequestHandler
Process addrinfo requests.
Definition: bitcoin-cli.cpp:243
CURRENCY_UNIT
const std::string CURRENCY_UNIT
Definition: feerate.h:14
SplitHostPort
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
Definition: strencodings.cpp:110
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue_get.cpp:135
NetinfoRequestHandler::Peer::ping
double ping
Definition: bitcoin-cli.cpp:393
CallRPC
static UniValue CallRPC(BaseRequestHandler *rh, const std::string &strMethod, const std::vector< std::string > &args, const std::optional< std::string > &rpcwallet={})
Definition: bitcoin-cli.cpp:706
ParseError
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.
Definition: bitcoin-cli.cpp:868
NetinfoRequestHandler::m_manual_peers_count
uint8_t m_manual_peers_count
Definition: bitcoin-cli.cpp:368
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:363
ParseGetInfoResult
static void ParseGetInfoResult(UniValue &result)
ParseGetInfoResult takes in -getinfo result in UniValue object and parses it into a user friendly Uni...
Definition: bitcoin-cli.cpp:940
NetinfoRequestHandler::PingTimeToString
std::string PingTimeToString(double seconds) const
Definition: bitcoin-cli.cpp:418
NetinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:438
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:637
NetinfoRequestHandler::m_help_doc
const std::string m_help_doc
Definition: bitcoin-cli.cpp:598
NetinfoRequestHandler::Peer::is_bip152_hb_from
bool is_bip152_hb_from
Definition: bitcoin-cli.cpp:404
univalue.h
CBaseChainParams::REGTEST
static const std::string REGTEST
Definition: chainparamsbase.h:25
RPCConvertNamedValues
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert named arguments to command-specific RPC representation.
Definition: client.cpp:265
IsSwitchChar
bool IsSwitchChar(char c)
Definition: system.h:124
GetProgressBar
static void GetProgressBar(double progress, std::string &progress_bar)
GetProgressBar constructs a progress bar with 5% intervals.
Definition: bitcoin-cli.cpp:918
JSONRPCRequestObj
UniValue JSONRPCRequestObj(const std::string &strMethod, const UniValue &params, const UniValue &id)
JSON-RPC protocol.
Definition: request.cpp:24
ArgsManager::ForceSetArg
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:619
obtain_evhttp_request
raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg)
Definition: events.h:45
obtain_evhttp_connection_base
raii_evhttp_connection obtain_evhttp_connection_base(struct event_base *base, std::string host, uint16_t port)
Definition: events.h:49
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:585
OptionsCategory::OPTIONS
@ OPTIONS
CreateBaseChainParams
std::unique_ptr< CBaseChainParams > CreateBaseChainParams(const std::string &chain)
Port numbers for incoming Tor connections (8334, 18334, 38334, 18445) have been chosen arbitrarily to...
Definition: chainparamsbase.cpp:43
NetinfoRequestHandler::m_block_relay_peers_count
uint8_t m_block_relay_peers_count
Definition: bitcoin-cli.cpp:367
RPC_IN_WARMUP
@ RPC_IN_WARMUP
Client still warming up.
Definition: protocol.h:49
HTTP_UNAUTHORIZED
@ HTTP_UNAUTHORIZED
Definition: protocol.h:14
NetinfoRequestHandler::Peer::last_blck
int64_t last_blck
Definition: bitcoin-cli.cpp:396
main
int main(int argc, char *argv[])
Definition: bitcoin-cli.cpp:1215
wallet::getbalances
RPCHelpMan getbalances()
Definition: coins.cpp:433
ArgsManager::ParseParameters
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:303
DEFAULT_WAIT_CLIENT_TIMEOUT
static constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT
Definition: bitcoin-cli.cpp:48
BaseRequestHandler::~BaseRequestHandler
virtual ~BaseRequestHandler()
Definition: bitcoin-cli.cpp:237
BaseRequestHandler::ProcessReply
virtual UniValue ProcessReply(const UniValue &batch_in)=0
CBaseChainParams::RPCPort
uint16_t RPCPort() const
Definition: chainparamsbase.h:29
HTTPReply::HTTPReply
HTTPReply()
Definition: bitcoin-cli.cpp:169
NO_STDIN_ECHO
#define NO_STDIN_ECHO()
Definition: stdin.h:13
GetinfoRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &batch_in) override
Collect values from the batch and form a simulated getinfo reply.
Definition: bitcoin-cli.cpp:316
ArgsManager::ReadConfigFiles
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:892
request.h
SetupCliArgs
static void SetupCliArgs(ArgsManager &argsman)
Definition: bitcoin-cli.cpp:60
CONTINUE_EXECUTION
static const int CONTINUE_EXECUTION
Definition: bitcoin-cli.cpp:50
GetWalletBalances
static void GetWalletBalances(UniValue &result)
GetWalletBalances calls listwallets; if more than one wallet is loaded, it then fetches mine....
Definition: bitcoin-cli.cpp:894
gArgs
ArgsManager gArgs
Definition: system.cpp:80
CBaseChainParams::MAIN
static const std::string MAIN
Chain name strings.
Definition: chainparamsbase.h:22
ping
static RPCHelpMan ping()
Definition: net.cpp:68
stdin.h
NetinfoRequestHandler::Peer::conn_type
std::string conn_type
Definition: bitcoin-cli.cpp:389
RPC_WALLET_NOT_SPECIFIED
@ RPC_WALLET_NOT_SPECIFIED
No wallet specified (error when there are multiple wallets loaded)
Definition: protocol.h:81
UninterruptibleSleep
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:22
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:808
system.h
mining.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
NetinfoRequestHandler::Peer::network
std::string network
Definition: bitcoin-cli.cpp:390
UniValue::getValStr
const std::string & getValStr() const
Definition: univalue.h:63
Join
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
Definition: string.h:44
GetinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Create a simulated getinfo request.
Definition: bitcoin-cli.cpp:302
GetinfoRequestHandler::ID_WALLETINFO
const int ID_WALLETINFO
Definition: bitcoin-cli.cpp:298
JSONRPCProcessBatchReply
std::vector< UniValue > JSONRPCProcessBatchReply(const UniValue &in)
Parse JSON-RPC batch reply into a vector.
Definition: request.cpp:133
NetinfoRequestHandler::ID_NETWORKINFO
static constexpr int ID_NETWORKINFO
Definition: bitcoin-cli.cpp:436
obtain_event_base
raii_event_base obtain_event_base()
Definition: events.h:30
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:105
GetConfigFile
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:814
ArgsManager
Definition: system.h:158
translation.h
NETWORKS
static constexpr std::array NETWORKS
Definition: bitcoin-cli.cpp:52
url.h
BaseParams
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
Definition: chainparamsbase.cpp:33
ParseResult
static void ParseResult(const UniValue &result, std::string &strPrint)
Parse UniValue result to update the message to print to std::cout.
Definition: bitcoin-cli.cpp:861
strRPCUserColonPass
static std::string strRPCUserColonPass
Definition: httprpc.cpp:69
NetinfoRequestHandler::Peer::last_recv
int64_t last_recv
Definition: bitcoin-cli.cpp:397
wallet::listwallets
static RPCHelpMan listwallets()
Definition: wallet.cpp:162
std
Definition: setup_common.h:33
NetinfoRequestHandler::Peer::last_send
int64_t last_send
Definition: bitcoin-cli.cpp:398
HTTP_NOT_FOUND
@ HTTP_NOT_FOUND
Definition: protocol.h:16
DEFAULT_NAMED
static const bool DEFAULT_NAMED
Definition: bitcoin-cli.cpp:49
BaseRequestHandler
Class that handles the conversion from a command-line to a JSON-RPC request, as well as converting ba...
Definition: bitcoin-cli.cpp:234
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
UrlDecodeFn
std::string(const std::string &url_encoded) UrlDecodeFn
Definition: url.h:10
HTTPReply::error
int error
Definition: bitcoin-cli.cpp:172
ConnectAndCallRPC
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.
Definition: bitcoin-cli.cpp:830
NetinfoRequestHandler::Peer::sub_version
std::string sub_version
Definition: bitcoin-cli.cpp:388
UniValue::empty
bool empty() const
Definition: univalue.h:64
SetupNetworking
bool SetupNetworking()
Definition: system.cpp:1328
node
Definition: init.h:22
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue_get.cpp:84
UniValue::get_real
double get_real() const
Definition: univalue_get.cpp:125
UniValue::size
size_t size() const
Definition: univalue.h:66
GetinfoRequestHandler::ID_NETWORKINFO
const int ID_NETWORKINFO
Definition: bitcoin-cli.cpp:296
AddrinfoRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:264
GenerateToAddressRequestHandler
Process RPC generatetoaddress request.
Definition: bitcoin-cli.cpp:665
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:776
G_TRANSLATION_FUN
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
Definition: bitcoin-cli.cpp:43
find_value
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
NetinfoRequestHandler::Peer::operator<
bool operator<(const Peer &rhs) const
Definition: bitcoin-cli.cpp:408
URL_DECODE
UrlDecodeFn *const URL_DECODE
Definition: bitcoin-cli.cpp:44
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:50
NetinfoRequestHandler::Peer::is_outbound
bool is_outbound
Definition: bitcoin-cli.cpp:407
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
UniValue::VARR
@ VARR
Definition: univalue.h:19
GetNewAddress
static UniValue GetNewAddress()
Call RPC getnewaddress.
Definition: bitcoin-cli.cpp:1061
NetinfoRequestHandler::Peer::min_ping
double min_ping
Definition: bitcoin-cli.cpp:392
NetinfoRequestHandler::Peer::last_trxn
int64_t last_trxn
Definition: bitcoin-cli.cpp:399
ArgsManager::GetIntArg
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:591
NetinfoRequestHandler::ChainToString
std::string ChainToString() const
Definition: bitcoin-cli.cpp:411
NetinfoRequestHandler::DetailsRequested
bool DetailsRequested() const
Definition: bitcoin-cli.cpp:377
GetinfoRequestHandler::ID_BALANCES
const int ID_BALANCES
Definition: bitcoin-cli.cpp:299
UniValue::VSTR
@ VSTR
Definition: univalue.h:19
DefaultRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:700
AddrinfoRequestHandler::NetworkStringToId
int8_t NetworkStringToId(const std::string &str) const
Definition: bitcoin-cli.cpp:246
http_request_done
static void http_request_done(struct evhttp_request *req, void *ctx)
Definition: bitcoin-cli.cpp:198
NetinfoRequestHandler::m_max_age_length
size_t m_max_age_length
Definition: bitcoin-cli.cpp:384
ParseUInt8
bool ParseUInt8(const std::string &str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
Definition: strencodings.cpp:309
NetinfoRequestHandler::Peer::version
int version
Definition: bitcoin-cli.cpp:402
UniValue::setStr
bool setStr(const std::string &val)
Definition: univalue.cpp:86
GetinfoRequestHandler::ID_BLOCKCHAININFO
const int ID_BLOCKCHAININFO
Definition: bitcoin-cli.cpp:297
CConnectionFailed
Definition: bitcoin-cli.cpp:107
client.h
StdinTerminal
bool StdinTerminal()
Definition: stdin.cpp:47
ctx
static secp256k1_context * ctx
Definition: tests.c:32
ArgsManager::NETWORK_ONLY
@ NETWORK_ONLY
Definition: system.h:179
HTTPReply::status
int status
Definition: bitcoin-cli.cpp:171
CBaseChainParams::SIGNET
static const std::string SIGNET
Definition: chainparamsbase.h:24
BaseRequestHandler::PrepareRequest
virtual UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args)=0
args
ArgsManager args
Definition: notifications.cpp:36
GetTimeSeconds
int64_t GetTimeSeconds()
Returns the system time (not mockable)
Definition: time.cpp:127
StdinReady
bool StdinReady()
Definition: stdin.cpp:56
HTTP_INTERNAL_SERVER_ERROR
@ HTTP_INTERNAL_SERVER_ERROR
Definition: protocol.h:18
CommandLineRPC
static int CommandLineRPC(int argc, char *argv[])
Definition: bitcoin-cli.cpp:1085
SetGenerateToAddressArgs
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.
Definition: bitcoin-cli.cpp:1074