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