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