Bitcoin ABC  0.24.7
P2P Digital Currency
bitcoin-cli.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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)
7 #include <config/bitcoin-config.h>
8 #endif
9 
10 #include <chainparamsbase.h>
11 #include <clientversion.h>
12 #include <currencyunit.h>
13 #include <rpc/client.h>
14 #include <rpc/mining.h>
15 #include <rpc/protocol.h>
16 #include <rpc/request.h>
17 #include <support/events.h>
18 #include <util/strencodings.h>
19 #include <util/system.h>
20 #include <util/translation.h>
21 
22 #include <event2/buffer.h>
23 #include <event2/keyvalq_struct.h>
24 
25 #include <compat/stdin.h>
26 #include <univalue.h>
27 
28 #include <cstdio>
29 #include <functional>
30 #include <memory>
31 #include <string>
32 #include <tuple>
33 
34 const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr;
35 
36 static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
37 static const int DEFAULT_HTTP_CLIENT_TIMEOUT = 900;
38 static const bool DEFAULT_NAMED = false;
39 static const int CONTINUE_EXECUTION = -1;
41 static const std::string DEFAULT_NBLOCKS = "1";
42 
43 static void SetupCliArgs(ArgsManager &argsman) {
44  SetupHelpOptions(argsman);
45 
46  const auto defaultBaseParams =
48  const auto testnetBaseParams =
50  const auto regtestBaseParams =
52 
53  SetupCurrencyUnitOptions(argsman);
54  argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY,
56  argsman.AddArg(
57  "-conf=<file>",
58  strprintf("Specify configuration file. Relative paths will be "
59  "prefixed by datadir location. (default: %s)",
62  argsman.AddArg("-datadir=<dir>", "Specify data directory",
64  argsman.AddArg(
65  "-generate",
66  strprintf(
67  "Generate blocks immediately, equivalent to RPC generatenewaddress "
68  "followed by RPC generatetoaddress. Optional positional integer "
69  "arguments are number of blocks to generate (default: %s) and "
70  "maximum iterations to try (default: %s), equivalent to RPC "
71  "generatetoaddress nblocks and maxtries arguments. Example: "
72  "bitcoin-cli -generate 4 1000",
75  argsman.AddArg(
76  "-getinfo",
77  "Get general information from the remote server. Note that unlike "
78  "server-side RPC calls, the results of -getinfo is the result of "
79  "multiple non-atomic requests. Some entries in the result may "
80  "represent results from different states (e.g. wallet balance may be "
81  "as of a different block from the chain state reported)",
83  argsman.AddArg("-netinfo",
84  "Get network peer connection information from the remote "
85  "server. An optional integer argument from 0 to 4 can be "
86  "passed for different peers listings (default: 0).",
88 
90  argsman.AddArg(
91  "-named",
92  strprintf("Pass named instead of positional arguments (default: %s)",
95  argsman.AddArg(
96  "-rpcconnect=<ip>",
97  strprintf("Send commands to node running on <ip> (default: %s)",
100  argsman.AddArg(
101  "-rpccookiefile=<loc>",
102  "Location of the auth cookie. Relative paths will be prefixed "
103  "by a net-specific datadir location. (default: data dir)",
105  argsman.AddArg("-rpcport=<port>",
106  strprintf("Connect to JSON-RPC on <port> (default: %u, "
107  "testnet: %u, regtest: %u)",
108  defaultBaseParams->RPCPort(),
109  testnetBaseParams->RPCPort(),
110  regtestBaseParams->RPCPort()),
113  argsman.AddArg("-rpcwait", "Wait for RPC server to start",
115  argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections",
117  argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections",
119  argsman.AddArg(
120  "-rpcclienttimeout=<n>",
121  strprintf("Timeout in seconds during HTTP requests, or 0 for "
122  "no timeout. (default: %d)",
125 
126  argsman.AddArg("-stdinrpcpass",
127  "Read RPC password from standard input as a single "
128  "line. When combined with -stdin, the first line "
129  "from standard input is used for the RPC password. When "
130  "combined with -stdinwalletpassphrase, -stdinrpcpass "
131  "consumes the first line, and -stdinwalletpassphrase "
132  "consumes the second.",
134  argsman.AddArg("-stdinwalletpassphrase",
135  "Read wallet passphrase from standard input as a single "
136  "line. When combined with -stdin, the first line "
137  "from standard input is used for the wallet passphrase.",
139  argsman.AddArg(
140  "-stdin",
141  "Read extra arguments from standard input, one per line until "
142  "EOF/Ctrl-D (recommended for sensitive information such as "
143  "passphrases). When combined with -stdinrpcpass, the first "
144  "line from standard input is used for the RPC password.",
146  argsman.AddArg(
147  "-rpcwallet=<walletname>",
148  "Send RPC for non-default wallet on RPC server (needs to exactly match "
149  "corresponding -wallet option passed to bitcoind). This changes the "
150  "RPC endpoint used, e.g. http://127.0.0.1:8332/wallet/<walletname>",
152 }
153 
155 static void libevent_log_cb(int severity, const char *msg) {
156 #ifndef EVENT_LOG_ERR
157 // EVENT_LOG_ERR was added in 2.0.19; but before then _EVENT_LOG_ERR existed.
158 #define EVENT_LOG_ERR _EVENT_LOG_ERR
159 #endif
160  // Ignore everything other than errors
161  if (severity >= EVENT_LOG_ERR) {
162  throw std::runtime_error(strprintf("libevent error: %s", msg));
163  }
164 }
165 
167 //
168 // Start
169 //
170 
171 //
172 // Exception thrown on connection error. This error is used to determine when
173 // to wait if -rpcwait is given.
174 //
175 class CConnectionFailed : public std::runtime_error {
176 public:
177  explicit inline CConnectionFailed(const std::string &msg)
178  : std::runtime_error(msg) {}
179 };
180 
181 //
182 // This function returns either one of EXIT_ codes when it's expected to stop
183 // the process or CONTINUE_EXECUTION when it's expected to continue further.
184 //
185 static int AppInitRPC(int argc, char *argv[]) {
186  //
187  // Parameters
188  //
190  std::string error;
191  if (!gArgs.ParseParameters(argc, argv, error)) {
192  tfm::format(std::cerr, "Error parsing command line arguments: %s\n",
193  error);
194  return EXIT_FAILURE;
195  }
196  if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
197  std::string strUsage =
198  PACKAGE_NAME " RPC client version " + FormatFullVersion() + "\n";
199  if (!gArgs.IsArgSet("-version")) {
200  strUsage += "\n"
201  "Usage: bitcoin-cli [options] <command> [params] "
202  "Send command to " PACKAGE_NAME "\n"
203  "or: bitcoin-cli [options] -named <command> "
204  "[name=value]... Send command to " PACKAGE_NAME
205  " (with named arguments)\n"
206  "or: bitcoin-cli [options] help "
207  "List commands\n"
208  "or: bitcoin-cli [options] help <command> Get "
209  "help for a command\n";
210 
211  strUsage += "\n" + gArgs.GetHelpMessage();
212  }
213 
214  tfm::format(std::cout, "%s", strUsage);
215  if (argc < 2) {
216  tfm::format(std::cerr, "Error: too few parameters\n");
217  return EXIT_FAILURE;
218  }
219  return EXIT_SUCCESS;
220  }
221  if (!CheckDataDirOption()) {
222  tfm::format(std::cerr,
223  "Error: Specified data directory \"%s\" does not exist.\n",
224  gArgs.GetArg("-datadir", ""));
225  return EXIT_FAILURE;
226  }
227  if (!gArgs.ReadConfigFiles(error, true)) {
228  tfm::format(std::cerr, "Error reading configuration file: %s\n", error);
229  return EXIT_FAILURE;
230  }
231  // Check for -chain, -testnet or -regtest parameter (BaseParams() calls are
232  // only valid after this clause)
233  try {
235  } catch (const std::exception &e) {
236  tfm::format(std::cerr, "Error: %s\n", e.what());
237  return EXIT_FAILURE;
238  }
239  return CONTINUE_EXECUTION;
240 }
241 
243 struct HTTPReply {
244  HTTPReply() : status(0), error(-1) {}
245 
246  int status;
247  int error;
248  std::string body;
249 };
250 
251 static std::string http_errorstring(int code) {
252  switch (code) {
253 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
254  case EVREQ_HTTP_TIMEOUT:
255  return "timeout reached";
256  case EVREQ_HTTP_EOF:
257  return "EOF reached";
258  case EVREQ_HTTP_INVALID_HEADER:
259  return "error while reading header, or invalid header";
260  case EVREQ_HTTP_BUFFER_ERROR:
261  return "error encountered while reading or writing";
262  case EVREQ_HTTP_REQUEST_CANCEL:
263  return "request was canceled";
264  case EVREQ_HTTP_DATA_TOO_LONG:
265  return "response body is larger than allowed";
266 #endif
267  default:
268  return "unknown";
269  }
270 }
271 
272 static void http_request_done(struct evhttp_request *req, void *ctx) {
273  HTTPReply *reply = static_cast<HTTPReply *>(ctx);
274 
275  if (req == nullptr) {
280  reply->status = 0;
281  return;
282  }
283 
284  reply->status = evhttp_request_get_response_code(req);
285 
286  struct evbuffer *buf = evhttp_request_get_input_buffer(req);
287  if (buf) {
288  size_t size = evbuffer_get_length(buf);
289  const char *data = (const char *)evbuffer_pullup(buf, size);
290  if (data) {
291  reply->body = std::string(data, size);
292  }
293  evbuffer_drain(buf, size);
294  }
295 }
296 
297 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
298 static void http_error_cb(enum evhttp_request_error err, void *ctx) {
299  HTTPReply *reply = static_cast<HTTPReply *>(ctx);
300  reply->error = err;
301 }
302 #endif
303 
309 public:
310  virtual ~BaseRequestHandler() {}
311  virtual UniValue PrepareRequest(const std::string &method,
312  const std::vector<std::string> &args) = 0;
313  virtual UniValue ProcessReply(const UniValue &batch_in) = 0;
314 };
315 
318 public:
319  const int ID_NETWORKINFO = 0;
320  const int ID_BLOCKCHAININFO = 1;
321  const int ID_WALLETINFO = 2;
322  const int ID_BALANCES = 3;
323 
325  UniValue PrepareRequest(const std::string &method,
326  const std::vector<std::string> &args) override {
327  if (!args.empty()) {
328  throw std::runtime_error("-getinfo takes no arguments");
329  }
330  UniValue result(UniValue::VARR);
331  result.push_back(
332  JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
333  result.push_back(JSONRPCRequestObj("getblockchaininfo", NullUniValue,
335  result.push_back(
336  JSONRPCRequestObj("getwalletinfo", NullUniValue, ID_WALLETINFO));
337  result.push_back(
338  JSONRPCRequestObj("getbalances", NullUniValue, ID_BALANCES));
339  return result;
340  }
341 
343  UniValue ProcessReply(const UniValue &batch_in) override {
344  UniValue result(UniValue::VOBJ);
345  const std::vector<UniValue> batch = JSONRPCProcessBatchReply(batch_in);
346  // Errors in getnetworkinfo() and getblockchaininfo() are fatal, pass
347  // them on; getwalletinfo() and getbalances are allowed to fail if there
348  // is no wallet.
349  if (!batch[ID_NETWORKINFO]["error"].isNull()) {
350  return batch[ID_NETWORKINFO];
351  }
352  if (!batch[ID_BLOCKCHAININFO]["error"].isNull()) {
353  return batch[ID_BLOCKCHAININFO];
354  }
355  result.pushKV("version", batch[ID_NETWORKINFO]["result"]["version"]);
356  result.pushKV("blocks", batch[ID_BLOCKCHAININFO]["result"]["blocks"]);
357  result.pushKV("headers", batch[ID_BLOCKCHAININFO]["result"]["headers"]);
358  result.pushKV(
359  "verificationprogress",
360  batch[ID_BLOCKCHAININFO]["result"]["verificationprogress"]);
361  result.pushKV("timeoffset",
362  batch[ID_NETWORKINFO]["result"]["timeoffset"]);
363 
364  UniValue connections(UniValue::VOBJ);
365  connections.pushKV("in",
366  batch[ID_NETWORKINFO]["result"]["connections_in"]);
367  connections.pushKV("out",
368  batch[ID_NETWORKINFO]["result"]["connections_out"]);
369  connections.pushKV("total",
370  batch[ID_NETWORKINFO]["result"]["connections"]);
371  result.pushKV("connections", connections);
372 
373  result.pushKV("proxy",
374  batch[ID_NETWORKINFO]["result"]["networks"][0]["proxy"]);
375  result.pushKV("difficulty",
376  batch[ID_BLOCKCHAININFO]["result"]["difficulty"]);
377  result.pushKV("chain",
378  UniValue(batch[ID_BLOCKCHAININFO]["result"]["chain"]));
379  if (!batch[ID_WALLETINFO]["result"].isNull()) {
380  result.pushKV("keypoolsize",
381  batch[ID_WALLETINFO]["result"]["keypoolsize"]);
382  if (!batch[ID_WALLETINFO]["result"]["unlocked_until"].isNull()) {
383  result.pushKV("unlocked_until",
384  batch[ID_WALLETINFO]["result"]["unlocked_until"]);
385  }
386  result.pushKV("paytxfee",
387  batch[ID_WALLETINFO]["result"]["paytxfee"]);
388  }
389  if (!batch[ID_BALANCES]["result"].isNull()) {
390  result.pushKV("balance",
391  batch[ID_BALANCES]["result"]["mine"]["trusted"]);
392  }
393  result.pushKV("relayfee", batch[ID_NETWORKINFO]["result"]["relayfee"]);
394  result.pushKV("warnings", batch[ID_NETWORKINFO]["result"]["warnings"]);
395  return JSONRPCReplyObj(result, NullUniValue, 1);
396  }
397 };
398 
401 private:
402  static constexpr int8_t UNKNOWN_NETWORK{-1};
403  static constexpr size_t m_networks_size{3};
404  const std::array<std::string, m_networks_size> m_networks{
405  {"ipv4", "ipv6", "onion"}};
407  std::array<std::array<uint16_t, m_networks_size + 2>, 3> m_counts{{{}}};
408  int8_t NetworkStringToId(const std::string &str) const {
409  for (size_t i = 0; i < m_networks_size; ++i) {
410  if (str == m_networks.at(i)) {
411  return i;
412  }
413  }
414  return UNKNOWN_NETWORK;
415  }
417  uint8_t m_details_level{0};
418  bool DetailsRequested() const {
419  return m_details_level > 0 && m_details_level < 5;
420  }
421  bool IsAddressSelected() const {
422  return m_details_level == 2 || m_details_level == 4;
423  }
424  bool IsVersionSelected() const {
425  return m_details_level == 3 || m_details_level == 4;
426  }
427  bool m_is_asmap_on{false};
428  size_t m_max_addr_length{0};
429  size_t m_max_id_length{2};
430  struct Peer {
431  int id;
433  int version;
434  int64_t conn_time;
435  int64_t last_blck;
436  int64_t last_recv;
437  int64_t last_send;
438  int64_t last_trxn;
439  double min_ping;
440  double ping;
441  std::string addr;
442  std::string network;
443  std::string sub_version;
446  bool operator<(const Peer &rhs) const {
447  return std::tie(is_outbound, min_ping) <
448  std::tie(rhs.is_outbound, rhs.min_ping);
449  }
450  };
451  std::vector<Peer> m_peers;
452  std::string ChainToString() const {
454  return " testnet";
455  }
457  return " regtest";
458  }
459  return "";
460  }
462 
463 public:
464  static constexpr int ID_PEERINFO = 0;
465  static constexpr int ID_NETWORKINFO = 1;
466 
467  UniValue PrepareRequest(const std::string &method,
468  const std::vector<std::string> &args) override {
469  if (!args.empty()) {
470  uint8_t n{0};
471  if (ParseUInt8(args.at(0), &n)) {
472  m_details_level = n;
473  }
474  }
475  UniValue result(UniValue::VARR);
476  result.push_back(
477  JSONRPCRequestObj("getpeerinfo", NullUniValue, ID_PEERINFO));
478  result.push_back(
479  JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
480  return result;
481  }
482 
483  UniValue ProcessReply(const UniValue &batch_in) override {
484  const std::vector<UniValue> batch{JSONRPCProcessBatchReply(batch_in)};
485  if (!batch[ID_PEERINFO]["error"].isNull()) {
486  return batch[ID_PEERINFO];
487  }
488  if (!batch[ID_NETWORKINFO]["error"].isNull()) {
489  return batch[ID_NETWORKINFO];
490  }
491 
492  const UniValue &networkinfo{batch[ID_NETWORKINFO]["result"]};
493  if (networkinfo["version"].get_int() < 230000) {
494  throw std::runtime_error("-netinfo requires bitcoind server to be "
495  "running v0.23.0 and up");
496  }
497 
498  // Count peer connection totals, and if DetailsRequested(), store peer
499  // data in a vector of structs.
500  for (const UniValue &peer : batch[ID_PEERINFO]["result"].getValues()) {
501  const std::string network{peer["network"].get_str()};
502  const int8_t network_id{NetworkStringToId(network)};
503  if (network_id == UNKNOWN_NETWORK) {
504  continue;
505  }
506  const bool is_outbound{!peer["inbound"].get_bool()};
507  const bool is_block_relay{!peer["relaytxes"].get_bool()};
508  // in/out by network
509  ++m_counts.at(is_outbound).at(network_id);
510  // in/out overall
511  ++m_counts.at(is_outbound).at(m_networks_size);
512  // total by network
513  ++m_counts.at(2).at(network_id);
514  // total overall
515  ++m_counts.at(2).at(m_networks_size);
516  if (is_block_relay) {
517  // in/out block-relay
518  ++m_counts.at(is_outbound).at(m_networks_size + 1);
519  // total block-relay
520  ++m_counts.at(2).at(m_networks_size + 1);
521  }
522  if (DetailsRequested()) {
523  // Push data for this peer to the peers vector.
524  const int peer_id{peer["id"].get_int()};
525  const int mapped_as{peer["mapped_as"].isNull()
526  ? 0
527  : peer["mapped_as"].get_int()};
528  const int version{peer["version"].get_int()};
529  const int64_t conn_time{peer["conntime"].get_int64()};
530  const int64_t last_blck{peer["last_block"].get_int64()};
531  const int64_t last_recv{peer["lastrecv"].get_int64()};
532  const int64_t last_send{peer["lastsend"].get_int64()};
533  const int64_t last_trxn{peer["last_transaction"].get_int64()};
534  const double min_ping{
535  peer["minping"].isNull() ? -1 : peer["minping"].get_real()};
536  const double ping{peer["pingtime"].isNull()
537  ? -1
538  : peer["pingtime"].get_real()};
539  const std::string addr{peer["addr"].get_str()};
540  const std::string sub_version{peer["subver"].get_str()};
541  m_peers.push_back({peer_id, mapped_as, version, conn_time,
542  last_blck, last_recv, last_send, last_trxn,
543  min_ping, ping, addr, network, sub_version,
544  is_block_relay, is_outbound});
546  std::max(ToString(peer_id).length(), m_max_id_length);
548  std::max(addr.length() + 1, m_max_addr_length);
549  m_is_asmap_on |= (mapped_as != 0);
550  }
551  }
552 
553  // Generate report header.
554  std::string result{strprintf("%s %s%s - %i%s\n\n", PACKAGE_NAME,
556  networkinfo["protocolversion"].get_int(),
557  networkinfo["subversion"].get_str())};
558 
559  // Report detailed peer connections list sorted by direction and minimum
560  // ping time.
561  if (DetailsRequested() && !m_peers.empty()) {
562  std::sort(m_peers.begin(), m_peers.end());
563  result += "Peer connections sorted by direction and min ping\n<-> "
564  "relay net mping ping send recv txn blk uptime ";
565  if (m_is_asmap_on) {
566  result += " asmap ";
567  }
568  result += strprintf("%*s %-*s%s\n", m_max_id_length, "id",
570  IsAddressSelected() ? "address" : "",
571  IsVersionSelected() ? "version" : "");
572  for (const Peer &peer : m_peers) {
573  std::string version{ToString(peer.version) + peer.sub_version};
574  result += strprintf(
575  "%3s %5s %5s%6s%7s%5s%5s%5s%5s%7s%*i %*s %-*s%s\n",
576  peer.is_outbound ? "out" : "in",
577  peer.is_block_relay ? "block" : "full", peer.network,
578  peer.min_ping == -1 ? ""
579  : ToString(round(1000 * peer.min_ping)),
580  peer.ping == -1 ? "" : ToString(round(1000 * peer.ping)),
581  peer.last_send == 0 ? ""
582  : ToString(m_time_now - peer.last_send),
583  peer.last_recv == 0 ? ""
584  : ToString(m_time_now - peer.last_recv),
585  peer.last_trxn == 0
586  ? ""
587  : ToString((m_time_now - peer.last_trxn) / 60),
588  peer.last_blck == 0
589  ? ""
590  : ToString((m_time_now - peer.last_blck) / 60),
591  peer.conn_time == 0
592  ? ""
593  : ToString((m_time_now - peer.conn_time) / 60),
594  // variable spacing
595  m_is_asmap_on ? 7 : 0,
596  m_is_asmap_on && peer.mapped_as != 0
597  ? ToString(peer.mapped_as)
598  : "",
599  // variable spacing
600  m_max_id_length, peer.id,
601  // variable spacing
603  IsAddressSelected() ? peer.addr : "",
604  IsVersionSelected() && version != "0" ? version : "");
605  }
606  result +=
607  " ms ms sec sec min min min\n\n";
608  }
609 
610  // Report peer connection totals by type.
611  result += " ipv4 ipv6 onion total block-relay\n";
612  const std::array<std::string, 3> rows{{"in", "out", "total"}};
613  for (size_t i = 0; i < m_networks_size; ++i) {
614  result += strprintf("%-5s %5i %5i %5i %5i %5i\n",
615  rows.at(i), m_counts.at(i).at(0),
616  m_counts.at(i).at(1), m_counts.at(i).at(2),
617  m_counts.at(i).at(m_networks_size),
618  m_counts.at(i).at(m_networks_size + 1));
619  }
620 
621  // Report local addresses, ports, and scores.
622  result += "\nLocal addresses";
623  const UniValue &local_addrs{networkinfo["localaddresses"]};
624  if (local_addrs.empty()) {
625  result += ": n/a\n";
626  } else {
627  for (const UniValue &addr : local_addrs.getValues()) {
628  result +=
629  strprintf("\n%-40i port %5i score %6i",
630  addr["address"].get_str(), addr["port"].get_int(),
631  addr["score"].get_int());
632  }
633  }
634 
635  return JSONRPCReplyObj(UniValue{result}, NullUniValue, 1);
636  }
637 };
638 
641 public:
642  UniValue PrepareRequest(const std::string &method,
643  const std::vector<std::string> &args) override {
644  address_str = args.at(1);
645  UniValue params{RPCConvertValues("generatetoaddress", args)};
646  return JSONRPCRequestObj("generatetoaddress", params, 1);
647  }
648 
649  UniValue ProcessReply(const UniValue &reply) override {
650  UniValue result(UniValue::VOBJ);
651  result.pushKV("address", address_str);
652  result.pushKV("blocks", reply.get_obj()["result"]);
653  return JSONRPCReplyObj(result, NullUniValue, 1);
654  }
655 
656 protected:
657  std::string address_str;
658 };
659 
662 public:
663  UniValue PrepareRequest(const std::string &method,
664  const std::vector<std::string> &args) override {
665  UniValue params;
666  if (gArgs.GetBoolArg("-named", DEFAULT_NAMED)) {
667  params = RPCConvertNamedValues(method, args);
668  } else {
669  params = RPCConvertValues(method, args);
670  }
671  return JSONRPCRequestObj(method, params, 1);
672  }
673 
674  UniValue ProcessReply(const UniValue &reply) override {
675  return reply.get_obj();
676  }
677 };
678 
679 static UniValue CallRPC(BaseRequestHandler *rh, const std::string &strMethod,
680  const std::vector<std::string> &args,
681  const std::optional<std::string> &rpcwallet = {}) {
682  std::string host;
683  // In preference order, we choose the following for the port:
684  // 1. -rpcport
685  // 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6)
686  // 3. default port for chain
687  int port = BaseParams().RPCPort();
688  SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host);
689  port = gArgs.GetArg("-rpcport", port);
690 
691  // Obtain event base
692  raii_event_base base = obtain_event_base();
693 
694  // Synchronously look up hostname
695  raii_evhttp_connection evcon =
696  obtain_evhttp_connection_base(base.get(), host, port);
697 
698  // Set connection timeout
699  {
700  const int timeout =
701  gArgs.GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT);
702  if (timeout > 0) {
703  evhttp_connection_set_timeout(evcon.get(), timeout);
704  } else {
705  // Indefinite request timeouts are not possible in libevent-http,
706  // so we set the timeout to a very long time period instead.
707 
708  // Average length of year in Gregorian calendar
709  constexpr int YEAR_IN_SECONDS = 31556952;
710  evhttp_connection_set_timeout(evcon.get(), 5 * YEAR_IN_SECONDS);
711  }
712  }
713 
715  raii_evhttp_request req =
717  if (req == nullptr) {
718  throw std::runtime_error("create http request failed");
719  }
720 #if LIBEVENT_VERSION_NUMBER >= 0x02010300
721  evhttp_request_set_error_cb(req.get(), http_error_cb);
722 #endif
723 
724  // Get credentials
725  std::string strRPCUserColonPass;
726  bool failedToGetAuthCookie = false;
727  if (gArgs.GetArg("-rpcpassword", "") == "") {
728  // Try fall back to cookie-based authentication if no password is
729  // provided
731  failedToGetAuthCookie = true;
732  }
733  } else {
734  strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" +
735  gArgs.GetArg("-rpcpassword", "");
736  }
737 
738  struct evkeyvalq *output_headers =
739  evhttp_request_get_output_headers(req.get());
740  assert(output_headers);
741  evhttp_add_header(output_headers, "Host", host.c_str());
742  evhttp_add_header(output_headers, "Connection", "close");
743  evhttp_add_header(output_headers, "Content-Type", "application/json");
744  evhttp_add_header(
745  output_headers, "Authorization",
746  (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());
747 
748  // Attach request data
749  std::string strRequest = rh->PrepareRequest(strMethod, args).write() + "\n";
750  struct evbuffer *output_buffer =
751  evhttp_request_get_output_buffer(req.get());
752  assert(output_buffer);
753  evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
754 
755  // check if we should use a special wallet endpoint
756  std::string endpoint = "/";
757  if (rpcwallet) {
758  char *encodedURI =
759  evhttp_uriencode(rpcwallet->data(), rpcwallet->size(), false);
760  if (encodedURI) {
761  endpoint = "/wallet/" + std::string(encodedURI);
762  free(encodedURI);
763  } else {
764  throw CConnectionFailed("uri-encode failed");
765  }
766  }
767  int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST,
768  endpoint.c_str());
769  // ownership moved to evcon in above call
770  req.release();
771  if (r != 0) {
772  throw CConnectionFailed("send http request failed");
773  }
774 
775  event_base_dispatch(base.get());
776 
777  if (response.status == 0) {
778  std::string responseErrorMessage;
779  if (response.error != -1) {
780  responseErrorMessage =
781  strprintf(" (error code %d - \"%s\")", response.error,
782  http_errorstring(response.error));
783  }
784  throw CConnectionFailed(
785  strprintf("Could not connect to the server %s:%d%s\n\nMake sure "
786  "the bitcoind server is running and that you are "
787  "connecting to the correct RPC port.",
788  host, port, responseErrorMessage));
789  } else if (response.status == HTTP_UNAUTHORIZED) {
790  if (failedToGetAuthCookie) {
791  throw std::runtime_error(strprintf(
792  "Could not locate RPC credentials. No authentication cookie "
793  "could be found, and RPC password is not set. See "
794  "-rpcpassword and -stdinrpcpass. Configuration file: (%s)",
796  .string()));
797  } else {
798  throw std::runtime_error(
799  "Authorization failed: Incorrect rpcuser or rpcpassword");
800  }
801  } else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST &&
802  response.status != HTTP_NOT_FOUND &&
804  throw std::runtime_error(
805  strprintf("server returned HTTP error %d", response.status));
806  } else if (response.body.empty()) {
807  throw std::runtime_error("no response from server");
808  }
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  }
815  const UniValue reply = rh->ProcessReply(valReply);
816  if (reply.empty()) {
817  throw std::runtime_error(
818  "expected reply to have result, error and id properties");
819  }
820 
821  return reply;
822 }
823 
835 static UniValue
836 ConnectAndCallRPC(BaseRequestHandler *rh, const std::string &strMethod,
837  const std::vector<std::string> &args,
838  const std::optional<std::string> &rpcwallet = {}) {
840  // Execute and handle connection failures with -rpcwait.
841  const bool fWait = gArgs.GetBoolArg("-rpcwait", false);
842  do {
843  try {
844  response = CallRPC(rh, strMethod, args, rpcwallet);
845  if (fWait) {
846  const UniValue &error = find_value(response, "error");
847  if (!error.isNull() &&
848  error["code"].get_int() == RPC_IN_WARMUP) {
849  throw CConnectionFailed("server in warmup");
850  }
851  }
852  break; // Connection succeeded, no need to retry.
853  } catch (const CConnectionFailed &) {
854  if (fWait) {
855  UninterruptibleSleep(std::chrono::milliseconds{1000});
856  } else {
857  throw;
858  }
859  }
860  } while (fWait);
861  return response;
862 }
863 
865 static void ParseResult(const UniValue &result, std::string &strPrint) {
866  if (result.isNull()) {
867  return;
868  }
869  strPrint = result.isStr() ? result.get_str() : result.write(2);
870 }
871 
876 static void ParseError(const UniValue &error, std::string &strPrint,
877  int &nRet) {
878  if (error.isObject()) {
879  const UniValue &err_code = find_value(error, "code");
880  const UniValue &err_msg = find_value(error, "message");
881  if (!err_code.isNull()) {
882  strPrint = "error code: " + err_code.getValStr() + "\n";
883  }
884  if (err_msg.isStr()) {
885  strPrint += ("error message:\n" + err_msg.get_str());
886  }
887  if (err_code.isNum() &&
888  err_code.get_int() == RPC_WALLET_NOT_SPECIFIED) {
889  strPrint += "\nTry adding \"-rpcwallet=<filename>\" option to "
890  "bitcoin-cli command line.";
891  }
892  } else {
893  strPrint = "error: " + error.write();
894  }
895  nRet = abs(error["code"].get_int());
896 }
897 
906 static void GetWalletBalances(UniValue &result) {
908  const UniValue listwallets =
909  ConnectAndCallRPC(&rh, "listwallets", /* args=*/{});
910  if (!find_value(listwallets, "error").isNull()) {
911  return;
912  }
913  const UniValue &wallets = find_value(listwallets, "result");
914  if (wallets.size() <= 1) {
915  return;
916  }
917 
918  UniValue balances(UniValue::VOBJ);
919  for (const UniValue &wallet : wallets.getValues()) {
920  const std::string wallet_name = wallet.get_str();
921  const UniValue getbalances =
922  ConnectAndCallRPC(&rh, "getbalances", /* args=*/{}, wallet_name);
923  const UniValue &balance =
924  find_value(getbalances, "result")["mine"]["trusted"];
925  balances.pushKV(wallet_name, balance);
926  }
927  result.pushKV("balances", balances);
928 }
929 
935  std::optional<std::string> wallet_name{};
936  if (gArgs.IsArgSet("-rpcwallet")) {
937  wallet_name = gArgs.GetArg("-rpcwallet", "");
938  }
940  return ConnectAndCallRPC(&rh, "getnewaddress", /* args=*/{}, wallet_name);
941 }
942 
950 static void SetGenerateToAddressArgs(const std::string &address,
951  std::vector<std::string> &args) {
952  if (args.size() > 2) {
953  throw std::runtime_error(
954  "too many arguments (maximum 2 for nblocks and maxtries)");
955  }
956  if (args.size() == 0) {
957  args.emplace_back(DEFAULT_NBLOCKS);
958  } else if (args.at(0) == "0") {
959  throw std::runtime_error(
960  "the first argument (number of blocks to generate, default: " +
961  DEFAULT_NBLOCKS + ") must be an integer value greater than zero");
962  }
963  args.emplace(args.begin() + 1, address);
964 }
965 
966 static int CommandLineRPC(int argc, char *argv[]) {
967  std::string strPrint;
968  int nRet = 0;
969  try {
970  // Skip switches
971  while (argc > 1 && IsSwitchChar(argv[1][0])) {
972  argc--;
973  argv++;
974  }
975  std::string rpcPass;
976  if (gArgs.GetBoolArg("-stdinrpcpass", false)) {
977  NO_STDIN_ECHO();
978  if (!StdinReady()) {
979  fputs("RPC password> ", stderr);
980  fflush(stderr);
981  }
982  if (!std::getline(std::cin, rpcPass)) {
983  throw std::runtime_error("-stdinrpcpass specified but failed "
984  "to read from standard input");
985  }
986  if (StdinTerminal()) {
987  fputc('\n', stdout);
988  }
989  gArgs.ForceSetArg("-rpcpassword", rpcPass);
990  }
991  std::vector<std::string> args =
992  std::vector<std::string>(&argv[1], &argv[argc]);
993  if (gArgs.GetBoolArg("-stdinwalletpassphrase", false)) {
994  NO_STDIN_ECHO();
995  std::string walletPass;
996  if (args.size() < 1 ||
997  args[0].substr(0, 16) != "walletpassphrase") {
998  throw std::runtime_error(
999  "-stdinwalletpassphrase is only applicable for "
1000  "walletpassphrase(change)");
1001  }
1002  if (!StdinReady()) {
1003  fputs("Wallet passphrase> ", stderr);
1004  fflush(stderr);
1005  }
1006  if (!std::getline(std::cin, walletPass)) {
1007  throw std::runtime_error("-stdinwalletpassphrase specified but "
1008  "failed to read from standard input");
1009  }
1010  if (StdinTerminal()) {
1011  fputc('\n', stdout);
1012  }
1013  args.insert(args.begin() + 1, walletPass);
1014  }
1015  if (gArgs.GetBoolArg("-stdin", false)) {
1016  // Read one arg per line from stdin and append
1017  std::string line;
1018  while (std::getline(std::cin, line)) {
1019  args.push_back(line);
1020  }
1021  if (StdinTerminal()) {
1022  fputc('\n', stdout);
1023  }
1024  }
1025  std::unique_ptr<BaseRequestHandler> rh;
1026  std::string method;
1027  if (gArgs.IsArgSet("-getinfo")) {
1028  rh.reset(new GetinfoRequestHandler());
1029  } else if (gArgs.GetBoolArg("-generate", false)) {
1031  const UniValue &error{find_value(getnewaddress, "error")};
1032  if (error.isNull()) {
1034  find_value(getnewaddress, "result").get_str(), args);
1035  rh.reset(new GenerateToAddressRequestHandler());
1036  } else {
1037  ParseError(error, strPrint, nRet);
1038  }
1039  } else if (gArgs.GetBoolArg("-netinfo", false)) {
1040  rh.reset(new NetinfoRequestHandler());
1041  } else {
1042  rh.reset(new DefaultRequestHandler());
1043  if (args.size() < 1) {
1044  throw std::runtime_error(
1045  "too few parameters (need at least command)");
1046  }
1047  method = args[0];
1048  // Remove trailing method name from arguments vector
1049  args.erase(args.begin());
1050  }
1051 
1052  if (nRet == 0) {
1053  // Perform RPC call
1054  std::optional<std::string> wallet_name{};
1055  if (gArgs.IsArgSet("-rpcwallet")) {
1056  wallet_name = gArgs.GetArg("-rpcwallet", "");
1057  }
1058  const UniValue reply =
1059  ConnectAndCallRPC(rh.get(), method, args, wallet_name);
1060 
1061  // Parse reply
1062  UniValue result = find_value(reply, "result");
1063  const UniValue &error = find_value(reply, "error");
1064  if (error.isNull()) {
1065  if (gArgs.IsArgSet("-getinfo") &&
1066  !gArgs.IsArgSet("-rpcwallet")) {
1067  // fetch multiwallet balances and append to result
1068  GetWalletBalances(result);
1069  }
1070  ParseResult(result, strPrint);
1071  } else {
1072  ParseError(error, strPrint, nRet);
1073  }
1074  }
1075  } catch (const std::exception &e) {
1076  strPrint = std::string("error: ") + e.what();
1077  nRet = EXIT_FAILURE;
1078  } catch (...) {
1079  PrintExceptionContinue(nullptr, "CommandLineRPC()");
1080  throw;
1081  }
1082 
1083  if (strPrint != "") {
1084  tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint);
1085  }
1086  return nRet;
1087 }
1088 
1089 int main(int argc, char *argv[]) {
1090 #ifdef WIN32
1091  util::WinCmdLineArgs winArgs;
1092  std::tie(argc, argv) = winArgs.get();
1093 #endif
1094  SetupEnvironment();
1095  if (!SetupNetworking()) {
1096  tfm::format(std::cerr, "Error: Initializing networking failed\n");
1097  return EXIT_FAILURE;
1098  }
1099  event_set_log_callback(&libevent_log_cb);
1100 
1101  try {
1102  int ret = AppInitRPC(argc, argv);
1103  if (ret != CONTINUE_EXECUTION) {
1104  return ret;
1105  }
1106  } catch (const std::exception &e) {
1107  PrintExceptionContinue(&e, "AppInitRPC()");
1108  return EXIT_FAILURE;
1109  } catch (...) {
1110  PrintExceptionContinue(nullptr, "AppInitRPC()");
1111  return EXIT_FAILURE;
1112  }
1113 
1114  int ret = EXIT_FAILURE;
1115  try {
1116  ret = CommandLineRPC(argc, argv);
1117  } catch (const std::exception &e) {
1118  PrintExceptionContinue(&e, "CommandLineRPC()");
1119  } catch (...) {
1120  PrintExceptionContinue(nullptr, "CommandLineRPC()");
1121  }
1122  return ret;
1123 }
DefaultRequestHandler
Process default single requests.
Definition: bitcoin-cli.cpp:661
GenerateToAddressRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:642
NetinfoRequestHandler::m_peers
std::vector< Peer > m_peers
Definition: bitcoin-cli.cpp:451
NetinfoRequestHandler::m_counts
std::array< std::array< uint16_t, m_networks_size+2 >, 3 > m_counts
Peer counts by (in/out/total, networks/total/block-relay)
Definition: bitcoin-cli.cpp:407
NetinfoRequestHandler::Peer
Definition: bitcoin-cli.cpp:430
HTTPReply
Reply structure for request_done to fill in.
Definition: bitcoin-cli.cpp:243
NetinfoRequestHandler::m_is_asmap_on
bool m_is_asmap_on
Definition: bitcoin-cli.cpp:427
NetinfoRequestHandler
Process netinfo requests.
Definition: bitcoin-cli.cpp:400
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:517
NetinfoRequestHandler::m_max_id_length
size_t m_max_id_length
Definition: bitcoin-cli.cpp:429
GetConfigFile
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:831
ToString
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:69
DEFAULT_NBLOCKS
static const std::string DEFAULT_NBLOCKS
Default number of blocks to generate for RPC generatetoaddress.
Definition: bitcoin-cli.cpp:41
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:27
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:1111
NetinfoRequestHandler::IsVersionSelected
bool IsVersionSelected() const
Definition: bitcoin-cli.cpp:424
NetinfoRequestHandler::Peer::mapped_as
int mapped_as
Definition: bitcoin-cli.cpp:432
NetinfoRequestHandler::m_networks
const std::array< std::string, m_networks_size > m_networks
Definition: bitcoin-cli.cpp:404
NetinfoRequestHandler::m_time_now
const int64_t m_time_now
Definition: bitcoin-cli.cpp:461
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:818
SetupHelpOptions
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:676
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
Definition: system.h:159
GenerateToAddressRequestHandler::address_str
std::string address_str
Definition: bitcoin-cli.cpp:657
NetinfoRequestHandler::m_details_level
uint8_t m_details_level
Optional user-supplied arg to set dashboard details level.
Definition: bitcoin-cli.cpp:417
ArgsManager::GetHelpMessage
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:598
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
NetinfoRequestHandler::Peer::addr
std::string addr
Definition: bitcoin-cli.cpp:441
libevent_log_cb
static void libevent_log_cb(int severity, const char *msg)
libevent event log callback
Definition: bitcoin-cli.cpp:155
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1306
GetinfoRequestHandler
Process getinfo requests.
Definition: bitcoin-cli.cpp:317
AppInitRPC
static int AppInitRPC(int argc, char *argv[])
Definition: bitcoin-cli.cpp:185
NetinfoRequestHandler::ID_PEERINFO
static constexpr int ID_PEERINFO
Definition: bitcoin-cli.cpp:464
chainparamsbase.h
HTTP_BAD_REQUEST
@ HTTP_BAD_REQUEST
Definition: protocol.h:12
SetupChainParamsBaseOptions
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
Definition: chainparamsbase.cpp:17
ArgsManager::GetChainName
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: system.cpp:1033
getnewaddress
static RPCHelpMan getnewaddress()
Definition: rpcwallet.cpp:209
NetinfoRequestHandler::NetworkStringToId
int8_t NetworkStringToId(const std::string &str) const
Definition: bitcoin-cli.cpp:408
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:400
DEFAULT_MAX_TRIES
static const uint64_t DEFAULT_MAX_TRIES
Default max iterations to try in RPC generatetodescriptor, generatetoaddress, and generateblock.
Definition: mining.h:12
HTTPReply::body
std::string body
Definition: bitcoin-cli.cpp:248
CBaseChainParams::TESTNET
static const std::string TESTNET
Definition: chainparamsbase.h:22
SelectBaseParams
void SelectBaseParams(const std::string &chain)
Sets the params returned by Params() to those for the given network.
Definition: chainparamsbase.cpp:63
mining.h
NetinfoRequestHandler::Peer::id
int id
Definition: bitcoin-cli.cpp:431
protocol.h
GenerateToAddressRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:649
GetAuthCookie
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
Definition: request.cpp:111
clientversion.h
SetupNetworking
bool SetupNetworking()
Definition: system.cpp:1344
UniValue::isNull
bool isNull() const
Definition: univalue.h:89
DEFAULT_HTTP_CLIENT_TIMEOUT
static const int DEFAULT_HTTP_CLIENT_TIMEOUT
Definition: bitcoin-cli.cpp:37
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:218
NetinfoRequestHandler::UNKNOWN_NETWORK
static constexpr int8_t UNKNOWN_NETWORK
Definition: bitcoin-cli.cpp:402
UniValue::write
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Definition: univalue_write.cpp:159
SplitHostPort
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
Definition: strencodings.cpp:113
UniValue::isNum
bool isNum() const
Definition: univalue.h:94
CConnectionFailed::CConnectionFailed
CConnectionFailed(const std::string &msg)
Definition: bitcoin-cli.cpp:177
NetinfoRequestHandler::m_max_addr_length
size_t m_max_addr_length
Definition: bitcoin-cli.cpp:428
SetupCurrencyUnitOptions
void SetupCurrencyUnitOptions(ArgsManager &argsman)
Definition: currencyunit.cpp:9
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
NetinfoRequestHandler::Peer::conn_time
int64_t conn_time
Definition: bitcoin-cli.cpp:434
NetinfoRequestHandler::Peer::is_block_relay
bool is_block_relay
Definition: bitcoin-cli.cpp:444
http_errorstring
static std::string http_errorstring(int code)
Definition: bitcoin-cli.cpp:251
UniValue
Definition: univalue.h:23
balance
static Amount balance
Definition: coinselector_tests.cpp:37
ArgsManager::ALLOW_INT
@ ALLOW_INT
Definition: system.h:157
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:98
NetinfoRequestHandler::IsAddressSelected
bool IsAddressSelected() const
Definition: bitcoin-cli.cpp:421
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:671
strencodings.h
UniValue::isStr
bool isStr() const
Definition: univalue.h:93
DefaultRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:663
DEFAULT_RPCCONNECT
static const char DEFAULT_RPCCONNECT[]
Definition: bitcoin-cli.cpp:36
events.h
NetinfoRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &batch_in) override
Definition: bitcoin-cli.cpp:483
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue_get.cpp:135
NetinfoRequestHandler::Peer::ping
double ping
Definition: bitcoin-cli.cpp:440
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:679
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:876
response
Response response
Definition: processor.cpp:321
NetinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Definition: bitcoin-cli.cpp:467
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:565
GetSystemTimeInSeconds
int64_t GetSystemTimeInSeconds()
Returns the system time (not mockable)
Definition: time.cpp:75
univalue.h
CBaseChainParams::REGTEST
static const std::string REGTEST
Definition: chainparamsbase.h:23
RPCConvertNamedValues
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert named arguments to command-specific RPC representation.
Definition: client.cpp:237
IsSwitchChar
bool IsSwitchChar(char c)
Definition: system.h:116
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:542
obtain_evhttp_request
raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg)
Definition: events.h:46
obtain_evhttp_connection_base
raii_evhttp_connection obtain_evhttp_connection_base(struct event_base *base, std::string host, uint16_t port)
Definition: events.h:51
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
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:46
RPC_IN_WARMUP
@ RPC_IN_WARMUP
Client still warming up.
Definition: protocol.h:58
HTTP_UNAUTHORIZED
@ HTTP_UNAUTHORIZED
Definition: protocol.h:13
NetinfoRequestHandler::Peer::last_blck
int64_t last_blck
Definition: bitcoin-cli.cpp:435
main
int main(int argc, char *argv[])
Definition: bitcoin-cli.cpp:1089
ArgsManager::ParseParameters
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:317
BaseRequestHandler::~BaseRequestHandler
virtual ~BaseRequestHandler()
Definition: bitcoin-cli.cpp:310
BaseRequestHandler::ProcessReply
virtual UniValue ProcessReply(const UniValue &batch_in)=0
CBaseChainParams::RPCPort
uint16_t RPCPort() const
Definition: chainparamsbase.h:26
HTTPReply::HTTPReply
HTTPReply()
Definition: bitcoin-cli.cpp:244
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:343
ArgsManager::ReadConfigFiles
NODISCARD bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:930
request.h
SetupCliArgs
static void SetupCliArgs(ArgsManager &argsman)
Definition: bitcoin-cli.cpp:43
CONTINUE_EXECUTION
static const int CONTINUE_EXECUTION
Definition: bitcoin-cli.cpp:39
GetWalletBalances
static void GetWalletBalances(UniValue &result)
GetWalletBalances calls listwallets; if more than one wallet is loaded, it then fetches mine....
Definition: bitcoin-cli.cpp:906
CBaseChainParams::MAIN
static const std::string MAIN
BIP70 chain name strings (main, test or regtest)
Definition: chainparamsbase.h:21
ping
static RPCHelpMan ping()
Definition: net.cpp:57
stdin.h
ctx
secp256k1_context * ctx
Definition: bench_multiset.c:12
RPC_WALLET_NOT_SPECIFIED
@ RPC_WALLET_NOT_SPECIFIED
No wallet specified (error when there are multiple wallets loaded)
Definition: protocol.h:109
UninterruptibleSleep
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:20
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:1201
listwallets
static RPCHelpMan listwallets()
Definition: rpcwallet.cpp:3177
NetinfoRequestHandler::Peer::network
std::string network
Definition: bitcoin-cli.cpp:442
UniValue::getValStr
const std::string & getValStr() const
Definition: univalue.h:77
GetinfoRequestHandler::PrepareRequest
UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args) override
Create a simulated getinfo request.
Definition: bitcoin-cli.cpp:325
GetinfoRequestHandler::ID_WALLETINFO
const int ID_WALLETINFO
Definition: bitcoin-cli.cpp:321
JSONRPCProcessBatchReply
std::vector< UniValue > JSONRPCProcessBatchReply(const UniValue &in)
Parse JSON-RPC batch reply into a vector.
Definition: request.cpp:137
NetinfoRequestHandler::ID_NETWORKINFO
static constexpr int ID_NETWORKINFO
Definition: bitcoin-cli.cpp:465
obtain_event_base
raii_event_base obtain_event_base()
Definition: events.h:28
getbalances
static RPCHelpMan getbalances()
Definition: rpcwallet.cpp:2907
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:105
NetinfoRequestHandler::m_networks_size
static constexpr size_t m_networks_size
Definition: bitcoin-cli.cpp:403
ArgsManager
Definition: system.h:152
currencyunit.h
translation.h
BaseParams
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
Definition: chainparamsbase.cpp:36
G_TRANSLATION_FUN
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
Definition: bitcoin-cli.cpp:34
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:865
strRPCUserColonPass
static std::string strRPCUserColonPass
Definition: httprpc.cpp:68
gArgs
ArgsManager gArgs
Definition: system.cpp:75
NetinfoRequestHandler::Peer::last_recv
int64_t last_recv
Definition: bitcoin-cli.cpp:436
NetinfoRequestHandler::Peer::last_send
int64_t last_send
Definition: bitcoin-cli.cpp:437
HTTP_NOT_FOUND
@ HTTP_NOT_FOUND
Definition: protocol.h:15
DEFAULT_NAMED
static const bool DEFAULT_NAMED
Definition: bitcoin-cli.cpp:38
BaseRequestHandler
Class that handles the conversion from a command-line to a JSON-RPC request, as well as converting ba...
Definition: bitcoin-cli.cpp:308
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
HTTPReply::error
int error
Definition: bitcoin-cli.cpp:247
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:836
NetinfoRequestHandler::Peer::sub_version
std::string sub_version
Definition: bitcoin-cli.cpp:443
UniValue::empty
bool empty() const
Definition: univalue.h:78
BITCOIN_CONF_FILENAME
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:72
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue_get.cpp:84
UniValue::size
size_t size() const
Definition: univalue.h:80
GetinfoRequestHandler::ID_NETWORKINFO
const int ID_NETWORKINFO
Definition: bitcoin-cli.cpp:319
GenerateToAddressRequestHandler
Process RPC generatetoaddress request.
Definition: bitcoin-cli.cpp:640
EncodeBase64
std::string EncodeBase64(Span< const uint8_t > input)
Definition: strencodings.cpp:137
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:446
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:58
NetinfoRequestHandler::Peer::is_outbound
bool is_outbound
Definition: bitcoin-cli.cpp:445
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
ArgsManager::NETWORK_ONLY
@ NETWORK_ONLY
Definition: system.h:166
UniValue::VARR
@ VARR
Definition: univalue.h:27
GetNewAddress
static UniValue GetNewAddress()
Call RPC getnewaddress.
Definition: bitcoin-cli.cpp:934
NetinfoRequestHandler::Peer::min_ping
double min_ping
Definition: bitcoin-cli.cpp:439
NetinfoRequestHandler::Peer::last_trxn
int64_t last_trxn
Definition: bitcoin-cli.cpp:438
NetinfoRequestHandler::ChainToString
std::string ChainToString() const
Definition: bitcoin-cli.cpp:452
NetinfoRequestHandler::DetailsRequested
bool DetailsRequested() const
Definition: bitcoin-cli.cpp:418
GetinfoRequestHandler::ID_BALANCES
const int ID_BALANCES
Definition: bitcoin-cli.cpp:322
UniValue::VSTR
@ VSTR
Definition: univalue.h:27
DefaultRequestHandler::ProcessReply
UniValue ProcessReply(const UniValue &reply) override
Definition: bitcoin-cli.cpp:674
http_request_done
static void http_request_done(struct evhttp_request *req, void *ctx)
Definition: bitcoin-cli.cpp:272
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:353
NetinfoRequestHandler::Peer::version
int version
Definition: bitcoin-cli.cpp:433
GetinfoRequestHandler::ID_BLOCKCHAININFO
const int ID_BLOCKCHAININFO
Definition: bitcoin-cli.cpp:320
CConnectionFailed
Definition: bitcoin-cli.cpp:175
client.h
StdinTerminal
bool StdinTerminal()
Definition: stdin.cpp:46
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:716
HTTPReply::status
int status
Definition: bitcoin-cli.cpp:246
BaseRequestHandler::PrepareRequest
virtual UniValue PrepareRequest(const std::string &method, const std::vector< std::string > &args)=0
StdinReady
bool StdinReady()
Definition: stdin.cpp:54
HTTP_INTERNAL_SERVER_ERROR
@ HTTP_INTERNAL_SERVER_ERROR
Definition: protocol.h:17
CommandLineRPC
static int CommandLineRPC(int argc, char *argv[])
Definition: bitcoin-cli.cpp:966
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:950