Bitcoin ABC  0.26.3
P2P Digital Currency
misc.cpp
Go to the documentation of this file.
1 // Copyright (c) 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 #include <chainparams.h>
7 #include <config.h>
8 #include <consensus/amount.h>
9 #include <httpserver.h>
10 #include <index/blockfilterindex.h>
11 #include <index/coinstatsindex.h>
12 #include <index/txindex.h>
13 #include <interfaces/chain.h>
14 #include <key_io.h>
15 #include <logging.h>
16 #include <node/context.h>
17 #include <outputtype.h>
18 #include <rpc/blockchain.h>
19 #include <rpc/server.h>
20 #include <rpc/server_util.h>
21 #include <rpc/util.h>
22 #include <scheduler.h>
23 #include <script/descriptor.h>
24 #include <timedata.h>
25 #include <util/check.h>
26 #include <util/message.h> // For MessageSign(), MessageVerify()
27 #include <util/strencodings.h>
28 #include <util/system.h>
29 #include <util/time.h>
30 
31 #include <univalue.h>
32 
33 #include <cstdint>
34 #include <tuple>
35 #ifdef HAVE_MALLOC_INFO
36 #include <malloc.h>
37 #endif
38 
39 using node::NodeContext;
40 
42  return RPCHelpMan{
43  "validateaddress",
44  "Return information about the given bitcoin address.\n",
45  {
47  "The bitcoin address to validate"},
48  },
49  RPCResult{
51  "",
52  "",
53  {
54  {RPCResult::Type::BOOL, "isvalid",
55  "If the address is valid or not. If not, this is the only "
56  "property returned."},
57  {RPCResult::Type::STR, "address",
58  "The bitcoin address validated"},
59  {RPCResult::Type::STR_HEX, "scriptPubKey",
60  "The hex-encoded scriptPubKey generated by the address"},
61  {RPCResult::Type::BOOL, "isscript", "If the key is a script"},
62  }},
63  RPCExamples{HelpExampleCli("validateaddress", EXAMPLE_ADDRESS) +
64  HelpExampleRpc("validateaddress", EXAMPLE_ADDRESS)},
65  [&](const RPCHelpMan &self, const Config &config,
66  const JSONRPCRequest &request) -> UniValue {
67  CTxDestination dest = DecodeDestination(request.params[0].get_str(),
68  config.GetChainParams());
69  bool isValid = IsValidDestination(dest);
70 
72  ret.pushKV("isvalid", isValid);
73 
74  if (isValid) {
75  if (ret["address"].isNull()) {
76  std::string currentAddress =
77  EncodeDestination(dest, config);
78  ret.pushKV("address", currentAddress);
79 
80  CScript scriptPubKey = GetScriptForDestination(dest);
81  ret.pushKV("scriptPubKey", HexStr(scriptPubKey));
82 
83  UniValue detail = DescribeAddress(dest);
84  ret.pushKVs(detail);
85  }
86  }
87  return ret;
88  },
89  };
90 }
91 
93  return RPCHelpMan{
94  "createmultisig",
95  "Creates a multi-signature address with n signature of m keys "
96  "required.\n"
97  "It returns a json object with the address and redeemScript.\n",
98  {
100  "The number of required signatures out of the n keys."},
101  {"keys",
104  "The hex-encoded public keys.",
105  {
107  "The hex-encoded public key"},
108  }},
109  },
110  RPCResult{
112  "",
113  "",
114  {
115  {RPCResult::Type::STR, "address",
116  "The value of the new multisig address."},
117  {RPCResult::Type::STR_HEX, "redeemScript",
118  "The string value of the hex-encoded redemption script."},
119  {RPCResult::Type::STR, "descriptor",
120  "The descriptor for this multisig"},
121  }},
122  RPCExamples{
123  "\nCreate a multisig address from 2 public keys\n" +
124  HelpExampleCli("createmultisig",
125  "2 "
126  "\"["
127  "\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd3"
128  "42cf11ae157a7ace5fd\\\","
129  "\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e1"
130  "7e107ef3f6aa5a61626\\\"]\"") +
131  "\nAs a JSON-RPC call\n" +
132  HelpExampleRpc("createmultisig",
133  "2, "
134  "\"["
135  "\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd3"
136  "42cf11ae157a7ace5fd\\\","
137  "\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e1"
138  "7e107ef3f6aa5a61626\\\"]\"")},
139  [&](const RPCHelpMan &self, const Config &config,
140  const JSONRPCRequest &request) -> UniValue {
141  int required = request.params[0].get_int();
142 
143  // Get the public keys
144  const UniValue &keys = request.params[1].get_array();
145  std::vector<CPubKey> pubkeys;
146  for (size_t i = 0; i < keys.size(); ++i) {
147  if ((keys[i].get_str().length() ==
149  keys[i].get_str().length() == 2 * CPubKey::SIZE) &&
150  IsHex(keys[i].get_str())) {
151  pubkeys.push_back(HexToPubKey(keys[i].get_str()));
152  } else {
154  strprintf("Invalid public key: %s\n",
155  keys[i].get_str()));
156  }
157  }
158 
159  // Get the output type
160  OutputType output_type = OutputType::LEGACY;
161 
162  // Construct using pay-to-script-hash:
163  FillableSigningProvider keystore;
164  CScript inner;
166  required, pubkeys, output_type, keystore, inner);
167 
168  // Make the descriptor
169  std::unique_ptr<Descriptor> descriptor =
170  InferDescriptor(GetScriptForDestination(dest), keystore);
171 
172  UniValue result(UniValue::VOBJ);
173  result.pushKV("address", EncodeDestination(dest, config));
174  result.pushKV("redeemScript", HexStr(inner));
175  result.pushKV("descriptor", descriptor->ToString());
176 
177  return result;
178  },
179  };
180 }
181 
183  return RPCHelpMan{
184  "getdescriptorinfo",
185  {"Analyses a descriptor.\n"},
186  {
187  {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO,
188  "The descriptor."},
189  },
190  RPCResult{
192  "",
193  "",
194  {
195  {RPCResult::Type::STR, "descriptor",
196  "The descriptor in canonical form, without private keys"},
197  {RPCResult::Type::STR, "checksum",
198  "The checksum for the input descriptor"},
199  {RPCResult::Type::BOOL, "isrange",
200  "Whether the descriptor is ranged"},
201  {RPCResult::Type::BOOL, "issolvable",
202  "Whether the descriptor is solvable"},
203  {RPCResult::Type::BOOL, "hasprivatekeys",
204  "Whether the input descriptor contained at least one private "
205  "key"},
206  }},
207  RPCExamples{"Analyse a descriptor\n" +
208  HelpExampleCli("getdescriptorinfo",
209  "\"pkh([d34db33f/84h/0h/"
210  "0h]"
211  "0279be667ef9dcbbac55a06295Ce870b07029Bfcdb2"
212  "dce28d959f2815b16f81798)\"")},
213  [&](const RPCHelpMan &self, const Config &config,
214  const JSONRPCRequest &request) -> UniValue {
215  RPCTypeCheck(request.params, {UniValue::VSTR});
216 
217  FlatSigningProvider provider;
218  std::string error;
219  auto desc = Parse(request.params[0].get_str(), provider, error);
220  if (!desc) {
222  }
223 
224  UniValue result(UniValue::VOBJ);
225  result.pushKV("descriptor", desc->ToString());
226  result.pushKV("checksum",
227  GetDescriptorChecksum(request.params[0].get_str()));
228  result.pushKV("isrange", desc->IsRange());
229  result.pushKV("issolvable", desc->IsSolvable());
230  result.pushKV("hasprivatekeys", provider.keys.size() > 0);
231  return result;
232  },
233  };
234 }
235 
237  return RPCHelpMan{
238  "deriveaddresses",
239  {"Derives one or more addresses corresponding to an output "
240  "descriptor.\n"
241  "Examples of output descriptors are:\n"
242  " pkh(<pubkey>) P2PKH outputs for the given "
243  "pubkey\n"
244  " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for "
245  "the given threshold and pubkeys\n"
246  " raw(<hex script>) Outputs whose scriptPubKey "
247  "equals the specified hex scripts\n"
248  "\nIn the above, <pubkey> either refers to a fixed public key in "
249  "hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
250  "or more path elements separated by \"/\", where \"h\" represents a "
251  "hardened child key.\n"
252  "For more information on output descriptors, see the documentation in "
253  "the doc/descriptors.md file.\n"},
254  {
255  {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO,
256  "The descriptor."},
258  "If a ranged descriptor is used, this specifies the end or the "
259  "range (in [begin,end] notation) to derive."},
260  },
261  RPCResult{
263  "",
264  "",
265  {
266  {RPCResult::Type::STR, "address", "the derived addresses"},
267  }},
268  RPCExamples{"First three pkh receive addresses\n" +
270  "deriveaddresses",
271  "\"pkh([d34db33f/84h/0h/0h]"
272  "xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8P"
273  "hqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKE"
274  "u3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#3vhfv5h5\" \"[0,2]\"")},
275  [&](const RPCHelpMan &self, const Config &config,
276  const JSONRPCRequest &request) -> UniValue {
277  // Range argument is checked later
278  RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()});
279  const std::string desc_str = request.params[0].get_str();
280 
281  int64_t range_begin = 0;
282  int64_t range_end = 0;
283 
284  if (request.params.size() >= 2 && !request.params[1].isNull()) {
285  std::tie(range_begin, range_end) =
286  ParseDescriptorRange(request.params[1]);
287  }
288 
289  FlatSigningProvider key_provider;
290  std::string error;
291  auto desc = Parse(desc_str, key_provider, error,
292  /* require_checksum = */ true);
293  if (!desc) {
295  }
296 
297  if (!desc->IsRange() && request.params.size() > 1) {
299  "Range should not be specified for an "
300  "un-ranged descriptor");
301  }
302 
303  if (desc->IsRange() && request.params.size() == 1) {
304  throw JSONRPCError(
306  "Range must be specified for a ranged descriptor");
307  }
308 
309  UniValue addresses(UniValue::VARR);
310 
311  for (int i = range_begin; i <= range_end; ++i) {
312  FlatSigningProvider provider;
313  std::vector<CScript> scripts;
314  if (!desc->Expand(i, key_provider, scripts, provider)) {
315  throw JSONRPCError(
317  strprintf("Cannot derive script without private keys"));
318  }
319 
320  for (const CScript &script : scripts) {
321  CTxDestination dest;
322  if (!ExtractDestination(script, dest)) {
323  throw JSONRPCError(
325  strprintf("Descriptor does not have a "
326  "corresponding address"));
327  }
328 
329  addresses.push_back(EncodeDestination(dest, config));
330  }
331  }
332 
333  // This should not be possible, but an assert seems overkill:
334  if (addresses.empty()) {
335  throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result");
336  }
337 
338  return addresses;
339  },
340  };
341 }
342 
344  return RPCHelpMan{
345  "verifymessage",
346  "Verify a signed message\n",
347  {
349  "The bitcoin address to use for the signature."},
351  "The signature provided by the signer in base 64 encoding (see "
352  "signmessage)."},
354  "The message that was signed."},
355  },
357  "If the signature is verified or not."},
358  RPCExamples{
359  "\nUnlock the wallet for 30 seconds\n" +
360  HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
361  "\nCreate the signature\n" +
363  "signmessage",
364  "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
365  "\nVerify the signature\n" +
366  HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4"
367  "XX\" \"signature\" \"my "
368  "message\"") +
369  "\nAs a JSON-RPC call\n" +
370  HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4"
371  "XX\", \"signature\", \"my "
372  "message\"")},
373  [&](const RPCHelpMan &self, const Config &config,
374  const JSONRPCRequest &request) -> UniValue {
375  LOCK(cs_main);
376 
377  std::string strAddress = request.params[0].get_str();
378  std::string strSign = request.params[1].get_str();
379  std::string strMessage = request.params[2].get_str();
380 
381  switch (MessageVerify(config.GetChainParams(), strAddress, strSign,
382  strMessage)) {
384  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
387  "Address does not refer to key");
390  "Malformed base64 encoding");
393  return false;
395  return true;
396  }
397 
398  return false;
399  },
400  };
401 }
402 
404  return RPCHelpMan{
405  "signmessagewithprivkey",
406  "Sign a message with the private key of an address\n",
407  {
409  "The private key to sign the message with."},
411  "The message to create a signature of."},
412  },
413  RPCResult{RPCResult::Type::STR, "signature",
414  "The signature of the message encoded in base 64"},
415  RPCExamples{"\nCreate the signature\n" +
416  HelpExampleCli("signmessagewithprivkey",
417  "\"privkey\" \"my message\"") +
418  "\nVerify the signature\n" +
419  HelpExampleCli("verifymessage",
420  "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" "
421  "\"signature\" \"my message\"") +
422  "\nAs a JSON-RPC call\n" +
423  HelpExampleRpc("signmessagewithprivkey",
424  "\"privkey\", \"my message\"")},
425  [&](const RPCHelpMan &self, const Config &config,
426  const JSONRPCRequest &request) -> UniValue {
427  std::string strPrivkey = request.params[0].get_str();
428  std::string strMessage = request.params[1].get_str();
429 
430  CKey key = DecodeSecret(strPrivkey);
431  if (!key.IsValid()) {
433  "Invalid private key");
434  }
435 
436  std::string signature;
437 
438  if (!MessageSign(key, strMessage, signature)) {
439  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
440  }
441 
442  return signature;
443  },
444  };
445 }
446 
448  return RPCHelpMan{
449  "setmocktime",
450  "Set the local time to given timestamp (-regtest only)\n",
451  {
453  UNIX_EPOCH_TIME + "\n"
454  "Pass 0 to go back to using the system time."},
455  },
457  RPCExamples{""},
458  [&](const RPCHelpMan &self, const Config &config,
459  const JSONRPCRequest &request) -> UniValue {
460  if (!config.GetChainParams().IsMockableChain()) {
461  throw std::runtime_error(
462  "setmocktime for regression testing (-regtest mode) only");
463  }
464 
465  // For now, don't change mocktime if we're in the middle of
466  // validation, as this could have an effect on mempool time-based
467  // eviction, as well as IsInitialBlockDownload().
468  // TODO: figure out the right way to synchronize around mocktime,
469  // and ensure all call sites of GetTime() are accessing this safely.
470  LOCK(cs_main);
471 
472  RPCTypeCheck(request.params, {UniValue::VNUM});
473  const int64_t time{request.params[0].get_int64()};
474  if (time < 0) {
475  throw JSONRPCError(
477  strprintf("Mocktime can not be negative: %s.", time));
478  }
479  SetMockTime(time);
480  auto node_context = util::AnyPtr<NodeContext>(request.context);
481  if (node_context) {
482  for (const auto &chain_client : node_context->chain_clients) {
483  chain_client->setMockTime(time);
484  }
485  }
486 
487  return NullUniValue;
488  },
489  };
490 }
491 
493  return RPCHelpMan{
494  "mockscheduler",
495  "Bump the scheduler into the future (-regtest only)\n",
496  {
497  {"delta_time", RPCArg::Type::NUM, RPCArg::Optional::NO,
498  "Number of seconds to forward the scheduler into the future."},
499  },
501  RPCExamples{""},
502  [&](const RPCHelpMan &self, const Config &config,
503  const JSONRPCRequest &request) -> UniValue {
504  if (!Params().IsMockableChain()) {
505  throw std::runtime_error("mockscheduler is for regression "
506  "testing (-regtest mode) only");
507  }
508 
509  // check params are valid values
510  RPCTypeCheck(request.params, {UniValue::VNUM});
511  int64_t delta_seconds = request.params[0].get_int64();
512  if ((delta_seconds <= 0) || (delta_seconds > 3600)) {
513  throw std::runtime_error(
514  "delta_time must be between 1 and 3600 seconds (1 hr)");
515  }
516 
517  auto node_context =
518  CHECK_NONFATAL(util::AnyPtr<NodeContext>(request.context));
519  // protect against null pointer dereference
520  CHECK_NONFATAL(node_context->scheduler);
521  node_context->scheduler->MockForward(
522  std::chrono::seconds(delta_seconds));
523 
524  return NullUniValue;
525  },
526  };
527 }
528 
532  obj.pushKV("used", uint64_t(stats.used));
533  obj.pushKV("free", uint64_t(stats.free));
534  obj.pushKV("total", uint64_t(stats.total));
535  obj.pushKV("locked", uint64_t(stats.locked));
536  obj.pushKV("chunks_used", uint64_t(stats.chunks_used));
537  obj.pushKV("chunks_free", uint64_t(stats.chunks_free));
538  return obj;
539 }
540 
541 #ifdef HAVE_MALLOC_INFO
542 static std::string RPCMallocInfo() {
543  char *ptr = nullptr;
544  size_t size = 0;
545  FILE *f = open_memstream(&ptr, &size);
546  if (f) {
547  malloc_info(0, f);
548  fclose(f);
549  if (ptr) {
550  std::string rv(ptr, size);
551  free(ptr);
552  return rv;
553  }
554  }
555  return "";
556 }
557 #endif
558 
560  /* Please, avoid using the word "pool" here in the RPC interface or help,
561  * as users will undoubtedly confuse it with the other "memory pool"
562  */
563  return RPCHelpMan{
564  "getmemoryinfo",
565  "Returns an object containing information about memory usage.\n",
566  {
567  {"mode", RPCArg::Type::STR, RPCArg::Default{"stats"},
568  "determines what kind of information is returned.\n"
569  " - \"stats\" returns general statistics about memory usage in "
570  "the daemon.\n"
571  " - \"mallocinfo\" returns an XML string describing low-level "
572  "heap state (only available if compiled with glibc 2.10+)."},
573  },
574  {
575  RPCResult{
576  "mode \"stats\"",
578  "",
579  "",
580  {
582  "locked",
583  "Information about locked memory manager",
584  {
585  {RPCResult::Type::NUM, "used", "Number of bytes used"},
586  {RPCResult::Type::NUM, "free",
587  "Number of bytes available in current arenas"},
588  {RPCResult::Type::NUM, "total",
589  "Total number of bytes managed"},
590  {RPCResult::Type::NUM, "locked",
591  "Amount of bytes that succeeded locking. If this "
592  "number is smaller than total, locking pages failed "
593  "at some point and key data could be swapped to "
594  "disk."},
595  {RPCResult::Type::NUM, "chunks_used",
596  "Number allocated chunks"},
597  {RPCResult::Type::NUM, "chunks_free",
598  "Number unused chunks"},
599  }},
600  }},
601  RPCResult{"mode \"mallocinfo\"", RPCResult::Type::STR, "",
602  "\"<malloc version=\"1\">...\""},
603  },
604  RPCExamples{HelpExampleCli("getmemoryinfo", "") +
605  HelpExampleRpc("getmemoryinfo", "")},
606  [&](const RPCHelpMan &self, const Config &config,
607  const JSONRPCRequest &request) -> UniValue {
608  std::string mode = request.params[0].isNull()
609  ? "stats"
610  : request.params[0].get_str();
611  if (mode == "stats") {
613  obj.pushKV("locked", RPCLockedMemoryInfo());
614  return obj;
615  } else if (mode == "mallocinfo") {
616 #ifdef HAVE_MALLOC_INFO
617  return RPCMallocInfo();
618 #else
620  "mallocinfo is only available when compiled "
621  "with glibc 2.10+");
622 #endif
623  } else {
625  "unknown mode " + mode);
626  }
627  },
628  };
629 }
630 
631 static void EnableOrDisableLogCategories(UniValue cats, bool enable) {
632  cats = cats.get_array();
633  for (size_t i = 0; i < cats.size(); ++i) {
634  std::string cat = cats[i].get_str();
635 
636  bool success;
637  if (enable) {
638  success = LogInstance().EnableCategory(cat);
639  } else {
640  success = LogInstance().DisableCategory(cat);
641  }
642 
643  if (!success) {
645  "unknown logging category " + cat);
646  }
647  }
648 }
649 
650 static RPCHelpMan logging() {
651  return RPCHelpMan{
652  "logging",
653  "Gets and sets the logging configuration.\n"
654  "When called without an argument, returns the list of categories with "
655  "status that are currently being debug logged or not.\n"
656  "When called with arguments, adds or removes categories from debug "
657  "logging and return the lists above.\n"
658  "The arguments are evaluated in order \"include\", \"exclude\".\n"
659  "If an item is both included and excluded, it will thus end up being "
660  "excluded.\n"
661  "The valid logging categories are: " +
663  "\n"
664  "In addition, the following are available as category names with "
665  "special meanings:\n"
666  " - \"all\", \"1\" : represent all logging categories.\n"
667  " - \"none\", \"0\" : even if other logging categories are "
668  "specified, ignore all of them.\n",
669  {
670  {"include",
673  "The categories to add to debug logging",
674  {
675  {"include_category", RPCArg::Type::STR,
676  RPCArg::Optional::OMITTED, "the valid logging category"},
677  }},
678  {"exclude",
681  "The categories to remove from debug logging",
682  {
683  {"exclude_category", RPCArg::Type::STR,
684  RPCArg::Optional::OMITTED, "the valid logging category"},
685  }},
686  },
687  RPCResult{
689  "",
690  "keys are the logging categories, and values indicates its status",
691  {
692  {RPCResult::Type::BOOL, "category",
693  "if being debug logged or not. false:inactive, true:active"},
694  }},
695  RPCExamples{
696  HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"") +
697  HelpExampleRpc("logging", "[\"all\"], [\"libevent\"]")},
698  [&](const RPCHelpMan &self, const Config &config,
699  const JSONRPCRequest &request) -> UniValue {
700  uint32_t original_log_categories = LogInstance().GetCategoryMask();
701  if (request.params[0].isArray()) {
702  EnableOrDisableLogCategories(request.params[0], true);
703  }
704 
705  if (request.params[1].isArray()) {
706  EnableOrDisableLogCategories(request.params[1], false);
707  }
708 
709  uint32_t updated_log_categories = LogInstance().GetCategoryMask();
710  uint32_t changed_log_categories =
711  original_log_categories ^ updated_log_categories;
712 
720  if (changed_log_categories & BCLog::LIBEVENT) {
722  LogInstance().WillLogCategory(BCLog::LIBEVENT))) {
724  if (changed_log_categories == BCLog::LIBEVENT) {
725  throw JSONRPCError(
727  "libevent logging cannot be updated when "
728  "using libevent before v2.1.1.");
729  }
730  }
731  }
732 
733  UniValue result(UniValue::VOBJ);
734  for (const auto &logCatActive : LogInstance().LogCategoriesList()) {
735  result.pushKV(logCatActive.category, logCatActive.active);
736  }
737 
738  return result;
739  },
740  };
741 }
742 
743 static RPCHelpMan echo(const std::string &name) {
744  return RPCHelpMan{
745  name,
746  "Simply echo back the input arguments. This command is for "
747  "testing.\n"
748  "\nIt will return an internal bug report when "
749  "arg9='trigger_internal_bug' is passed.\n"
750  "\nThe difference between echo and echojson is that echojson has "
751  "argument conversion enabled in the client-side table in "
752  "bitcoin-cli and the GUI. There is no server-side difference.",
753  {
755  ""},
757  ""},
759  ""},
761  ""},
763  ""},
765  ""},
767  ""},
769  ""},
771  ""},
773  ""},
774  },
775  RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},
776  RPCExamples{""},
777  [&](const RPCHelpMan &self, const Config &config,
778  const JSONRPCRequest &request) -> UniValue {
779  if (request.params[9].isStr()) {
780  CHECK_NONFATAL(request.params[9].get_str() !=
781  "trigger_internal_bug");
782  }
783 
784  return request.params;
785  },
786  };
787 }
788 
789 static RPCHelpMan echo() {
790  return echo("echo");
791 }
793  return echo("echojson");
794 }
795 
797  return RPCHelpMan{
798  "getcurrencyinfo",
799  "Returns an object containing information about the currency.\n",
800  {},
801  {
802  RPCResult{
804  "",
805  "",
806  {
807  {RPCResult::Type::STR, "ticker", "Ticker symbol"},
808  {RPCResult::Type::NUM, "satoshisperunit",
809  "Number of satoshis per base unit"},
810  {RPCResult::Type::NUM, "decimals",
811  "Number of digits to the right of the decimal point."},
812  }},
813  },
814  RPCExamples{HelpExampleCli("getcurrencyinfo", "") +
815  HelpExampleRpc("getcurrencyinfo", "")},
816  [&](const RPCHelpMan &self, const Config &config,
817  const JSONRPCRequest &request) -> UniValue {
818  const Currency &currency = Currency::get();
819 
821  res.pushKV("ticker", currency.ticker);
822  res.pushKV("satoshisperunit", currency.baseunit / SATOSHI);
823  res.pushKV("decimals", currency.decimals);
824  return res;
825  },
826  };
827 }
828 
829 static UniValue SummaryToJSON(const IndexSummary &&summary,
830  std::string index_name) {
831  UniValue ret_summary(UniValue::VOBJ);
832  if (!index_name.empty() && index_name != summary.name) {
833  return ret_summary;
834  }
835 
836  UniValue entry(UniValue::VOBJ);
837  entry.pushKV("synced", summary.synced);
838  entry.pushKV("best_block_height", summary.best_block_height);
839  ret_summary.pushKV(summary.name, entry);
840  return ret_summary;
841 }
842 
844  return RPCHelpMan{
845  "getindexinfo",
846  "Returns the status of one or all available indices currently "
847  "running in the node.\n",
848  {
849  {"index_name", RPCArg::Type::STR,
851  "Filter results for an index with a specific name."},
852  },
853  RPCResult{
855  "",
856  "",
857  {
859  "name",
860  "The name of the index",
861  {
862  {RPCResult::Type::BOOL, "synced",
863  "Whether the index is synced or not"},
864  {RPCResult::Type::NUM, "best_block_height",
865  "The block height to which the index is synced"},
866  }},
867  },
868  },
869  RPCExamples{HelpExampleCli("getindexinfo", "") +
870  HelpExampleRpc("getindexinfo", "") +
871  HelpExampleCli("getindexinfo", "txindex") +
872  HelpExampleRpc("getindexinfo", "txindex")},
873  [&](const RPCHelpMan &self, const Config &config,
874  const JSONRPCRequest &request) -> UniValue {
875  UniValue result(UniValue::VOBJ);
876  const std::string index_name =
877  request.params[0].isNull() ? "" : request.params[0].get_str();
878 
879  if (g_txindex) {
880  result.pushKVs(
881  SummaryToJSON(g_txindex->GetSummary(), index_name));
882  }
883 
884  if (g_coin_stats_index) {
885  result.pushKVs(SummaryToJSON(g_coin_stats_index->GetSummary(),
886  index_name));
887  }
888 
889  ForEachBlockFilterIndex([&result, &index_name](
890  const BlockFilterIndex &index) {
891  result.pushKVs(SummaryToJSON(index.GetSummary(), index_name));
892  });
893 
894  return result;
895  },
896  };
897 }
898 
899 static RPCHelpMan gettime() {
900  return RPCHelpMan{
901  "gettime",
902  "Returns the node time information\n",
903  {},
904  RPCResult{
906  "time",
907  "",
908  {
909  {RPCResult::Type::NUM, "local", "The node local timestamp"},
910  {RPCResult::Type::NUM, "offset",
911  "The time offset gathered from the other nodes on the "
912  "network"},
913  {RPCResult::Type::NUM, "adjusted",
914  "The adjusted timestamp of this node"},
915  },
916  },
917  RPCExamples{HelpExampleCli("gettime", "") +
918  HelpExampleRpc("gettime", "")},
919  [&](const RPCHelpMan &self, const Config &config,
920  const JSONRPCRequest &request) -> UniValue {
921  UniValue timeObj(UniValue::VOBJ);
922  timeObj.pushKV("local", GetTime());
923  timeObj.pushKV("offset", GetTimeOffset());
924  timeObj.pushKV("adjusted", TicksSinceEpoch<std::chrono::seconds>(
925  GetAdjustedTime()));
926  return timeObj;
927  },
928  };
929 }
930 
932  // clang-format off
933  static const CRPCCommand commands[] = {
934  // category actor (function)
935  // ------------------ ----------------------
936  { "control", getmemoryinfo, },
937  { "control", logging, },
938  { "util", validateaddress, },
939  { "util", createmultisig, },
940  { "util", deriveaddresses, },
941  { "util", getdescriptorinfo, },
942  { "util", verifymessage, },
943  { "util", signmessagewithprivkey, },
944  { "util", getcurrencyinfo, },
945  { "util", getindexinfo, },
946  { "util", gettime, },
947 
948  /* Not shown in help */
949  { "hidden", setmocktime, },
950  { "hidden", mockscheduler, },
951  { "hidden", echo, },
952  { "hidden", echojson, },
953  };
954  // clang-format on
955  for (const auto &c : commands) {
956  t.appendCommand(c.name, &c);
957  }
958 }
static constexpr Amount SATOSHI
Definition: amount.h:143
void ForEachBlockFilterIndex(std::function< void(BlockFilterIndex &)> fn)
Iterate over all running block filter indexes, invoking fn on each.
const CChainParams & Params()
Return the currently selected parameters.
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:53
void DisableCategory(LogFlags category)
Definition: logging.cpp:337
void EnableCategory(LogFlags category)
Definition: logging.cpp:324
uint32_t GetCategoryMask() const
Definition: logging.h:149
std::string LogCategoriesString() const
Returns a string with the log categories in alphabetical order.
Definition: logging.h:162
IndexSummary GetSummary() const
Get a summary of the index and its state.
Definition: base.cpp:387
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
bool IsMockableChain() const
If this chain allows time to be mocked.
Definition: chainparams.h:107
An encapsulated secp256k1 private key.
Definition: key.h:28
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:94
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
RPC command dispatcher.
Definition: server.h:183
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:330
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:431
Definition: config.h:17
Fillable signing provider that keeps keys in an address->secret map.
Stats stats() const
Get pool usage statistics.
Definition: lockedpool.cpp:332
static LockedPoolManager & Instance()
Return the current instance, or create it once.
Definition: lockedpool.h:236
const std::string & get_str() const
@ VOBJ
Definition: univalue.h:27
@ VARR
Definition: univalue.h:27
bool isNull() const
Definition: univalue.h:89
size_t size() const
Definition: univalue.h:80
bool empty() const
Definition: univalue.h:78
bool pushKVs(const UniValue &obj)
Definition: univalue.cpp:146
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
const UniValue & get_array() const
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
int get_int() const
std::unique_ptr< CoinStatsIndex > g_coin_stats_index
The global UTXO set hash object.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
bool UpdateHTTPServerLogging(bool enable)
Change logging level for libevent.
Definition: httpserver.cpp:443
std::string EncodeDestination(const CTxDestination &dest, const Config &config)
Definition: key_io.cpp:167
CTxDestination DecodeDestination(const std::string &addr, const CChainParams &params)
Definition: key_io.cpp:174
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:77
BCLog::Logger & LogInstance()
Definition: logging.cpp:20
MessageVerificationResult MessageVerify(const CChainParams &params, const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: message.cpp:24
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: message.cpp:56
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
@ ERR_INVALID_ADDRESS
The provided address is invalid.
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
@ OK
The message verification was successful.
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
static RPCHelpMan logging()
Definition: misc.cpp:650
static RPCHelpMan setmocktime()
Definition: misc.cpp:447
void RegisterMiscRPCCommands(CRPCTable &t)
Definition: misc.cpp:931
static void EnableOrDisableLogCategories(UniValue cats, bool enable)
Definition: misc.cpp:631
static UniValue RPCLockedMemoryInfo()
Definition: misc.cpp:529
static RPCHelpMan mockscheduler()
Definition: misc.cpp:492
static RPCHelpMan getmemoryinfo()
Definition: misc.cpp:559
static RPCHelpMan getcurrencyinfo()
Definition: misc.cpp:796
static RPCHelpMan getdescriptorinfo()
Definition: misc.cpp:182
static RPCHelpMan echo(const std::string &name)
Definition: misc.cpp:743
static UniValue SummaryToJSON(const IndexSummary &&summary, std::string index_name)
Definition: misc.cpp:829
static RPCHelpMan gettime()
Definition: misc.cpp:899
static RPCHelpMan echojson()
Definition: misc.cpp:792
static RPCHelpMan deriveaddresses()
Definition: misc.cpp:236
static RPCHelpMan signmessagewithprivkey()
Definition: misc.cpp:403
static RPCHelpMan createmultisig()
Definition: misc.cpp:92
static RPCHelpMan verifymessage()
Definition: misc.cpp:343
static RPCHelpMan validateaddress()
Definition: misc.cpp:41
static RPCHelpMan getindexinfo()
Definition: misc.cpp:843
@ LIBEVENT
Definition: logging.h:57
static bool isNull(const AnyVoteItem &item)
Definition: processor.cpp:405
OutputType
Definition: outputtype.h:16
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:57
const char * name
Definition: rest.cpp:48
@ RPC_MISC_ERROR
General application defined errors std::exception thrown in command handling.
Definition: protocol.h:38
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
Definition: protocol.h:40
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:46
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:42
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:1043
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:24
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:175
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:258
const std::string EXAMPLE_ADDRESS
Example CashAddr address used in multiple RPCExamples.
Definition: util.cpp:21
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:192
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
Definition: util.cpp:20
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:216
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:326
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:158
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:260
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:240
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:85
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
bool IsHex(const std::string &str)
Returns true if each character in str is a hex character, and has an even number of hex digits.
Amount baseunit
Definition: amount.h:147
static const Currency & get()
Definition: amount.cpp:18
std::string ticker
Definition: amount.h:150
uint8_t decimals
Definition: amount.h:149
std::map< CKeyID, CKey > keys
Memory statistics.
Definition: lockedpool.h:153
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ STR_HEX
Special type that is a STR with only hex chars.
@ OMITTED_NAMED_ARG
Optional arg that is a named argument and has a default value of null.
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
@ NO
Required arg.
@ ANY
Special type to disable type checks (for testing only)
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
NodeContext struct containing references to chain state and connection state.
Definition: context.h:38
#define LOCK(cs)
Definition: sync.h:306
bool error(const char *fmt, const Args &...args)
Definition: system.h:45
int64_t GetTime()
Definition: time.cpp:109
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:89
int64_t GetTimeOffset()
"Never go to sea with two chronometers; take one or three." Our three time sources are:
Definition: timedata.cpp:29
NodeClock::time_point GetAdjustedTime()
Definition: timedata.cpp:34
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:17
const UniValue NullUniValue
Definition: univalue.cpp:13