Bitcoin Core  21.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-2020 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 <rpc/client.h>
13 #include <rpc/mining.h>
14 #include <rpc/protocol.h>
15 #include <rpc/request.h>
16 #include <tinyformat.h>
17 #include <util/strencodings.h>
18 #include <util/system.h>
19 #include <util/translation.h>
20 #include <util/url.h>
21 
22 #include <algorithm>
23 #include <cmath>
24 #include <functional>
25 #include <memory>
26 #include <optional>
27 #include <stdio.h>
28 #include <string>
29 #include <tuple>
30 
31 #include <event2/buffer.h>
32 #include <event2/keyvalq_struct.h>
33 #include <support/events.h>
34 
35 #include <univalue.h>
36 #include <compat/stdin.h>
37 
38 const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
40 
41 static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
42 static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
43 static const bool DEFAULT_NAMED=false;
44 static const int CONTINUE_EXECUTION=-1;
45 
47 static const std::string DEFAULT_NBLOCKS = "1";
48 
49 static void SetupCliArgs(ArgsManager& argsman)
50 {
51  SetupHelpOptions(argsman);
52 
53  const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
54  const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
55  const auto signetBaseParams = CreateBaseChainParams(CBaseChainParams::SIGNET);
56  const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
57 
58  argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
59  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);
60  argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
61  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);
62  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);
63  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);
64 
66  argsman.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
67  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);
68  argsman.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
69  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);
70  argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
71  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);
72  argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
73  argsman.AddArg("-rpcwait", "Wait for RPC server to start", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
74  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);
75  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);
76  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);
77  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);
78 }
79 
81 static void libevent_log_cb(int severity, const char *msg)
82 {
83 #ifndef EVENT_LOG_ERR // EVENT_LOG_ERR was added in 2.0.19; but before then _EVENT_LOG_ERR existed.
84 # define EVENT_LOG_ERR _EVENT_LOG_ERR
85 #endif
86  // Ignore everything other than errors
87  if (severity >= EVENT_LOG_ERR) {
88  throw std::runtime_error(strprintf("libevent error: %s", msg));
89  }
90 }
91 
92 //
93 // Exception thrown on connection error. This error is used to determine
94 // when to wait if -rpcwait is given.
95 //
96 class CConnectionFailed : public std::runtime_error
97 {
98 public:
99 
100  explicit inline CConnectionFailed(const std::string& msg) :
101  std::runtime_error(msg)
102  {}
103 
104 };
105 
106 //
107 // This function returns either one of EXIT_ codes when it's expected to stop the process or
108 // CONTINUE_EXECUTION when it's expected to continue further.
109 //
110 static int AppInitRPC(int argc, char* argv[])
111 {
113  std::string error;
114  if (!gArgs.ParseParameters(argc, argv, error)) {
115  tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);
116  return EXIT_FAILURE;
117  }
118  if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
119  std::string strUsage = PACKAGE_NAME " RPC client version " + FormatFullVersion() + "\n";
120  if (!gArgs.IsArgSet("-version")) {
121  strUsage += "\n"
122  "Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n"
123  "or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n"
124  "or: bitcoin-cli [options] help List commands\n"
125  "or: bitcoin-cli [options] help <command> Get help for a command\n";
126  strUsage += "\n" + gArgs.GetHelpMessage();
127  }
128 
129  tfm::format(std::cout, "%s", strUsage);
130  if (argc < 2) {
131  tfm::format(std::cerr, "Error: too few parameters\n");
132  return EXIT_FAILURE;
133  }
134  return EXIT_SUCCESS;
135  }
136  if (!CheckDataDirOption()) {
137  tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""));
138  return EXIT_FAILURE;
139  }
140  if (!gArgs.ReadConfigFiles(error, true)) {
141  tfm::format(std::cerr, "Error reading configuration file: %s\n", error);
142  return EXIT_FAILURE;
143  }
144  // Check for chain settings (BaseParams() calls are only valid after this clause)
145  try {
147  } catch (const std::exception& e) {
148  tfm::format(std::cerr, "Error: %s\n", e.what());
149  return EXIT_FAILURE;
150  }
151  return CONTINUE_EXECUTION;
152 }
153 
154 
156 struct HTTPReply
157 {
158  HTTPReply(): status(0), error(-1) {}
159 
160  int status;
161  int error;
162  std::string body;
163 };
164 
165 static std::string http_errorstring(int code)
166 {
167  switch(code) {
168 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
169  case EVREQ_HTTP_TIMEOUT:
170  return "timeout reached";
171  case EVREQ_HTTP_EOF:
172  return "EOF reached";
173  case EVREQ_HTTP_INVALID_HEADER:
174  return "error while reading header, or invalid header";
175  case EVREQ_HTTP_BUFFER_ERROR:
176  return "error encountered while reading or writing";
177  case EVREQ_HTTP_REQUEST_CANCEL:
178  return "request was canceled";
179  case EVREQ_HTTP_DATA_TOO_LONG:
180  return "response body is larger than allowed";
181 #endif
182  default:
183  return "unknown";
184  }
185 }
186 
187 static void http_request_done(struct evhttp_request *req, void *ctx)
188 {
189  HTTPReply *reply = static_cast<HTTPReply*>(ctx);
190 
191  if (req == nullptr) {
192  /* If req is nullptr, it means an error occurred while connecting: the
193  * error code will have been passed to http_error_cb.
194  */
195  reply->status = 0;
196  return;
197  }
198 
199  reply->status = evhttp_request_get_response_code(req);
200 
201  struct evbuffer *buf = evhttp_request_get_input_buffer(req);
202  if (buf)
203  {
204  size_t size = evbuffer_get_length(buf);
205  const char *data = (const char*)evbuffer_pullup(buf, size);
206  if (data)
207  reply->body = std::string(data, size);
208  evbuffer_drain(buf, size);
209  }
210 }
211 
212 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
213 static void http_error_cb(enum evhttp_request_error err, void *ctx)
214 {
215  HTTPReply *reply = static_cast<HTTPReply*>(ctx);
216  reply->error = err;
217 }
218 #endif
219 
224 {
225 public:
226  virtual ~BaseRequestHandler() {}
227  virtual UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) = 0;
228  virtual UniValue ProcessReply(const UniValue &batch_in) = 0;
229 };
230 
233 {
234 public:
235  const int ID_NETWORKINFO = 0;
236  const int ID_BLOCKCHAININFO = 1;
237  const int ID_WALLETINFO = 2;
238  const int ID_BALANCES = 3;
239 
241  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
242  {
243  if (!args.empty()) {
244  throw std::runtime_error("-getinfo takes no arguments");
245  }
246  UniValue result(UniValue::VARR);
247  result.push_back(JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
248  result.push_back(JSONRPCRequestObj("getblockchaininfo", NullUniValue, ID_BLOCKCHAININFO));
249  result.push_back(JSONRPCRequestObj("getwalletinfo", NullUniValue, ID_WALLETINFO));
250  result.push_back(JSONRPCRequestObj("getbalances", NullUniValue, ID_BALANCES));
251  return result;
252  }
253 
255  UniValue ProcessReply(const UniValue &batch_in) override
256  {
257  UniValue result(UniValue::VOBJ);
258  const std::vector<UniValue> batch = JSONRPCProcessBatchReply(batch_in);
259  // Errors in getnetworkinfo() and getblockchaininfo() are fatal, pass them on;
260  // getwalletinfo() and getbalances() are allowed to fail if there is no wallet.
261  if (!batch[ID_NETWORKINFO]["error"].isNull()) {
262  return batch[ID_NETWORKINFO];
263  }
264  if (!batch[ID_BLOCKCHAININFO]["error"].isNull()) {
265  return batch[ID_BLOCKCHAININFO];
266  }
267  result.pushKV("version", batch[ID_NETWORKINFO]["result"]["version"]);
268  result.pushKV("blocks", batch[ID_BLOCKCHAININFO]["result"]["blocks"]);
269  result.pushKV("headers", batch[ID_BLOCKCHAININFO]["result"]["headers"]);
270  result.pushKV("verificationprogress", batch[ID_BLOCKCHAININFO]["result"]["verificationprogress"]);
271  result.pushKV("timeoffset", batch[ID_NETWORKINFO]["result"]["timeoffset"]);
272 
273  UniValue connections(UniValue::VOBJ);
274  connections.pushKV("in", batch[ID_NETWORKINFO]["result"]["connections_in"]);
275  connections.pushKV("out", batch[ID_NETWORKINFO]["result"]["connections_out"]);
276  connections.pushKV("total", batch[ID_NETWORKINFO]["result"]["connections"]);
277  result.pushKV("connections", connections);
278 
279  result.pushKV("proxy", batch[ID_NETWORKINFO]["result"]["networks"][0]["proxy"]);
280  result.pushKV("difficulty", batch[ID_BLOCKCHAININFO]["result"]["difficulty"]);
281  result.pushKV("chain", UniValue(batch[ID_BLOCKCHAININFO]["result"]["chain"]));
282  if (!batch[ID_WALLETINFO]["result"].isNull()) {
283  result.pushKV("keypoolsize", batch[ID_WALLETINFO]["result"]["keypoolsize"]);
284  if (!batch[ID_WALLETINFO]["result"]["unlocked_until"].isNull()) {
285  result.pushKV("unlocked_until", batch[ID_WALLETINFO]["result"]["unlocked_until"]);
286  }
287  result.pushKV("paytxfee", batch[ID_WALLETINFO]["result"]["paytxfee"]);
288  }
289  if (!batch[ID_BALANCES]["result"].isNull()) {
290  result.pushKV("balance", batch[ID_BALANCES]["result"]["mine"]["trusted"]);
291  }
292  result.pushKV("relayfee", batch[ID_NETWORKINFO]["result"]["relayfee"]);
293  result.pushKV("warnings", batch[ID_NETWORKINFO]["result"]["warnings"]);
294  return JSONRPCReplyObj(result, NullUniValue, 1);
295  }
296 };
297 
300 {
301 private:
302  static constexpr int8_t UNKNOWN_NETWORK{-1};
303  static constexpr uint8_t m_networks_size{4};
304  static constexpr uint8_t MAX_DETAIL_LEVEL{4};
305  const std::array<std::string, m_networks_size> m_networks{{"ipv4", "ipv6", "onion", "i2p"}};
306  std::array<std::array<uint16_t, m_networks_size + 1>, 3> m_counts{{{}}};
309  int8_t NetworkStringToId(const std::string& str) const
310  {
311  for (uint8_t i = 0; i < m_networks_size; ++i) {
312  if (str == m_networks.at(i)) return i;
313  }
314  return UNKNOWN_NETWORK;
315  }
316  uint8_t m_details_level{0};
317  bool DetailsRequested() const { return m_details_level > 0 && m_details_level < 5; }
318  bool IsAddressSelected() const { return m_details_level == 2 || m_details_level == 4; }
319  bool IsVersionSelected() const { return m_details_level == 3 || m_details_level == 4; }
320  bool m_is_asmap_on{false};
321  size_t m_max_addr_length{0};
322  size_t m_max_age_length{3};
323  size_t m_max_id_length{2};
324  struct Peer {
325  std::string addr;
326  std::string sub_version;
327  std::string conn_type;
328  std::string network;
329  std::string age;
330  double min_ping;
331  double ping;
332  int64_t last_blck;
333  int64_t last_recv;
334  int64_t last_send;
335  int64_t last_trxn;
336  int id;
338  int version;
343  bool operator<(const Peer& rhs) const { return std::tie(is_outbound, min_ping) < std::tie(rhs.is_outbound, rhs.min_ping); }
344  };
345  std::vector<Peer> m_peers;
346  std::string ChainToString() const
347  {
348  if (gArgs.GetChainName() == CBaseChainParams::TESTNET) return " testnet";
349  if (gArgs.GetChainName() == CBaseChainParams::SIGNET) return " signet";
350  if (gArgs.GetChainName() == CBaseChainParams::REGTEST) return " regtest";
351  return "";
352  }
353  std::string PingTimeToString(double seconds) const
354  {
355  if (seconds < 0) return "";
356  const double milliseconds{round(1000 * seconds)};
357  return milliseconds > 999999 ? "-" : ToString(milliseconds);
358  }
359  std::string ConnectionTypeForNetinfo(const std::string& conn_type) const
360  {
361  if (conn_type == "outbound-full-relay") return "full";
362  if (conn_type == "block-relay-only") return "block";
363  if (conn_type == "manual" || conn_type == "feeler") return conn_type;
364  if (conn_type == "addr-fetch") return "addr";
365  return "";
366  }
368 
369 public:
370  static constexpr int ID_PEERINFO = 0;
371  static constexpr int ID_NETWORKINFO = 1;
372 
373  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
374  {
375  if (!args.empty()) {
376  uint8_t n{0};
377  if (ParseUInt8(args.at(0), &n)) {
378  m_details_level = std::min(n, MAX_DETAIL_LEVEL);
379  } else {
380  throw std::runtime_error(strprintf("invalid -netinfo argument: %s\nFor more information, run: bitcoin-cli -netinfo help", args.at(0)));
381  }
382  }
383  UniValue result(UniValue::VARR);
384  result.push_back(JSONRPCRequestObj("getpeerinfo", NullUniValue, ID_PEERINFO));
385  result.push_back(JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
386  return result;
387  }
388 
389  UniValue ProcessReply(const UniValue& batch_in) override
390  {
391  const std::vector<UniValue> batch{JSONRPCProcessBatchReply(batch_in)};
392  if (!batch[ID_PEERINFO]["error"].isNull()) return batch[ID_PEERINFO];
393  if (!batch[ID_NETWORKINFO]["error"].isNull()) return batch[ID_NETWORKINFO];
394 
395  const UniValue& networkinfo{batch[ID_NETWORKINFO]["result"]};
396  if (networkinfo["version"].get_int() < 209900) {
397  throw std::runtime_error("-netinfo requires bitcoind server to be running v0.21.0 and up");
398  }
399 
400  // Count peer connection totals, and if DetailsRequested(), store peer data in a vector of structs.
401  for (const UniValue& peer : batch[ID_PEERINFO]["result"].getValues()) {
402  const std::string network{peer["network"].get_str()};
403  const int8_t network_id{NetworkStringToId(network)};
404  if (network_id == UNKNOWN_NETWORK) continue;
405  const bool is_outbound{!peer["inbound"].get_bool()};
406  const bool is_block_relay{!peer["relaytxes"].get_bool()};
407  const std::string conn_type{peer["connection_type"].get_str()};
408  ++m_counts.at(is_outbound).at(network_id); // in/out by network
409  ++m_counts.at(is_outbound).at(m_networks_size); // in/out overall
410  ++m_counts.at(2).at(network_id); // total by network
411  ++m_counts.at(2).at(m_networks_size); // total overall
412  if (conn_type == "block-relay-only") ++m_block_relay_peers_count;
413  if (conn_type == "manual") ++m_manual_peers_count;
414  if (DetailsRequested()) {
415  // Push data for this peer to the peers vector.
416  const int peer_id{peer["id"].get_int()};
417  const int mapped_as{peer["mapped_as"].isNull() ? 0 : peer["mapped_as"].get_int()};
418  const int version{peer["version"].get_int()};
419  const int64_t conn_time{peer["conntime"].get_int64()};
420  const int64_t last_blck{peer["last_block"].get_int64()};
421  const int64_t last_recv{peer["lastrecv"].get_int64()};
422  const int64_t last_send{peer["lastsend"].get_int64()};
423  const int64_t last_trxn{peer["last_transaction"].get_int64()};
424  const double min_ping{peer["minping"].isNull() ? -1 : peer["minping"].get_real()};
425  const double ping{peer["pingtime"].isNull() ? -1 : peer["pingtime"].get_real()};
426  const std::string addr{peer["addr"].get_str()};
427  const std::string age{conn_time == 0 ? "" : ToString((m_time_now - conn_time) / 60)};
428  const std::string sub_version{peer["subver"].get_str()};
429  const bool is_bip152_hb_from{peer["bip152_hb_from"].get_bool()};
430  const bool is_bip152_hb_to{peer["bip152_hb_to"].get_bool()};
431  m_peers.push_back({addr, sub_version, conn_type, network, age, min_ping, ping, last_blck, last_recv, last_send, last_trxn, peer_id, mapped_as, version, is_bip152_hb_from, is_bip152_hb_to, is_block_relay, is_outbound});
432  m_max_addr_length = std::max(addr.length() + 1, m_max_addr_length);
433  m_max_age_length = std::max(age.length(), m_max_age_length);
434  m_max_id_length = std::max(ToString(peer_id).length(), m_max_id_length);
435  m_is_asmap_on |= (mapped_as != 0);
436  }
437  }
438 
439  // Generate report header.
440  std::string result{strprintf("%s %s%s - %i%s\n\n", PACKAGE_NAME, FormatFullVersion(), ChainToString(), networkinfo["protocolversion"].get_int(), networkinfo["subversion"].get_str())};
441 
442  // Report detailed peer connections list sorted by direction and minimum ping time.
443  if (DetailsRequested() && !m_peers.empty()) {
444  std::sort(m_peers.begin(), m_peers.end());
445  result += strprintf("<-> type net mping ping send recv txn blk hb %*s ", m_max_age_length, "age");
446  if (m_is_asmap_on) result += " asmap ";
447  result += strprintf("%*s %-*s%s\n", m_max_id_length, "id", IsAddressSelected() ? m_max_addr_length : 0, IsAddressSelected() ? "address" : "", IsVersionSelected() ? "version" : "");
448  for (const Peer& peer : m_peers) {
449  std::string version{ToString(peer.version) + peer.sub_version};
450  result += strprintf(
451  "%3s %6s %5s%7s%7s%5s%5s%5s%5s %2s %*s%*i %*s %-*s%s\n",
452  peer.is_outbound ? "out" : "in",
453  ConnectionTypeForNetinfo(peer.conn_type),
454  peer.network,
455  PingTimeToString(peer.min_ping),
456  PingTimeToString(peer.ping),
457  peer.last_send == 0 ? "" : ToString(m_time_now - peer.last_send),
458  peer.last_recv == 0 ? "" : ToString(m_time_now - peer.last_recv),
459  peer.last_trxn == 0 ? "" : ToString((m_time_now - peer.last_trxn) / 60),
460  peer.last_blck == 0 ? "" : ToString((m_time_now - peer.last_blck) / 60),
461  strprintf("%s%s", peer.is_bip152_hb_to ? "." : " ", peer.is_bip152_hb_from ? "*" : " "),
462  m_max_age_length, // variable spacing
463  peer.age,
464  m_is_asmap_on ? 7 : 0, // variable spacing
465  m_is_asmap_on && peer.mapped_as != 0 ? ToString(peer.mapped_as) : "",
466  m_max_id_length, // variable spacing
467  peer.id,
468  IsAddressSelected() ? m_max_addr_length : 0, // variable spacing
469  IsAddressSelected() ? peer.addr : "",
470  IsVersionSelected() && version != "0" ? version : "");
471  }
472  result += strprintf(" ms ms sec sec min min %*s\n\n", m_max_age_length, "min");
473  }
474 
475  // Report peer connection totals by type.
476  result += " ipv4 ipv6 onion";
477  const bool any_i2p_peers = m_counts.at(2).at(3); // false if total i2p peers count is 0, otherwise true
478  if (any_i2p_peers) result += " i2p";
479  result += " total block";
480  if (m_manual_peers_count) result += " manual";
481  const std::array<std::string, 3> rows{{"in", "out", "total"}};
482  for (uint8_t i = 0; i < 3; ++i) {
483  result += strprintf("\n%-5s %5i %5i %5i", rows.at(i), m_counts.at(i).at(0), m_counts.at(i).at(1), m_counts.at(i).at(2)); // ipv4/ipv6/onion peers counts
484  if (any_i2p_peers) result += strprintf(" %5i", m_counts.at(i).at(3)); // i2p peers count
485  result += strprintf(" %5i", m_counts.at(i).at(m_networks_size)); // total peers count
486  if (i == 1) { // the outbound row has two extra columns for block relay and manual peer counts
487  result += strprintf(" %5i", m_block_relay_peers_count);
488  if (m_manual_peers_count) result += strprintf(" %5i", m_manual_peers_count);
489  }
490  }
491 
492  // Report local addresses, ports, and scores.
493  result += "\n\nLocal addresses";
494  const std::vector<UniValue>& local_addrs{networkinfo["localaddresses"].getValues()};
495  if (local_addrs.empty()) {
496  result += ": n/a\n";
497  } else {
498  size_t max_addr_size{0};
499  for (const UniValue& addr : local_addrs) {
500  max_addr_size = std::max(addr["address"].get_str().length() + 1, max_addr_size);
501  }
502  for (const UniValue& addr : local_addrs) {
503  result += strprintf("\n%-*s port %6i score %6i", max_addr_size, addr["address"].get_str(), addr["port"].get_int(), addr["score"].get_int());
504  }
505  }
506 
507  return JSONRPCReplyObj(UniValue{result}, NullUniValue, 1);
508  }
509 
510  const std::string m_help_doc{
511  "-netinfo level|\"help\" \n\n"
512  "Returns a network peer connections dashboard with information from the remote server.\n"
513  "This human-readable interface will change regularly and is not intended to be a stable API.\n"
514  "Under the hood, -netinfo fetches the data by calling getpeerinfo and getnetworkinfo.\n"
515  + 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) +
516  "Pass \"help\" to see this detailed help documentation.\n"
517  "If more than one argument is passed, only the first one is read and parsed.\n"
518  "Suggestion: use with the Linux watch(1) command for a live dashboard; see example below.\n\n"
519  "Arguments:\n"
520  + strprintf("1. level (integer 0-%d, optional) Specify the info level of the peers dashboard (default 0):\n", MAX_DETAIL_LEVEL) +
521  " 0 - Connection counts and local addresses\n"
522  " 1 - Like 0 but with a peers listing (without address or version columns)\n"
523  " 2 - Like 1 but with an address column\n"
524  " 3 - Like 1 but with a version column\n"
525  " 4 - Like 1 but with both address and version columns\n"
526  "2. help (string \"help\", optional) Print this help documentation instead of the dashboard.\n\n"
527  "Result:\n\n"
528  + 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) +
529  " Column Description\n"
530  " ------ -----------\n"
531  " <-> Direction\n"
532  " \"in\" - inbound connections are those initiated by the peer\n"
533  " \"out\" - outbound connections are those initiated by us\n"
534  " type Type of peer connection\n"
535  " \"full\" - full relay, the default\n"
536  " \"block\" - block relay; like full relay but does not relay transactions or addresses\n"
537  " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n"
538  " \"feeler\" - short-lived connection for testing addresses\n"
539  " \"addr\" - address fetch; short-lived connection for requesting addresses\n"
540  " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", or \"cjdns\")\n"
541  " mping Minimum observed ping time, in milliseconds (ms)\n"
542  " ping Last observed ping time, in milliseconds (ms)\n"
543  " send Time since last message sent to the peer, in seconds\n"
544  " recv Time since last message received from the peer, in seconds\n"
545  " txn Time since last novel transaction received from the peer and accepted into our mempool, in minutes\n"
546  " blk Time since last novel block passing initial validity checks received from the peer, in minutes\n"
547  " hb High-bandwidth BIP152 compact block relay\n"
548  " \".\" (to) - we selected the peer as a high-bandwidth peer\n"
549  " \"*\" (from) - the peer selected us as a high-bandwidth peer\n"
550  " age Duration of connection to the peer, in minutes\n"
551  " asmap Mapped AS (Autonomous System) number in the BGP route to the peer, used for diversifying\n"
552  " peer selection (only displayed if the -asmap config option is set)\n"
553  " id Peer index, in increasing order of peer connections since node startup\n"
554  " address IP address and port of the peer\n"
555  " version Peer version and subversion concatenated, e.g. \"70016/Satoshi:21.0.0/\"\n\n"
556  "* The connection counts table displays the number of peers by direction, network, and the totals\n"
557  " for each, as well as two special outbound columns for block relay peers and manual peers.\n\n"
558  "* The local addresses table lists each local address broadcast by the node, the port, and the score.\n\n"
559  "Examples:\n\n"
560  "Connection counts and local addresses only\n"
561  "> bitcoin-cli -netinfo\n\n"
562  "Compact peers listing\n"
563  "> bitcoin-cli -netinfo 1\n\n"
564  "Full dashboard\n"
565  + strprintf("> bitcoin-cli -netinfo %d\n\n", MAX_DETAIL_LEVEL) +
566  "Full live dashboard, adjust --interval or --no-title as needed (Linux)\n"
567  + strprintf("> watch --interval 1 --no-title bitcoin-cli -netinfo %d\n\n", MAX_DETAIL_LEVEL) +
568  "See this help\n"
569  "> bitcoin-cli -netinfo help\n"};
570 };
571 
574 {
575 public:
576  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
577  {
578  address_str = args.at(1);
579  UniValue params{RPCConvertValues("generatetoaddress", args)};
580  return JSONRPCRequestObj("generatetoaddress", params, 1);
581  }
582 
583  UniValue ProcessReply(const UniValue &reply) override
584  {
585  UniValue result(UniValue::VOBJ);
586  result.pushKV("address", address_str);
587  result.pushKV("blocks", reply.get_obj()["result"]);
588  return JSONRPCReplyObj(result, NullUniValue, 1);
589  }
590 protected:
591  std::string address_str;
592 };
593 
596 public:
597  UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
598  {
599  UniValue params;
600  if(gArgs.GetBoolArg("-named", DEFAULT_NAMED)) {
601  params = RPCConvertNamedValues(method, args);
602  } else {
603  params = RPCConvertValues(method, args);
604  }
605  return JSONRPCRequestObj(method, params, 1);
606  }
607 
608  UniValue ProcessReply(const UniValue &reply) override
609  {
610  return reply.get_obj();
611  }
612 };
613 
614 static UniValue CallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const std::optional<std::string>& rpcwallet = {})
615 {
616  std::string host;
617  // In preference order, we choose the following for the port:
618  // 1. -rpcport
619  // 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6)
620  // 3. default port for chain
621  uint16_t port{BaseParams().RPCPort()};
622  SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host);
623  port = static_cast<uint16_t>(gArgs.GetArg("-rpcport", port));
624 
625  // Obtain event base
626  raii_event_base base = obtain_event_base();
627 
628  // Synchronously look up hostname
629  raii_evhttp_connection evcon = obtain_evhttp_connection_base(base.get(), host, port);
630 
631  // Set connection timeout
632  {
633  const int timeout = gArgs.GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT);
634  if (timeout > 0) {
635  evhttp_connection_set_timeout(evcon.get(), timeout);
636  } else {
637  // Indefinite request timeouts are not possible in libevent-http, so we
638  // set the timeout to a very long time period instead.
639 
640  constexpr int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
641  evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
642  }
643  }
644 
645  HTTPReply response;
646  raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response);
647  if (req == nullptr)
648  throw std::runtime_error("create http request failed");
649 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
650  evhttp_request_set_error_cb(req.get(), http_error_cb);
651 #endif
652 
653  // Get credentials
654  std::string strRPCUserColonPass;
655  bool failedToGetAuthCookie = false;
656  if (gArgs.GetArg("-rpcpassword", "") == "") {
657  // Try fall back to cookie-based authentication if no password is provided
659  failedToGetAuthCookie = true;
660  }
661  } else {
662  strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" + gArgs.GetArg("-rpcpassword", "");
663  }
664 
665  struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get());
666  assert(output_headers);
667  evhttp_add_header(output_headers, "Host", host.c_str());
668  evhttp_add_header(output_headers, "Connection", "close");
669  evhttp_add_header(output_headers, "Content-Type", "application/json");
670  evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());
671 
672  // Attach request data
673  std::string strRequest = rh->PrepareRequest(strMethod, args).write() + "\n";
674  struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get());
675  assert(output_buffer);
676  evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
677 
678  // check if we should use a special wallet endpoint
679  std::string endpoint = "/";
680  if (rpcwallet) {
681  char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(), false);
682  if (encodedURI) {
683  endpoint = "/wallet/" + std::string(encodedURI);
684  free(encodedURI);
685  } else {
686  throw CConnectionFailed("uri-encode failed");
687  }
688  }
689  int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, endpoint.c_str());
690  req.release(); // ownership moved to evcon in above call
691  if (r != 0) {
692  throw CConnectionFailed("send http request failed");
693  }
694 
695  event_base_dispatch(base.get());
696 
697  if (response.status == 0) {
698  std::string responseErrorMessage;
699  if (response.error != -1) {
700  responseErrorMessage = strprintf(" (error code %d - \"%s\")", response.error, http_errorstring(response.error));
701  }
702  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));
703  } else if (response.status == HTTP_UNAUTHORIZED) {
704  if (failedToGetAuthCookie) {
705  throw std::runtime_error(strprintf(
706  "Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)",
707  GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string()));
708  } else {
709  throw std::runtime_error("Authorization failed: Incorrect rpcuser or rpcpassword");
710  }
711  } else if (response.status == HTTP_SERVICE_UNAVAILABLE) {
712  throw std::runtime_error(strprintf("Server response: %s", response.body));
713  } else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
714  throw std::runtime_error(strprintf("server returned HTTP error %d", response.status));
715  else if (response.body.empty())
716  throw std::runtime_error("no response from server");
717 
718  // Parse reply
719  UniValue valReply(UniValue::VSTR);
720  if (!valReply.read(response.body))
721  throw std::runtime_error("couldn't parse reply from server");
722  const UniValue reply = rh->ProcessReply(valReply);
723  if (reply.empty())
724  throw std::runtime_error("expected reply to have result, error and id properties");
725 
726  return reply;
727 }
728 
738 static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const std::optional<std::string>& rpcwallet = {})
739 {
740  UniValue response(UniValue::VOBJ);
741  // Execute and handle connection failures with -rpcwait.
742  const bool fWait = gArgs.GetBoolArg("-rpcwait", false);
743  do {
744  try {
745  response = CallRPC(rh, strMethod, args, rpcwallet);
746  if (fWait) {
747  const UniValue& error = find_value(response, "error");
748  if (!error.isNull() && error["code"].get_int() == RPC_IN_WARMUP) {
749  throw CConnectionFailed("server in warmup");
750  }
751  }
752  break; // Connection succeeded, no need to retry.
753  } catch (const CConnectionFailed&) {
754  if (fWait) {
755  UninterruptibleSleep(std::chrono::milliseconds{1000});
756  } else {
757  throw;
758  }
759  }
760  } while (fWait);
761  return response;
762 }
763 
765 static void ParseResult(const UniValue& result, std::string& strPrint)
766 {
767  if (result.isNull()) return;
768  strPrint = result.isStr() ? result.get_str() : result.write(2);
769 }
770 
772 static void ParseError(const UniValue& error, std::string& strPrint, int& nRet)
773 {
774  if (error.isObject()) {
775  const UniValue& err_code = find_value(error, "code");
776  const UniValue& err_msg = find_value(error, "message");
777  if (!err_code.isNull()) {
778  strPrint = "error code: " + err_code.getValStr() + "\n";
779  }
780  if (err_msg.isStr()) {
781  strPrint += ("error message:\n" + err_msg.get_str());
782  }
783  if (err_code.isNum() && err_code.get_int() == RPC_WALLET_NOT_SPECIFIED) {
784  strPrint += "\nTry adding \"-rpcwallet=<filename>\" option to bitcoin-cli command line.";
785  }
786  } else {
787  strPrint = "error: " + error.write();
788  }
789  nRet = abs(error["code"].get_int());
790 }
791 
798 static void GetWalletBalances(UniValue& result)
799 {
801  const UniValue listwallets = ConnectAndCallRPC(&rh, "listwallets", /* args=*/{});
802  if (!find_value(listwallets, "error").isNull()) return;
803  const UniValue& wallets = find_value(listwallets, "result");
804  if (wallets.size() <= 1) return;
805 
806  UniValue balances(UniValue::VOBJ);
807  for (const UniValue& wallet : wallets.getValues()) {
808  const std::string wallet_name = wallet.get_str();
809  const UniValue getbalances = ConnectAndCallRPC(&rh, "getbalances", /* args=*/{}, wallet_name);
810  const UniValue& balance = find_value(getbalances, "result")["mine"]["trusted"];
811  balances.pushKV(wallet_name, balance);
812  }
813  result.pushKV("balances", balances);
814 }
815 
821 {
822  std::optional<std::string> wallet_name{};
823  if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");
825  return ConnectAndCallRPC(&rh, "getnewaddress", /* args=*/{}, wallet_name);
826 }
827 
833 static void SetGenerateToAddressArgs(const std::string& address, std::vector<std::string>& args)
834 {
835  if (args.size() > 2) throw std::runtime_error("too many arguments (maximum 2 for nblocks and maxtries)");
836  if (args.size() == 0) {
837  args.emplace_back(DEFAULT_NBLOCKS);
838  } else if (args.at(0) == "0") {
839  throw std::runtime_error("the first argument (number of blocks to generate, default: " + DEFAULT_NBLOCKS + ") must be an integer value greater than zero");
840  }
841  args.emplace(args.begin() + 1, address);
842 }
843 
844 static int CommandLineRPC(int argc, char *argv[])
845 {
846  std::string strPrint;
847  int nRet = 0;
848  try {
849  // Skip switches
850  while (argc > 1 && IsSwitchChar(argv[1][0])) {
851  argc--;
852  argv++;
853  }
854  std::string rpcPass;
855  if (gArgs.GetBoolArg("-stdinrpcpass", false)) {
856  NO_STDIN_ECHO();
857  if (!StdinReady()) {
858  fputs("RPC password> ", stderr);
859  fflush(stderr);
860  }
861  if (!std::getline(std::cin, rpcPass)) {
862  throw std::runtime_error("-stdinrpcpass specified but failed to read from standard input");
863  }
864  if (StdinTerminal()) {
865  fputc('\n', stdout);
866  }
867  gArgs.ForceSetArg("-rpcpassword", rpcPass);
868  }
869  std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
870  if (gArgs.GetBoolArg("-stdinwalletpassphrase", false)) {
871  NO_STDIN_ECHO();
872  std::string walletPass;
873  if (args.size() < 1 || args[0].substr(0, 16) != "walletpassphrase") {
874  throw std::runtime_error("-stdinwalletpassphrase is only applicable for walletpassphrase(change)");
875  }
876  if (!StdinReady()) {
877  fputs("Wallet passphrase> ", stderr);
878  fflush(stderr);
879  }
880  if (!std::getline(std::cin, walletPass)) {
881  throw std::runtime_error("-stdinwalletpassphrase specified but failed to read from standard input");
882  }
883  if (StdinTerminal()) {
884  fputc('\n', stdout);
885  }
886  args.insert(args.begin() + 1, walletPass);
887  }
888  if (gArgs.GetBoolArg("-stdin", false)) {
889  // Read one arg per line from stdin and append
890  std::string line;
891  while (std::getline(std::cin, line)) {
892  args.push_back(line);
893  }
894  if (StdinTerminal()) {
895  fputc('\n', stdout);
896  }
897  }
898  std::unique_ptr<BaseRequestHandler> rh;
899  std::string method;
900  if (gArgs.IsArgSet("-getinfo")) {
901  rh.reset(new GetinfoRequestHandler());
902  } else if (gArgs.GetBoolArg("-netinfo", false)) {
903  if (!args.empty() && args.at(0) == "help") {
904  tfm::format(std::cout, "%s\n", NetinfoRequestHandler().m_help_doc);
905  return 0;
906  }
907  rh.reset(new NetinfoRequestHandler());
908  } else if (gArgs.GetBoolArg("-generate", false)) {
910  const UniValue& error{find_value(getnewaddress, "error")};
911  if (error.isNull()) {
912  SetGenerateToAddressArgs(find_value(getnewaddress, "result").get_str(), args);
913  rh.reset(new GenerateToAddressRequestHandler());
914  } else {
915  ParseError(error, strPrint, nRet);
916  }
917  } else {
918  rh.reset(new DefaultRequestHandler());
919  if (args.size() < 1) {
920  throw std::runtime_error("too few parameters (need at least command)");
921  }
922  method = args[0];
923  args.erase(args.begin()); // Remove trailing method name from arguments vector
924  }
925  if (nRet == 0) {
926  // Perform RPC call
927  std::optional<std::string> wallet_name{};
928  if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");
929  const UniValue reply = ConnectAndCallRPC(rh.get(), method, args, wallet_name);
930 
931  // Parse reply
932  UniValue result = find_value(reply, "result");
933  const UniValue& error = find_value(reply, "error");
934  if (error.isNull()) {
935  if (gArgs.IsArgSet("-getinfo") && !gArgs.IsArgSet("-rpcwallet")) {
936  GetWalletBalances(result); // fetch multiwallet balances and append to result
937  }
938  ParseResult(result, strPrint);
939  } else {
940  ParseError(error, strPrint, nRet);
941  }
942  }
943  } catch (const std::exception& e) {
944  strPrint = std::string("error: ") + e.what();
945  nRet = EXIT_FAILURE;
946  } catch (...) {
947  PrintExceptionContinue(nullptr, "CommandLineRPC()");
948  throw;
949  }
950 
951  if (strPrint != "") {
952  tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint);
953  }
954  return nRet;
955 }
956 
957 #ifdef WIN32
958 // Export main() and ensure working ASLR on Windows.
959 // Exporting a symbol will prevent the linker from stripping
960 // the .reloc section from the binary, which is a requirement
961 // for ASLR. This is a temporary workaround until a fixed
962 // version of binutils is used for releases.
963 __declspec(dllexport) int main(int argc, char* argv[])
964 {
965  util::WinCmdLineArgs winArgs;
966  std::tie(argc, argv) = winArgs.get();
967 #else
968 int main(int argc, char* argv[])
969 {
970 #endif
972  if (!SetupNetworking()) {
973  tfm::format(std::cerr, "Error: Initializing networking failed\n");
974  return EXIT_FAILURE;
975  }
976  event_set_log_callback(&libevent_log_cb);
977 
978  try {
979  int ret = AppInitRPC(argc, argv);
980  if (ret != CONTINUE_EXECUTION)
981  return ret;
982  }
983  catch (const std::exception& e) {
984  PrintExceptionContinue(&e, "AppInitRPC()");
985  return EXIT_FAILURE;
986  } catch (...) {
987  PrintExceptionContinue(nullptr, "AppInitRPC()");
988  return EXIT_FAILURE;
989  }
990 
991  int ret = EXIT_FAILURE;
992  try {
993  ret = CommandLineRPC(argc, argv);
994  }
995  catch (const std::exception& e) {
996  PrintExceptionContinue(&e, "CommandLineRPC()");
997  } catch (...) {
998  PrintExceptionContinue(nullptr, "CommandLineRPC()");
999  }
1000  return ret;
1001 }
DefaultRequestHandler
Process default single requests.
Definition: bitcoin-cli.cpp:595
GenerateToAddressRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:576
urlDecode
UrlDecodeFn urlDecode
Definition: url.h:11
NetinfoRequestHandler::ConnectionTypeForNetinfo
std::string ConnectionTypeForNetinfo(const std::string &conn_type) const
Definition: bitcoin-cli.cpp:359
NetinfoRequestHandler::m_peers
std::vector< Peer > m_peers
Definition: bitcoin-cli.cpp:345
NetinfoRequestHandler::Peer
Definition: bitcoin-cli.cpp:324
HTTPReply
Reply structure for request_done to fill in.
Definition: bitcoin-cli.cpp:156
NetinfoRequestHandler::m_is_asmap_on
bool m_is_asmap_on
Definition: bitcoin-cli.cpp:320
NetinfoRequestHandler
Process netinfo requests.
Definition: bitcoin-cli.cpp:299
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:515
NetinfoRequestHandler::m_max_id_length
size_t m_max_id_length
Definition: bitcoin-cli.cpp:323
HTTP_SERVICE_UNAVAILABLE
@ HTTP_SERVICE_UNAVAILABLE
Definition: protocol.h:19
GetConfigFile
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:816
ToString
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:79
DEFAULT_NBLOCKS
static const std::string DEFAULT_NBLOCKS
Default number of blocks to generate for RPC generatetoaddress.
Definition: bitcoin-cli.cpp:47
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:21
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:319
NetinfoRequestHandler::Peer::mapped_as
int mapped_as
Definition: bitcoin-cli.cpp:337
NetinfoRequestHandler::m_networks
const std::array< std::string, m_networks_size > m_networks
Definition: bitcoin-cli.cpp:305
NetinfoRequestHandler::m_time_now
const int64_t m_time_now
Definition: bitcoin-cli.cpp:367
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:801
SetupHelpOptions
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:657
GenerateToAddressRequestHandler::address_str
std::string address_str
Definition: bitcoin-cli.cpp:591
NetinfoRequestHandler::m_details_level
uint8_t m_details_level
Optional user-supplied arg to set dashboard details level.
Definition: bitcoin-cli.cpp:316
ArgsManager::GetHelpMessage
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:583
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
NetinfoRequestHandler::Peer::addr
std::string addr
Definition: bitcoin-cli.cpp:325
libevent_log_cb
static void libevent_log_cb(int severity, const char *msg)
libevent event log callback
Definition: bitcoin-cli.cpp:81
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1287
GetinfoRequestHandler
Process getinfo requests.
Definition: bitcoin-cli.cpp:232
AppInitRPC
static int AppInitRPC(int argc, char *argv[])
Definition: bitcoin-cli.cpp:110
NetinfoRequestHandler::ID_PEERINFO
static constexpr int ID_PEERINFO
Definition: bitcoin-cli.cpp:370
NetinfoRequestHandler::MAX_DETAIL_LEVEL
static constexpr uint8_t MAX_DETAIL_LEVEL
Definition: bitcoin-cli.cpp:304
chainparamsbase.h
HTTP_BAD_REQUEST
@ HTTP_BAD_REQUEST
Definition: protocol.h:13
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
Definition: system.h:174
SetupChainParamsBaseOptions
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
Definition: chainparamsbase.cpp:18
ArgsManager::GetChainName
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:982
getnewaddress
static RPCHelpMan getnewaddress()
Definition: rpcwallet.cpp:233
NetinfoRequestHandler::NetworkStringToId
int8_t NetworkStringToId(const std::string &str) const
Definition: bitcoin-cli.cpp:309
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:407
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
HTTPReply::body
std::string body
Definition: bitcoin-cli.cpp:162
CBaseChainParams::TESTNET
static const std::string TESTNET
Definition: chainparamsbase.h:23
SelectBaseParams
void SelectBaseParams(const std::string &chain)
Sets the params returned by Params() to those for the given network.
Definition: chainparamsbase.cpp:57
mining.h
NetinfoRequestHandler::Peer::id
int id
Definition: bitcoin-cli.cpp:336
protocol.h
GenerateToAddressRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:583
GetAuthCookie
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
Definition: request.cpp:108
clientversion.h
SetupNetworking
bool SetupNetworking()
Definition: system.cpp:1324
wallet
Definition: interfaces.cpp:47
UniValue::isNull
bool isNull() const
Definition: univalue.h:77
DEFAULT_HTTP_CLIENT_TIMEOUT
static const int DEFAULT_HTTP_CLIENT_TIMEOUT
Definition: bitcoin-cli.cpp:42
JSONRPCReplyObj
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:33
RPCConvertValues
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert positional arguments to command-specific RPC representation.
Definition: client.cpp:234
EncodeBase64
std::string EncodeBase64(Span< const unsigned char > input)
Definition: strencodings.cpp:131
bitcoin-config.h
NetinfoRequestHandler::UNKNOWN_NETWORK
static constexpr int8_t UNKNOWN_NETWORK
Definition: bitcoin-cli.cpp:302
UniValue::write
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Definition: univalue_write.cpp:29
UniValue::isNum
bool isNum() const
Definition: univalue.h:82
CConnectionFailed::CConnectionFailed
CConnectionFailed(const std::string &msg)
Definition: bitcoin-cli.cpp:100
NetinfoRequestHandler::m_max_addr_length
size_t m_max_addr_length
Definition: bitcoin-cli.cpp:321
NetinfoRequestHandler::Peer::age
std::string age
Definition: bitcoin-cli.cpp:329
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
NetinfoRequestHandler::Peer::is_block_relay
bool is_block_relay
Definition: bitcoin-cli.cpp:341
http_errorstring
static std::string http_errorstring(int code)
Definition: bitcoin-cli.cpp:165
balance
static CAmount balance
Definition: coinselector_tests.cpp:33
UniValue
Definition: univalue.h:19
tinyformat.h
NetinfoRequestHandler::Peer::is_bip152_hb_to
bool is_bip152_hb_to
Definition: bitcoin-cli.cpp:340
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:97
NetinfoRequestHandler::IsAddressSelected
bool IsAddressSelected() const
Definition: bitcoin-cli.cpp:318
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:652
strencodings.h
UniValue::isStr
bool isStr() const
Definition: univalue.h:81
DefaultRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:597
DEFAULT_RPCCONNECT
static const char DEFAULT_RPCCONNECT[]
Definition: bitcoin-cli.cpp:41
events.h
NetinfoRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &batch_in) override
Definition: bitcoin-cli.cpp:389
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:134
NetinfoRequestHandler::Peer::ping
double ping
Definition: bitcoin-cli.cpp:331
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:614
NetinfoRequestHandler::m_networks_size
static constexpr uint8_t m_networks_size
Definition: bitcoin-cli.cpp:303
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:772
NetinfoRequestHandler::m_manual_peers_count
uint8_t m_manual_peers_count
Definition: bitcoin-cli.cpp:308
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:365
NetinfoRequestHandler::PingTimeToString
std::string PingTimeToString(double seconds) const
Definition: bitcoin-cli.cpp:353
NetinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:373
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:555
NetinfoRequestHandler::m_help_doc
const std::string m_help_doc
Definition: bitcoin-cli.cpp:510
GetSystemTimeInSeconds
int64_t GetSystemTimeInSeconds()
Returns the system time (not mockable)
Definition: time.cpp:127
NetinfoRequestHandler::Peer::is_bip152_hb_from
bool is_bip152_hb_from
Definition: bitcoin-cli.cpp:339
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:253
IsSwitchChar
bool IsSwitchChar(char c)
Definition: system.h:132
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:537
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:503
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:307
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:332
main
int main(int argc, char *argv[])
Definition: bitcoin-cli.cpp:968
ArgsManager::ParseParameters
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:286
BaseRequestHandler::~BaseRequestHandler
virtual ~BaseRequestHandler()
Definition: bitcoin-cli.cpp:226
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:158
NO_STDIN_ECHO
#define NO_STDIN_ECHO()
Definition: stdin.h:13
EVENT_LOG_ERR
#define EVENT_LOG_ERR
GetinfoRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &batch_in) override
Collect values from the batch and form a simulated getinfo reply.
Definition: bitcoin-cli.cpp:255
ArgsManager::ReadConfigFiles
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:895
request.h
SetupCliArgs
static void SetupCliArgs(ArgsManager &argsman)
Definition: bitcoin-cli.cpp:49
CONTINUE_EXECUTION
static const int CONTINUE_EXECUTION
Definition: bitcoin-cli.cpp:44
GetWalletBalances
static void GetWalletBalances(UniValue &result)
GetWalletBalances calls listwallets; if more than one wallet is loaded, it then fetches mine....
Definition: bitcoin-cli.cpp:798
CBaseChainParams::MAIN
static const std::string MAIN
Chain name strings.
Definition: chainparamsbase.h:22
ping
static RPCHelpMan ping()
Definition: net.cpp:65
stdin.h
NetinfoRequestHandler::Peer::conn_type
std::string conn_type
Definition: bitcoin-cli.cpp:327
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
system.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
listwallets
static RPCHelpMan listwallets()
Definition: rpcwallet.cpp:2532
NetinfoRequestHandler::Peer::network
std::string network
Definition: bitcoin-cli.cpp:328
UniValue::getValStr
const std::string & getValStr() const
Definition: univalue.h:65
GetinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Create a simulated getinfo request.
Definition: bitcoin-cli.cpp:241
GetinfoRequestHandler::ID_WALLETINFO
const int ID_WALLETINFO
Definition: bitcoin-cli.cpp:237
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:371
obtain_event_base
raii_event_base obtain_event_base()
Definition: events.h:30
getbalances
static RPCHelpMan getbalances()
Definition: rpcwallet.cpp:2333
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:104
ArgsManager
Definition: system.h:166
translation.h
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:765
strRPCUserColonPass
static std::string strRPCUserColonPass
Definition: httprpc.cpp:68
gArgs
ArgsManager gArgs
Definition: system.cpp:79
NetinfoRequestHandler::Peer::last_recv
int64_t last_recv
Definition: bitcoin-cli.cpp:333
NetinfoRequestHandler::Peer::last_send
int64_t last_send
Definition: bitcoin-cli.cpp:334
HTTP_NOT_FOUND
@ HTTP_NOT_FOUND
Definition: protocol.h:16
DEFAULT_NAMED
static const bool DEFAULT_NAMED
Definition: bitcoin-cli.cpp:43
BaseRequestHandler
Class that handles the conversion from a command-line to a JSON-RPC request, as well as converting ba...
Definition: bitcoin-cli.cpp:223
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:161
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:738
NetinfoRequestHandler::Peer::sub_version
std::string sub_version
Definition: bitcoin-cli.cpp:326
UniValue::empty
bool empty() const
Definition: univalue.h:66
BITCOIN_CONF_FILENAME
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:76
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue_get.cpp:83
UniValue::size
size_t size() const
Definition: univalue.h:68
GetinfoRequestHandler::ID_NETWORKINFO
const int ID_NETWORKINFO
Definition: bitcoin-cli.cpp:235
GenerateToAddressRequestHandler
Process RPC generatetoaddress request.
Definition: bitcoin-cli.cpp:573
G_TRANSLATION_FUN
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
Definition: bitcoin-cli.cpp:38
find_value
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:234
NetinfoRequestHandler::Peer::operator<
bool operator<(const Peer &rhs) const
Definition: bitcoin-cli.cpp:343
URL_DECODE
UrlDecodeFn *const URL_DECODE
Definition: bitcoin-cli.cpp:39
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:50
NetinfoRequestHandler::Peer::is_outbound
bool is_outbound
Definition: bitcoin-cli.cpp:342
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:50
NetinfoRequestHandler::m_counts
std::array< std::array< uint16_t, m_networks_size+1 >, 3 > m_counts
Peer counts by (in/out/total, networks/total)
Definition: bitcoin-cli.cpp:306
UniValue::VARR
@ VARR
Definition: univalue.h:21
GetNewAddress
static UniValue GetNewAddress()
Call RPC getnewaddress.
Definition: bitcoin-cli.cpp:820
NetinfoRequestHandler::Peer::min_ping
double min_ping
Definition: bitcoin-cli.cpp:330
NetinfoRequestHandler::Peer::last_trxn
int64_t last_trxn
Definition: bitcoin-cli.cpp:335
NetinfoRequestHandler::ChainToString
std::string ChainToString() const
Definition: bitcoin-cli.cpp:346
NetinfoRequestHandler::DetailsRequested
bool DetailsRequested() const
Definition: bitcoin-cli.cpp:317
GetinfoRequestHandler::ID_BALANCES
const int ID_BALANCES
Definition: bitcoin-cli.cpp:238
UniValue::VSTR
@ VSTR
Definition: univalue.h:21
DefaultRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:608
http_request_done
static void http_request_done(struct evhttp_request *req, void *ctx)
Definition: bitcoin-cli.cpp:187
NetinfoRequestHandler::m_max_age_length
size_t m_max_age_length
Definition: bitcoin-cli.cpp:322
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:327
NetinfoRequestHandler::Peer::version
int version
Definition: bitcoin-cli.cpp:338
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
GetinfoRequestHandler::ID_BLOCKCHAININFO
const int ID_BLOCKCHAININFO
Definition: bitcoin-cli.cpp:236
CConnectionFailed
Definition: bitcoin-cli.cpp:96
client.h
StdinTerminal
bool StdinTerminal()
Definition: stdin.cpp:47
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:694
ctx
static secp256k1_context * ctx
Definition: tests.c:36
ArgsManager::NETWORK_ONLY
@ NETWORK_ONLY
Definition: system.h:181
HTTPReply::status
int status
Definition: bitcoin-cli.cpp:160
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
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:844
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:833