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