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