Bitcoin Core  0.19.99
P2P Digital Currency
misc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 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 <httpserver.h>
7 #include <key_io.h>
8 #include <outputtype.h>
9 #include <rpc/blockchain.h>
10 #include <rpc/server.h>
11 #include <rpc/util.h>
12 #include <script/descriptor.h>
13 #include <util/check.h>
14 #include <util/strencodings.h>
15 #include <util/system.h>
16 #include <util/validation.h>
17 
18 #include <stdint.h>
19 #include <tuple>
20 #ifdef HAVE_MALLOC_INFO
21 #include <malloc.h>
22 #endif
23 
24 #include <univalue.h>
25 
26 static UniValue validateaddress(const JSONRPCRequest& request)
27 {
28  RPCHelpMan{"validateaddress",
29  "\nReturn information about the given bitcoin address.\n",
30  {
31  {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to validate"},
32  },
33  RPCResult{
34  "{\n"
35  " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
36  " \"address\" : \"address\", (string) The bitcoin address validated\n"
37  " \"scriptPubKey\" : \"hex\", (string) The hex-encoded scriptPubKey generated by the address\n"
38  " \"isscript\" : true|false, (boolean) If the key is a script\n"
39  " \"iswitness\" : true|false, (boolean) If the address is a witness address\n"
40  " \"witness_version\" : version (numeric, optional) The version number of the witness program\n"
41  " \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n"
42  "}\n"
43  },
45  HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
46  + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
47  },
48  }.Check(request);
49 
50  CTxDestination dest = DecodeDestination(request.params[0].get_str());
51  bool isValid = IsValidDestination(dest);
52 
54  ret.pushKV("isvalid", isValid);
55  if (isValid)
56  {
57  std::string currentAddress = EncodeDestination(dest);
58  ret.pushKV("address", currentAddress);
59 
60  CScript scriptPubKey = GetScriptForDestination(dest);
61  ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
62 
63  UniValue detail = DescribeAddress(dest);
64  ret.pushKVs(detail);
65  }
66  return ret;
67 }
68 
69 static UniValue createmultisig(const JSONRPCRequest& request)
70 {
71  RPCHelpMan{"createmultisig",
72  "\nCreates a multi-signature address with n signature of m keys required.\n"
73  "It returns a json object with the address and redeemScript.\n",
74  {
75  {"nrequired", RPCArg::Type::NUM, RPCArg::Optional::NO, "The number of required signatures out of the n keys."},
76  {"keys", RPCArg::Type::ARR, RPCArg::Optional::NO, "A json array of hex-encoded public keys.",
77  {
78  {"key", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hex-encoded public key"},
79  }},
80  {"address_type", RPCArg::Type::STR, /* default */ "legacy", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
81  },
82  RPCResult{
83  "{\n"
84  " \"address\" : \"multisigaddress\", (string) The value of the new multisig address.\n"
85  " \"redeemScript\" : \"script\" (string) The string value of the hex-encoded redemption script.\n"
86  " \"descriptor\" : \"descriptor\" (string) The descriptor for this multisig\n"
87  "}\n"
88  },
90  "\nCreate a multisig address from 2 public keys\n"
91  + HelpExampleCli("createmultisig", "2 \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"") +
92  "\nAs a JSON-RPC call\n"
93  + HelpExampleRpc("createmultisig", "2, \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"")
94  },
95  }.Check(request);
96 
97  int required = request.params[0].get_int();
98 
99  // Get the public keys
100  const UniValue& keys = request.params[1].get_array();
101  std::vector<CPubKey> pubkeys;
102  for (unsigned int i = 0; i < keys.size(); ++i) {
103  if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) {
104  pubkeys.push_back(HexToPubKey(keys[i].get_str()));
105  } else {
106  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str()));
107  }
108  }
109 
110  // Get the output type
111  OutputType output_type = OutputType::LEGACY;
112  if (!request.params[2].isNull()) {
113  if (!ParseOutputType(request.params[2].get_str(), output_type)) {
114  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
115  }
116  }
117 
118  // Construct using pay-to-script-hash:
119  FillableSigningProvider keystore;
120  CScript inner;
121  const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, keystore, inner);
122 
123  // Make the descriptor
124  std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), keystore);
125 
126  UniValue result(UniValue::VOBJ);
127  result.pushKV("address", EncodeDestination(dest));
128  result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
129  result.pushKV("descriptor", descriptor->ToString());
130 
131  return result;
132 }
133 
135 {
136  RPCHelpMan{"getdescriptorinfo",
137  {"\nAnalyses a descriptor.\n"},
138  {
139  {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."},
140  },
141  RPCResult{
142  "{\n"
143  " \"descriptor\" : \"desc\", (string) The descriptor in canonical form, without private keys\n"
144  " \"checksum\" : \"chksum\", (string) The checksum for the input descriptor\n"
145  " \"isrange\" : true|false, (boolean) Whether the descriptor is ranged\n"
146  " \"issolvable\" : true|false, (boolean) Whether the descriptor is solvable\n"
147  " \"hasprivatekeys\" : true|false, (boolean) Whether the input descriptor contained at least one private key\n"
148  "}\n"
149  },
150  RPCExamples{
151  "Analyse a descriptor\n" +
152  HelpExampleCli("getdescriptorinfo", "\"wpkh([d34db33f/84h/0h/0h]0279be667ef9dcbbac55a06295Ce870b07029Bfcdb2dce28d959f2815b16f81798)\"")
153  }}.Check(request);
154 
155  RPCTypeCheck(request.params, {UniValue::VSTR});
156 
157  FlatSigningProvider provider;
158  std::string error;
159  auto desc = Parse(request.params[0].get_str(), provider, error);
160  if (!desc) {
162  }
163 
164  UniValue result(UniValue::VOBJ);
165  result.pushKV("descriptor", desc->ToString());
166  result.pushKV("checksum", GetDescriptorChecksum(request.params[0].get_str()));
167  result.pushKV("isrange", desc->IsRange());
168  result.pushKV("issolvable", desc->IsSolvable());
169  result.pushKV("hasprivatekeys", provider.keys.size() > 0);
170  return result;
171 }
172 
174 {
175  RPCHelpMan{"deriveaddresses",
176  {"\nDerives one or more addresses corresponding to an output descriptor.\n"
177  "Examples of output descriptors are:\n"
178  " pkh(<pubkey>) P2PKH outputs for the given pubkey\n"
179  " wpkh(<pubkey>) Native segwit P2PKH outputs for the given pubkey\n"
180  " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"
181  " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n"
182  "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
183  "or more path elements separated by \"/\", where \"h\" represents a hardened child key.\n"
184  "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"},
185  {
186  {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."},
187  {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."},
188  },
189  RPCResult{
190  "[ address ] (json array) the derived addresses\n"
191  },
192  RPCExamples{
193  "First three native segwit receive addresses\n" +
194  HelpExampleCli("deriveaddresses", "\"wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu\" \"[0,2]\"")
195  }}.Check(request);
196 
197  RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()}); // Range argument is checked later
198  const std::string desc_str = request.params[0].get_str();
199 
200  int64_t range_begin = 0;
201  int64_t range_end = 0;
202 
203  if (request.params.size() >= 2 && !request.params[1].isNull()) {
204  std::tie(range_begin, range_end) = ParseDescriptorRange(request.params[1]);
205  }
206 
207  FlatSigningProvider key_provider;
208  std::string error;
209  auto desc = Parse(desc_str, key_provider, error, /* require_checksum = */ true);
210  if (!desc) {
212  }
213 
214  if (!desc->IsRange() && request.params.size() > 1) {
215  throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor");
216  }
217 
218  if (desc->IsRange() && request.params.size() == 1) {
219  throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor");
220  }
221 
222  UniValue addresses(UniValue::VARR);
223 
224  for (int i = range_begin; i <= range_end; ++i) {
225  FlatSigningProvider provider;
226  std::vector<CScript> scripts;
227  if (!desc->Expand(i, key_provider, scripts, provider)) {
228  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys"));
229  }
230 
231  for (const CScript &script : scripts) {
232  CTxDestination dest;
233  if (!ExtractDestination(script, dest)) {
234  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Descriptor does not have a corresponding address"));
235  }
236 
237  addresses.push_back(EncodeDestination(dest));
238  }
239  }
240 
241  // This should not be possible, but an assert seems overkill:
242  if (addresses.empty()) {
243  throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result");
244  }
245 
246  return addresses;
247 }
248 
249 static UniValue verifymessage(const JSONRPCRequest& request)
250 {
251  RPCHelpMan{"verifymessage",
252  "\nVerify a signed message\n",
253  {
254  {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the signature."},
255  {"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."},
256  {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
257  },
258  RPCResult{
259  "true|false (boolean) If the signature is verified or not.\n"
260  },
261  RPCExamples{
262  "\nUnlock the wallet for 30 seconds\n"
263  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
264  "\nCreate the signature\n"
265  + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
266  "\nVerify the signature\n"
267  + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
268  "\nAs a JSON-RPC call\n"
269  + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"signature\", \"my message\"")
270  },
271  }.Check(request);
272 
273  LOCK(cs_main);
274 
275  std::string strAddress = request.params[0].get_str();
276  std::string strSign = request.params[1].get_str();
277  std::string strMessage = request.params[2].get_str();
278 
279  CTxDestination destination = DecodeDestination(strAddress);
280  if (!IsValidDestination(destination)) {
281  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
282  }
283 
284  const PKHash *pkhash = boost::get<PKHash>(&destination);
285  if (!pkhash) {
286  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
287  }
288 
289  bool fInvalid = false;
290  std::vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
291 
292  if (fInvalid)
293  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
294 
295  CHashWriter ss(SER_GETHASH, 0);
296  ss << strMessageMagic;
297  ss << strMessage;
298 
299  CPubKey pubkey;
300  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
301  return false;
302 
303  return (pubkey.GetID() == *pkhash);
304 }
305 
307 {
308  RPCHelpMan{"signmessagewithprivkey",
309  "\nSign a message with the private key of an address\n",
310  {
311  {"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
312  {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
313  },
314  RPCResult{
315  "\"signature\" (string) The signature of the message encoded in base 64\n"
316  },
317  RPCExamples{
318  "\nCreate the signature\n"
319  + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
320  "\nVerify the signature\n"
321  + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
322  "\nAs a JSON-RPC call\n"
323  + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
324  },
325  }.Check(request);
326 
327  std::string strPrivkey = request.params[0].get_str();
328  std::string strMessage = request.params[1].get_str();
329 
330  CKey key = DecodeSecret(strPrivkey);
331  if (!key.IsValid()) {
332  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
333  }
334 
335  CHashWriter ss(SER_GETHASH, 0);
336  ss << strMessageMagic;
337  ss << strMessage;
338 
339  std::vector<unsigned char> vchSig;
340  if (!key.SignCompact(ss.GetHash(), vchSig))
341  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
342 
343  return EncodeBase64(vchSig.data(), vchSig.size());
344 }
345 
346 static UniValue setmocktime(const JSONRPCRequest& request)
347 {
348  RPCHelpMan{"setmocktime",
349  "\nSet the local time to given timestamp (-regtest only)\n",
350  {
352  " Pass 0 to go back to using the system time."},
353  },
354  RPCResults{},
355  RPCExamples{""},
356  }.Check(request);
357 
358  if (!Params().MineBlocksOnDemand())
359  throw std::runtime_error("setmocktime for regression testing (-regtest mode) only");
360 
361  // For now, don't change mocktime if we're in the middle of validation, as
362  // this could have an effect on mempool time-based eviction, as well as
363  // IsCurrentForFeeEstimation() and IsInitialBlockDownload().
364  // TODO: figure out the right way to synchronize around mocktime, and
365  // ensure all call sites of GetTime() are accessing this safely.
366  LOCK(cs_main);
367 
368  RPCTypeCheck(request.params, {UniValue::VNUM});
369  SetMockTime(request.params[0].get_int64());
370 
371  return NullUniValue;
372 }
373 
375 {
378  obj.pushKV("used", uint64_t(stats.used));
379  obj.pushKV("free", uint64_t(stats.free));
380  obj.pushKV("total", uint64_t(stats.total));
381  obj.pushKV("locked", uint64_t(stats.locked));
382  obj.pushKV("chunks_used", uint64_t(stats.chunks_used));
383  obj.pushKV("chunks_free", uint64_t(stats.chunks_free));
384  return obj;
385 }
386 
387 #ifdef HAVE_MALLOC_INFO
388 static std::string RPCMallocInfo()
389 {
390  char *ptr = nullptr;
391  size_t size = 0;
392  FILE *f = open_memstream(&ptr, &size);
393  if (f) {
394  malloc_info(0, f);
395  fclose(f);
396  if (ptr) {
397  std::string rv(ptr, size);
398  free(ptr);
399  return rv;
400  }
401  }
402  return "";
403 }
404 #endif
405 
406 static UniValue getmemoryinfo(const JSONRPCRequest& request)
407 {
408  /* Please, avoid using the word "pool" here in the RPC interface or help,
409  * as users will undoubtedly confuse it with the other "memory pool"
410  */
411  RPCHelpMan{"getmemoryinfo",
412  "Returns an object containing information about memory usage.\n",
413  {
414  {"mode", RPCArg::Type::STR, /* default */ "\"stats\"", "determines what kind of information is returned.\n"
415  " - \"stats\" returns general statistics about memory usage in the daemon.\n"
416  " - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc 2.10+)."},
417  },
418  {
419  RPCResult{"mode \"stats\"",
420  "{\n"
421  " \"locked\" : { (json object) Information about locked memory manager\n"
422  " \"used\" : xxxxx, (numeric) Number of bytes used\n"
423  " \"free\" : xxxxx, (numeric) Number of bytes available in current arenas\n"
424  " \"total\" : xxxxxxx, (numeric) Total number of bytes managed\n"
425  " \"locked\" : xxxxxx, (numeric) Amount of bytes that succeeded locking. If this number is smaller than total, locking pages failed at some point and key data could be swapped to disk.\n"
426  " \"chunks_used\" : xxxxx, (numeric) Number allocated chunks\n"
427  " \"chunks_free\" : xxxxx, (numeric) Number unused chunks\n"
428  " }\n"
429  "}\n"
430  },
431  RPCResult{"mode \"mallocinfo\"",
432  "\"<malloc version=\"1\">...\"\n"
433  },
434  },
435  RPCExamples{
436  HelpExampleCli("getmemoryinfo", "")
437  + HelpExampleRpc("getmemoryinfo", "")
438  },
439  }.Check(request);
440 
441  std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str();
442  if (mode == "stats") {
444  obj.pushKV("locked", RPCLockedMemoryInfo());
445  return obj;
446  } else if (mode == "mallocinfo") {
447 #ifdef HAVE_MALLOC_INFO
448  return RPCMallocInfo();
449 #else
450  throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo is only available when compiled with glibc 2.10+");
451 #endif
452  } else {
453  throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode);
454  }
455 }
456 
457 static void EnableOrDisableLogCategories(UniValue cats, bool enable) {
458  cats = cats.get_array();
459  for (unsigned int i = 0; i < cats.size(); ++i) {
460  std::string cat = cats[i].get_str();
461 
462  bool success;
463  if (enable) {
464  success = LogInstance().EnableCategory(cat);
465  } else {
466  success = LogInstance().DisableCategory(cat);
467  }
468 
469  if (!success) {
470  throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown logging category " + cat);
471  }
472  }
473 }
474 
476 {
477  RPCHelpMan{"logging",
478  "Gets and sets the logging configuration.\n"
479  "When called without an argument, returns the list of categories with status that are currently being debug logged or not.\n"
480  "When called with arguments, adds or removes categories from debug logging and return the lists above.\n"
481  "The arguments are evaluated in order \"include\", \"exclude\".\n"
482  "If an item is both included and excluded, it will thus end up being excluded.\n"
483  "The valid logging categories are: " + ListLogCategories() + "\n"
484  "In addition, the following are available as category names with special meanings:\n"
485  " - \"all\", \"1\" : represent all logging categories.\n"
486  " - \"none\", \"0\" : even if other logging categories are specified, ignore all of them.\n"
487  ,
488  {
489  {"include", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "A json array of categories to add debug logging",
490  {
491  {"include_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"},
492  }},
493  {"exclude", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "A json array of categories to remove debug logging",
494  {
495  {"exclude_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"},
496  }},
497  },
498  RPCResult{
499  "{ (json object where keys are the logging categories, and values indicates its status\n"
500  " \"category\" : true|false, (boolean) if being debug logged or not. false:inactive, true:active\n"
501  " ...\n"
502  "}\n"
503  },
504  RPCExamples{
505  HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"")
506  + HelpExampleRpc("logging", "[\"all\"], [\"libevent\"]")
507  },
508  }.Check(request);
509 
510  uint32_t original_log_categories = LogInstance().GetCategoryMask();
511  if (request.params[0].isArray()) {
512  EnableOrDisableLogCategories(request.params[0], true);
513  }
514  if (request.params[1].isArray()) {
515  EnableOrDisableLogCategories(request.params[1], false);
516  }
517  uint32_t updated_log_categories = LogInstance().GetCategoryMask();
518  uint32_t changed_log_categories = original_log_categories ^ updated_log_categories;
519 
520  // Update libevent logging if BCLog::LIBEVENT has changed.
521  // If the library version doesn't allow it, UpdateHTTPServerLogging() returns false,
522  // in which case we should clear the BCLog::LIBEVENT flag.
523  // Throw an error if the user has explicitly asked to change only the libevent
524  // flag and it failed.
525  if (changed_log_categories & BCLog::LIBEVENT) {
526  if (!UpdateHTTPServerLogging(LogInstance().WillLogCategory(BCLog::LIBEVENT))) {
527  LogInstance().DisableCategory(BCLog::LIBEVENT);
528  if (changed_log_categories == BCLog::LIBEVENT) {
529  throw JSONRPCError(RPC_INVALID_PARAMETER, "libevent logging cannot be updated when using libevent before v2.1.1.");
530  }
531  }
532  }
533 
534  UniValue result(UniValue::VOBJ);
535  std::vector<CLogCategoryActive> vLogCatActive = ListActiveLogCategories();
536  for (const auto& logCatActive : vLogCatActive) {
537  result.pushKV(logCatActive.category, logCatActive.active);
538  }
539 
540  return result;
541 }
542 
543 static UniValue echo(const JSONRPCRequest& request)
544 {
545  if (request.fHelp)
546  throw std::runtime_error(
547  RPCHelpMan{"echo|echojson ...",
548  "\nSimply echo back the input arguments. This command is for testing.\n"
549  "\nIt will return an internal bug report when exactly 100 arguments are passed.\n"
550  "\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in "
551  "bitcoin-cli and the GUI. There is no server-side difference.",
552  {},
553  RPCResults{},
554  RPCExamples{""},
555  }.ToString()
556  );
557 
558  CHECK_NONFATAL(request.params.size() != 100);
559 
560  return request.params;
561 }
562 
563 // clang-format off
564 static const CRPCCommand commands[] =
565 { // category name actor (function) argNames
566  // --------------------- ------------------------ ----------------------- ----------
567  { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} },
568  { "control", "logging", &logging, {"include", "exclude"}},
569  { "util", "validateaddress", &validateaddress, {"address"} },
570  { "util", "createmultisig", &createmultisig, {"nrequired","keys","address_type"} },
571  { "util", "deriveaddresses", &deriveaddresses, {"descriptor", "range"} },
572  { "util", "getdescriptorinfo", &getdescriptorinfo, {"descriptor"} },
573  { "util", "verifymessage", &verifymessage, {"address","signature","message"} },
574  { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
575 
576  /* Not shown in help */
577  { "hidden", "setmocktime", &setmocktime, {"timestamp"}},
578  { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
579  { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
580 };
581 // clang-format on
582 
584 {
585  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
586  t.appendCommand(commands[vcidx].name, &commands[vcidx]);
587 }
void EnableCategory(LogFlags flag)
Definition: logging.cpp:90
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:18
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:156
BCLog::Logger & LogInstance()
Definition: logging.cpp:14
Bitcoin RPC command dispatcher.
Definition: server.h:119
static UniValue signmessagewithprivkey(const JSONRPCRequest &request)
Definition: misc.cpp:306
Required arg.
static LockedPoolManager & Instance()
Return the current instance, or create it once.
Definition: lockedpool.h:222
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
std::map< CKeyID, CKey > keys
std::string ListLogCategories()
Returns a string with the log categories.
Definition: logging.cpp:185
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
Definition: descriptor.cpp:999
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:16
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
Definition: strencodings.h:19
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:28
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:325
const std::string & get_str() const
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
const UniValue & get_array() const
int64_t get_int64() const
bool pushKVs(const UniValue &obj)
Definition: univalue.cpp:146
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:259
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:155
OutputType
Definition: outputtype.h:17
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Create a compact signature (65 bytes), which allows reconstructing the used public key...
Definition: key.cpp:246
void SetMockTime(int64_t nMockTimeIn)
For testing.
Definition: time.cpp:44
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
Definition: descriptor.cpp:990
iterator end()
Definition: prevector.h:292
Special type that is a STR with only hex chars.
std::string name
Definition: server.h:110
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:51
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
static UniValue createmultisig(const JSONRPCRequest &request)
Definition: misc.cpp:69
UniValue params
Definition: request.h:32
#define LOCK(cs)
Definition: sync.h:179
UniValue deriveaddresses(const JSONRPCRequest &request)
Definition: misc.cpp:173
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:187
std::string EncodeBase64(const unsigned char *pch, size_t len)
An encapsulated public key.
Definition: pubkey.h:30
Fillable signing provider that keeps keys in an address->secret map.
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:116
bool IsHex(const std::string &str)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:106
Unexpected type was passed as parameter.
Definition: protocol.h:40
uint32_t GetCategoryMask() const
Definition: logging.h:127
bool empty() const
Definition: univalue.h:66
void DisableCategory(LogFlags flag)
Definition: logging.cpp:111
General application defined errors.
Definition: protocol.h:39
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
int get_int() const
Invalid address or key.
Definition: protocol.h:41
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:289
static const CRPCCommand commands[]
Definition: misc.cpp:564
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:157
bool isNull() const
Definition: univalue.h:77
static UniValue RPCLockedMemoryInfo()
Definition: misc.cpp:374
static UniValue echo(const JSONRPCRequest &request)
Definition: misc.cpp:543
Optional arg that is a named argument and has a default value of null.
static void EnableOrDisableLogCategories(UniValue cats, bool enable)
Definition: misc.cpp:457
Special type that is a NUM or [NUM,NUM].
uint256 GetHash()
Definition: hash.h:136
bool fHelp
Definition: request.h:33
Optional argument with default value omitted because they are implicitly clear.
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:215
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
UniValue getdescriptorinfo(const JSONRPCRequest &request)
Definition: misc.cpp:134
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
void RegisterMiscRPCCommands(CRPCTable &t)
Register miscellaneous RPC commands.
Definition: misc.cpp:583
const std::string strMessageMagic
Definition: validation.cpp:25
UniValue logging(const JSONRPCRequest &request)
Definition: misc.cpp:475
std::string HexStr(const T itbegin, const T itend)
Definition: strencodings.h:125
const UniValue NullUniValue
Definition: univalue.cpp:13
iterator begin()
Definition: prevector.h:290
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:683
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:111
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:210
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:117
static UniValue validateaddress(const JSONRPCRequest &request)
Definition: misc.cpp:26
size_t size() const
Definition: univalue.h:68
An encapsulated private key.
Definition: key.h:27
Stats stats() const
Get pool usage statistics.
Definition: lockedpool.cpp:327
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:132
static UniValue verifymessage(const JSONRPCRequest &request)
Definition: misc.cpp:249
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:143
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:246
static UniValue setmocktime(const JSONRPCRequest &request)
Definition: misc.cpp:346
bool ParseOutputType(const std::string &type, OutputType &output_type)
Definition: outputtype.cpp:24
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
std::vector< CLogCategoryActive > ListActiveLogCategories()
Returns a vector of the active log categories.
Definition: logging.cpp:200
static UniValue getmemoryinfo(const JSONRPCRequest &request)
Definition: misc.cpp:406
bool isArray() const
Definition: univalue.h:83
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:123
bool UpdateHTTPServerLogging(bool enable)
Change logging level for libevent.
Definition: httpserver.cpp:409
Memory statistics.
Definition: lockedpool.h:145
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:93