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