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