Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

misc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Copyright (c) 2014-2020 The Dash Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include <base58.h>
8 #include <chain.h>
9 #include <clientversion.h>
10 #include <core_io.h>
11 #include <init.h>
12 #include <httpserver.h>
13 #include <net.h>
14 #include <netbase.h>
15 #include <rpc/blockchain.h>
16 #include <rpc/server.h>
17 #include <rpc/util.h>
18 #include <timedata.h>
19 #include <txmempool.h>
20 #include <util.h>
21 #include <utilstrencodings.h>
22 #include <validation.h>
23 #ifdef ENABLE_WALLET
24 #include <wallet/rpcwallet.h>
25 #include <wallet/wallet.h>
26 #include <wallet/walletdb.h>
27 #endif
28 #include <warnings.h>
29 
31 #include <spork.h>
32 
33 #include <stdint.h>
34 #ifdef HAVE_MALLOC_INFO
35 #include <malloc.h>
36 #endif
37 
38 #include <boost/algorithm/string.hpp>
39 
40 #include <univalue.h>
41 
42 UniValue debug(const JSONRPCRequest& request)
43 {
44  if (request.fHelp || request.params.size() != 1)
45  throw std::runtime_error(
46  "debug \"category\"\n"
47  "Change debug category on the fly. Specify single category or use '+' to specify many.\n"
48  "The valid debug categories are: " + ListLogCategories() + ".\n"
49  "libevent logging is configured on startup and cannot be modified by this RPC during runtime.\n"
50  "There are also a few meta-categories:\n"
51  " - \"all\", \"1\" and \"\" activate all categories at once;\n"
52  " - \"dash\" activates all Dash-specific categories at once;\n"
53  " - \"none\" (or \"0\") deactivates all categories at once.\n"
54  "Note: If specified category doesn't match any of the above, no error is thrown.\n"
55  "\nArguments:\n"
56  "1. \"category\" (string, required) The name of the debug category to turn on.\n"
57  "\nResult:\n"
58  " result (string) \"Debug mode: \" followed by the specified category.\n"
59  "\nExamples:\n"
60  + HelpExampleCli("debug", "dash")
61  + HelpExampleRpc("debug", "dash+net")
62  );
63 
64  std::string strMode = request.params[0].get_str();
66 
67  std::vector<std::string> categories;
68  boost::split(categories, strMode, boost::is_any_of("+"));
69 
70  if (std::find(categories.begin(), categories.end(), std::string("0")) == categories.end()) {
71  for (const auto& cat : categories) {
72  uint64_t flag;
73  if (GetLogCategory(&flag, &cat)) {
74  logCategories |= flag;
75  }
76  }
77  }
78 
79  return "Debug mode: " + ListActiveLogCategoriesString();
80 }
81 
83 {
84  if (request.fHelp || request.params.size() != 1)
85  throw std::runtime_error(
86  "mnsync [status|next|reset]\n"
87  "Returns the sync status, updates to the next step or resets it entirely.\n"
88  );
89 
90  std::string strMode = request.params[0].get_str();
91 
92  if(strMode == "status") {
93  UniValue objStatus(UniValue::VOBJ);
94  objStatus.push_back(Pair("AssetID", masternodeSync.GetAssetID()));
95  objStatus.push_back(Pair("AssetName", masternodeSync.GetAssetName()));
96  objStatus.push_back(Pair("AssetStartTime", masternodeSync.GetAssetStartTime()));
97  objStatus.push_back(Pair("Attempt", masternodeSync.GetAttempt()));
98  objStatus.push_back(Pair("IsBlockchainSynced", masternodeSync.IsBlockchainSynced()));
99  objStatus.push_back(Pair("IsSynced", masternodeSync.IsSynced()));
100  return objStatus;
101  }
102 
103  if(strMode == "next")
104  {
106  return "sync updated to " + masternodeSync.GetAssetName();
107  }
108 
109  if(strMode == "reset")
110  {
111  masternodeSync.Reset(true);
112  return "success";
113  }
114  return "failure";
115 }
116 
117 #ifdef ENABLE_WALLET
118 class DescribeAddressVisitor : public boost::static_visitor<UniValue>
119 {
120 public:
121  CWallet * const pwallet;
122 
123  explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {}
124 
125  UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
126 
127  UniValue operator()(const CKeyID &keyID) const {
129  CPubKey vchPubKey;
130  obj.push_back(Pair("isscript", false));
131  if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
132  obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
133  obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
134  }
135  return obj;
136  }
137 
138  UniValue operator()(const CScriptID &scriptID) const {
140  CScript subscript;
141  obj.push_back(Pair("isscript", true));
142  if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
143  std::vector<CTxDestination> addresses;
144  txnouttype whichType;
145  int nRequired;
146  ExtractDestinations(subscript, whichType, addresses, nRequired);
147  obj.push_back(Pair("script", GetTxnOutputType(whichType)));
148  obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
150  for (const CTxDestination& addr : addresses) {
151  a.push_back(EncodeDestination(addr));
152  }
153  obj.push_back(Pair("addresses", a));
154  if (whichType == TX_MULTISIG)
155  obj.push_back(Pair("sigsrequired", nRequired));
156  }
157  return obj;
158  }
159 };
160 #endif
161 
162 /*
163  Used for updating/reading spork settings on the network
164 */
166 {
167  if (request.params.size() == 1) {
168  // basic mode, show info
169  std:: string strCommand = request.params[0].get_str();
170  if (strCommand == "show") {
172  for (const auto& sporkDef : sporkDefs) {
173  ret.push_back(Pair(sporkDef.name, sporkManager.GetSporkValue(sporkDef.sporkId)));
174  }
175  return ret;
176  } else if(strCommand == "active"){
178  for (const auto& sporkDef : sporkDefs) {
179  ret.push_back(Pair(sporkDef.name, sporkManager.IsSporkActive(sporkDef.sporkId)));
180  }
181  return ret;
182  }
183  }
184 
185  if (request.fHelp || request.params.size() != 2) {
186  // default help, for basic mode
187  throw std::runtime_error(
188  "spork \"command\"\n"
189  "\nShows information about current state of sporks\n"
190  "\nArguments:\n"
191  "1. \"command\" (string, required) 'show' to show all current spork values, 'active' to show which sporks are active\n"
192  "\nResult:\n"
193  "For 'show':\n"
194  "{\n"
195  " \"SPORK_NAME\" : spork_value, (number) The value of the specific spork with the name SPORK_NAME\n"
196  " ...\n"
197  "}\n"
198  "For 'active':\n"
199  "{\n"
200  " \"SPORK_NAME\" : true|false, (boolean) 'true' for time-based sporks if spork is active and 'false' otherwise\n"
201  " ...\n"
202  "}\n"
203  "\nExamples:\n"
204  + HelpExampleCli("spork", "show")
205  + HelpExampleRpc("spork", "\"show\""));
206  } else {
207  // advanced mode, update spork values
208  SporkId nSporkID = sporkManager.GetSporkIDByName(request.params[0].get_str());
209  if(nSporkID == SPORK_INVALID)
210  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid spork name");
211 
212  if (!g_connman)
213  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
214 
215  // SPORK VALUE
216  int64_t nValue = request.params[1].get_int64();
217 
218  //broadcast new spork
219  if(sporkManager.UpdateSpork(nSporkID, nValue, *g_connman)){
220  return "success";
221  } else {
222  throw std::runtime_error(
223  "spork \"name\" value\n"
224  "\nUpdate the value of the specific spork. Requires \"-sporkkey\" to be set to sign the message.\n"
225  "\nArguments:\n"
226  "1. \"name\" (string, required) The name of the spork to update\n"
227  "2. value (number, required) The new desired value of the spork\n"
228  "\nResult:\n"
229  " result (string) \"success\" if spork value was updated or this help otherwise\n"
230  "\nExamples:\n"
231  + HelpExampleCli("spork", "SPORK_2_INSTANTSEND_ENABLED 4070908800")
232  + HelpExampleRpc("spork", "\"SPORK_2_INSTANTSEND_ENABLED\", 4070908800"));
233  }
234  }
235 
236 }
237 
239 {
240  if (request.fHelp || request.params.size() != 1)
241  throw std::runtime_error(
242  "validateaddress \"address\"\n"
243  "\nReturn information about the given dash address.\n"
244  "\nArguments:\n"
245  "1. \"address\" (string, required) The dash address to validate\n"
246  "\nResult:\n"
247  "{\n"
248  " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
249  " \"address\" : \"address\", (string) The dash address validated\n"
250  " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
251  " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
252  " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
253  " \"isscript\" : true|false, (boolean) If the key is a script\n"
254  " \"script\" : \"type\" (string, optional) The output script type. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata\n"
255  " \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address\n"
256  " \"addresses\" (string, optional) Array of addresses associated with the known redeemscript\n"
257  " [\n"
258  " \"address\"\n"
259  " ,...\n"
260  " ]\n"
261  " \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output\n"
262  " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
263  " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
264  " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
265  " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
266  " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
267  " \"hdchainid\" : \"<hash>\" (string, optional) The ID of the HD chain\n"
268  "}\n"
269  "\nExamples:\n"
270  + HelpExampleCli("validateaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"")
271  + HelpExampleRpc("validateaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"")
272  );
273 
274 #ifdef ENABLE_WALLET
275  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
276 
277  LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
278 #else
279  LOCK(cs_main);
280 #endif
281 
282  CTxDestination dest = DecodeDestination(request.params[0].get_str());
283  bool isValid = IsValidDestination(dest);
284 
286  ret.push_back(Pair("isvalid", isValid));
287  if (isValid)
288  {
289  std::string currentAddress = EncodeDestination(dest);
290  ret.push_back(Pair("address", currentAddress));
291 
292  CScript scriptPubKey = GetScriptForDestination(dest);
293  ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
294 
295 #ifdef ENABLE_WALLET
296  isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
297  ret.push_back(Pair("ismine", bool(mine & ISMINE_SPENDABLE)));
298  ret.push_back(Pair("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)));
299  UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
300  ret.pushKVs(detail);
301  if (pwallet && pwallet->mapAddressBook.count(dest)) {
302  ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name));
303  }
304  if (pwallet) {
305  const CKeyMetadata* meta = nullptr;
306  const CKeyID *keyID = boost::get<CKeyID>(&dest);
307  if (const CKeyID* key_id = boost::get<CKeyID>(&dest)) {
308  auto it = pwallet->mapKeyMetadata.find(*key_id);
309  if (it != pwallet->mapKeyMetadata.end()) {
310  meta = &it->second;
311  }
312  }
313  if (!meta) {
314  auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
315  if (it != pwallet->m_script_metadata.end()) {
316  meta = &it->second;
317  }
318  }
319  if (meta) {
320  ret.push_back(Pair("timestamp", meta->nCreateTime));
321  }
322 
323  CHDChain hdChainCurrent;
324  if (keyID && pwallet->mapHdPubKeys.count(*keyID) && pwallet->GetHDChain(hdChainCurrent)) {
325  ret.push_back(Pair("hdkeypath", pwallet->mapHdPubKeys[*keyID].GetKeyPath()));
326  ret.push_back(Pair("hdchainid", hdChainCurrent.GetID().GetHex()));
327  }
328  }
329 #endif
330  }
331  return ret;
332 }
333 
334 // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around
335 class CWallet;
336 
338 {
339  if (request.fHelp || request.params.size() < 2 || request.params.size() > 2)
340  {
341  std::string msg = "createmultisig nrequired [\"key\",...]\n"
342  "\nCreates a multi-signature address with n signature of m keys required.\n"
343  "It returns a json object with the address and redeemScript.\n"
344  "DEPRECATION WARNING: Using addresses with createmultisig is deprecated. Clients must\n"
345  "transition to using addmultisigaddress to create multisig addresses with addresses known\n"
346  "to the wallet before upgrading to v0.17. To use the deprecated functionality, start dashd with -deprecatedrpc=createmultisig\n"
347  "\nArguments:\n"
348  "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
349  "2. \"keys\" (string, required) A json array of hex-encoded public keys\n"
350  " [\n"
351  " \"key\" (string) The hex-encoded public key\n"
352  " ,...\n"
353  " ]\n"
354 
355  "\nResult:\n"
356  "{\n"
357  " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
358  " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
359  "}\n"
360 
361  "\nExamples:\n"
362  "\nCreate a multisig address from 2 public keys\n"
363  + HelpExampleCli("createmultisig", "2 \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"") +
364  "\nAs a json rpc call\n"
365  + HelpExampleRpc("createmultisig", "2, \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"")
366  ;
367  throw std::runtime_error(msg);
368  }
369 
370  int required = request.params[0].get_int();
371 
372  // Get the public keys
373  const UniValue& keys = request.params[1].get_array();
374  std::vector<CPubKey> pubkeys;
375  for (unsigned int i = 0; i < keys.size(); ++i) {
376  if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) {
377  pubkeys.push_back(HexToPubKey(keys[i].get_str()));
378  } else {
379 #ifdef ENABLE_WALLET
380  CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
381  if (IsDeprecatedRPCEnabled("createmultisig") && EnsureWalletIsAvailable(pwallet, false)) {
382  pubkeys.push_back(AddrToPubKey(pwallet, keys[i].get_str()));
383  } else
384 #endif
385  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\nNote that from v0.16, createmultisig no longer accepts addresses."
386  " Clients must transition to using addmultisigaddress to create multisig addresses with addresses known to the wallet before upgrading to v0.17."
387  " To use the deprecated functionality, start dashd with -deprecatedrpc=createmultisig", keys[i].get_str()));
388  }
389  }
390 
391  // Construct using pay-to-script-hash:
392  CScript inner = CreateMultisigRedeemscript(required, pubkeys);
393  CScriptID innerID(inner);
394 
395  UniValue result(UniValue::VOBJ);
396  result.push_back(Pair("address", EncodeDestination(innerID)));
397  result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
398 
399  return result;
400 }
401 
403 {
404  if (request.fHelp || request.params.size() != 3)
405  throw std::runtime_error(
406  "verifymessage \"address\" \"signature\" \"message\"\n"
407  "\nVerify a signed message\n"
408  "\nArguments:\n"
409  "1. \"address\" (string, required) The dash address to use for the signature.\n"
410  "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
411  "3. \"message\" (string, required) The message that was signed.\n"
412  "\nResult:\n"
413  "true|false (boolean) If the signature is verified or not.\n"
414  "\nExamples:\n"
415  "\nUnlock the wallet for 30 seconds\n"
416  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
417  "\nCreate the signature\n"
418  + HelpExampleCli("signmessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"my message\"") +
419  "\nVerify the signature\n"
420  + HelpExampleCli("verifymessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"signature\" \"my message\"") +
421  "\nAs json rpc\n"
422  + HelpExampleRpc("verifymessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", \"signature\", \"my message\"")
423  );
424 
425  LOCK(cs_main);
426 
427  std::string strAddress = request.params[0].get_str();
428  std::string strSign = request.params[1].get_str();
429  std::string strMessage = request.params[2].get_str();
430 
431  CTxDestination destination = DecodeDestination(strAddress);
432  if (!IsValidDestination(destination)) {
433  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
434  }
435 
436  const CKeyID *keyID = boost::get<CKeyID>(&destination);
437  if (!keyID) {
438  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
439  }
440 
441  bool fInvalid = false;
442  std::vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
443 
444  if (fInvalid)
445  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
446 
447  CHashWriter ss(SER_GETHASH, 0);
448  ss << strMessageMagic;
449  ss << strMessage;
450 
451  CPubKey pubkey;
452  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
453  return false;
454 
455  return (pubkey.GetID() == *keyID);
456 }
457 
459 {
460  if (request.fHelp || request.params.size() != 2)
461  throw std::runtime_error(
462  "signmessagewithprivkey \"privkey\" \"message\"\n"
463  "\nSign a message with the private key of an address\n"
464  "\nArguments:\n"
465  "1. \"privkey\" (string, required) The private key to sign the message with.\n"
466  "2. \"message\" (string, required) The message to create a signature of.\n"
467  "\nResult:\n"
468  "\"signature\" (string) The signature of the message encoded in base 64\n"
469  "\nExamples:\n"
470  "\nCreate the signature\n"
471  + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
472  "\nVerify the signature\n"
473  + HelpExampleCli("verifymessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"signature\" \"my message\"") +
474  "\nAs json rpc\n"
475  + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
476  );
477 
478  std::string strPrivkey = request.params[0].get_str();
479  std::string strMessage = request.params[1].get_str();
480 
481  CBitcoinSecret vchSecret;
482  bool fGood = vchSecret.SetString(strPrivkey);
483  if (!fGood)
484  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
485  CKey key = vchSecret.GetKey();
486  if (!key.IsValid())
487  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
488 
489  CHashWriter ss(SER_GETHASH, 0);
490  ss << strMessageMagic;
491  ss << strMessage;
492 
493  std::vector<unsigned char> vchSig;
494  if (!key.SignCompact(ss.GetHash(), vchSig))
495  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
496 
497  return EncodeBase64(vchSig.data(), vchSig.size());
498 }
499 
501 {
502  if (request.fHelp || request.params.size() != 1)
503  throw std::runtime_error(
504  "setmocktime timestamp\n"
505  "\nSet the local time to given timestamp (-regtest only)\n"
506  "\nArguments:\n"
507  "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
508  " Pass 0 to go back to using the system time."
509  );
510 
511  if (!Params().MineBlocksOnDemand())
512  throw std::runtime_error("setmocktime for regression testing (-regtest mode) only");
513 
514  // For now, don't change mocktime if we're in the middle of validation, as
515  // this could have an effect on mempool time-based eviction, as well as
516  // IsCurrentForFeeEstimation() and IsInitialBlockDownload().
517  // TODO: figure out the right way to synchronize around mocktime, and
518  // ensure all call sites of GetTime() are accessing this safely.
519  LOCK(cs_main);
520 
521  RPCTypeCheck(request.params, {UniValue::VNUM});
522  SetMockTime(request.params[0].get_int64());
523 
524  return NullUniValue;
525 }
526 
527 bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address)
528 {
529  if (type == 2) {
530  address = EncodeDestination(CScriptID(hash));
531  } else if (type == 1) {
532  address = EncodeDestination(CKeyID(hash));
533  } else {
534  return false;
535  }
536  return true;
537 }
538 
539 bool getIndexKey(const std::string& str, uint160& hashBytes, int& type)
540 {
541  CTxDestination dest = DecodeDestination(str);
542  if (!IsValidDestination(dest)) {
543  type = 0;
544  return false;
545  }
546  const CKeyID *keyID = boost::get<CKeyID>(&dest);
547  const CScriptID *scriptID = boost::get<CScriptID>(&dest);
548  type = keyID ? 1 : 2;
549  hashBytes = keyID ? *keyID : *scriptID;
550  return true;
551 }
552 
553 bool getAddressesFromParams(const UniValue& params, std::vector<std::pair<uint160, int> > &addresses)
554 {
555  if (params[0].isStr()) {
556  uint160 hashBytes;
557  int type = 0;
558  if (!getIndexKey(params[0].get_str(), hashBytes, type)) {
559  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
560  }
561  addresses.push_back(std::make_pair(hashBytes, type));
562  } else if (params[0].isObject()) {
563 
564  UniValue addressValues = find_value(params[0].get_obj(), "addresses");
565  if (!addressValues.isArray()) {
566  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Addresses is expected to be an array");
567  }
568 
569  std::vector<UniValue> values = addressValues.getValues();
570 
571  for (std::vector<UniValue>::iterator it = values.begin(); it != values.end(); ++it) {
572 
573  uint160 hashBytes;
574  int type = 0;
575  if (!getIndexKey(it->get_str(), hashBytes, type)) {
576  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
577  }
578  addresses.push_back(std::make_pair(hashBytes, type));
579  }
580  } else {
581  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
582  }
583 
584  return true;
585 }
586 
587 bool heightSort(std::pair<CAddressUnspentKey, CAddressUnspentValue> a,
588  std::pair<CAddressUnspentKey, CAddressUnspentValue> b) {
589  return a.second.blockHeight < b.second.blockHeight;
590 }
591 
592 bool timestampSort(std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> a,
593  std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> b) {
594  return a.second.time < b.second.time;
595 }
596 
598 {
599  if (request.fHelp || request.params.size() != 1)
600  throw std::runtime_error(
601  "getaddressmempool\n"
602  "\nReturns all mempool deltas for an address (requires addressindex to be enabled).\n"
603  "\nArguments:\n"
604  "{\n"
605  " \"addresses\"\n"
606  " [\n"
607  " \"address\" (string) The base58check encoded address\n"
608  " ,...\n"
609  " ]\n"
610  "}\n"
611  "\nResult:\n"
612  "[\n"
613  " {\n"
614  " \"address\" (string) The base58check encoded address\n"
615  " \"txid\" (string) The related txid\n"
616  " \"index\" (number) The related input or output index\n"
617  " \"satoshis\" (number) The difference of duffs\n"
618  " \"timestamp\" (number) The time the transaction entered the mempool (seconds)\n"
619  " \"prevtxid\" (string) The previous txid (if spending)\n"
620  " \"prevout\" (string) The previous transaction output index (if spending)\n"
621  " }\n"
622  "]\n"
623  "\nExamples:\n"
624  + HelpExampleCli("getaddressmempool", "'{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}'")
625  + HelpExampleRpc("getaddressmempool", "{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}")
626  );
627 
628  std::vector<std::pair<uint160, int> > addresses;
629 
630  if (!getAddressesFromParams(request.params, addresses)) {
631  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
632  }
633 
634  std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> > indexes;
635 
636  if (!mempool.getAddressIndex(addresses, indexes)) {
637  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
638  }
639 
640  std::sort(indexes.begin(), indexes.end(), timestampSort);
641 
642  UniValue result(UniValue::VARR);
643 
644  for (std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> >::iterator it = indexes.begin();
645  it != indexes.end(); it++) {
646 
647  std::string address;
648  if (!getAddressFromIndex(it->first.type, it->first.addressBytes, address)) {
649  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
650  }
651 
652  UniValue delta(UniValue::VOBJ);
653  delta.push_back(Pair("address", address));
654  delta.push_back(Pair("txid", it->first.txhash.GetHex()));
655  delta.push_back(Pair("index", (int)it->first.index));
656  delta.push_back(Pair("satoshis", it->second.amount));
657  delta.push_back(Pair("timestamp", it->second.time));
658  if (it->second.amount < 0) {
659  delta.push_back(Pair("prevtxid", it->second.prevhash.GetHex()));
660  delta.push_back(Pair("prevout", (int)it->second.prevout));
661  }
662  result.push_back(delta);
663  }
664 
665  return result;
666 }
667 
669 {
670  if (request.fHelp || request.params.size() != 1)
671  throw std::runtime_error(
672  "getaddressutxos\n"
673  "\nReturns all unspent outputs for an address (requires addressindex to be enabled).\n"
674  "\nArguments:\n"
675  "{\n"
676  " \"addresses\"\n"
677  " [\n"
678  " \"address\" (string) The base58check encoded address\n"
679  " ,...\n"
680  " ]\n"
681  "}\n"
682  "\nResult:\n"
683  "[\n"
684  " {\n"
685  " \"address\" (string) The address base58check encoded\n"
686  " \"txid\" (string) The output txid\n"
687  " \"outputIndex\" (number) The output index\n"
688  " \"script\" (string) The script hex encoded\n"
689  " \"satoshis\" (number) The number of duffs of the output\n"
690  " \"height\" (number) The block height\n"
691  " }\n"
692  "]\n"
693  "\nExamples:\n"
694  + HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}'")
695  + HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}")
696  );
697 
698  std::vector<std::pair<uint160, int> > addresses;
699 
700  if (!getAddressesFromParams(request.params, addresses)) {
701  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
702  }
703 
704  std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
705 
706  for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
707  if (!GetAddressUnspent((*it).first, (*it).second, unspentOutputs)) {
708  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
709  }
710  }
711 
712  std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort);
713 
714  UniValue result(UniValue::VARR);
715 
716  for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) {
717  UniValue output(UniValue::VOBJ);
718  std::string address;
719  if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) {
720  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
721  }
722 
723  output.push_back(Pair("address", address));
724  output.push_back(Pair("txid", it->first.txhash.GetHex()));
725  output.push_back(Pair("outputIndex", (int)it->first.index));
726  output.push_back(Pair("script", HexStr(it->second.script.begin(), it->second.script.end())));
727  output.push_back(Pair("satoshis", it->second.satoshis));
728  output.push_back(Pair("height", it->second.blockHeight));
729  result.push_back(output);
730  }
731 
732  return result;
733 }
734 
736 {
737  if (request.fHelp || request.params.size() != 1 || !request.params[0].isObject())
738  throw std::runtime_error(
739  "getaddressdeltas\n"
740  "\nReturns all changes for an address (requires addressindex to be enabled).\n"
741  "\nArguments:\n"
742  "{\n"
743  " \"addresses\"\n"
744  " [\n"
745  " \"address\" (string) The base58check encoded address\n"
746  " ,...\n"
747  " ]\n"
748  " \"start\" (number) The start block height\n"
749  " \"end\" (number) The end block height\n"
750  "}\n"
751  "\nResult:\n"
752  "[\n"
753  " {\n"
754  " \"satoshis\" (number) The difference of duffs\n"
755  " \"txid\" (string) The related txid\n"
756  " \"index\" (number) The related input or output index\n"
757  " \"blockindex\" (number) The related block index\n"
758  " \"height\" (number) The block height\n"
759  " \"address\" (string) The base58check encoded address\n"
760  " }\n"
761  "]\n"
762  "\nExamples:\n"
763  + HelpExampleCli("getaddressdeltas", "'{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}'")
764  + HelpExampleRpc("getaddressdeltas", "{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}")
765  );
766 
767 
768  UniValue startValue = find_value(request.params[0].get_obj(), "start");
769  UniValue endValue = find_value(request.params[0].get_obj(), "end");
770 
771  int start = 0;
772  int end = 0;
773 
774  if (startValue.isNum() && endValue.isNum()) {
775  start = startValue.get_int();
776  end = endValue.get_int();
777  if (end < start) {
778  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start");
779  }
780  }
781 
782  std::vector<std::pair<uint160, int> > addresses;
783 
784  if (!getAddressesFromParams(request.params, addresses)) {
785  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
786  }
787 
788  std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
789 
790  for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
791  if (start > 0 && end > 0) {
792  if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) {
793  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
794  }
795  } else {
796  if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) {
797  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
798  }
799  }
800  }
801 
802  UniValue result(UniValue::VARR);
803 
804  for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
805  std::string address;
806  if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) {
807  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
808  }
809 
810  UniValue delta(UniValue::VOBJ);
811  delta.push_back(Pair("satoshis", it->second));
812  delta.push_back(Pair("txid", it->first.txhash.GetHex()));
813  delta.push_back(Pair("index", (int)it->first.index));
814  delta.push_back(Pair("blockindex", (int)it->first.txindex));
815  delta.push_back(Pair("height", it->first.blockHeight));
816  delta.push_back(Pair("address", address));
817  result.push_back(delta);
818  }
819 
820  return result;
821 }
822 
824 {
825  if (request.fHelp || request.params.size() != 1)
826  throw std::runtime_error(
827  "getaddressbalance\n"
828  "\nReturns the balance for an address(es) (requires addressindex to be enabled).\n"
829  "\nArguments:\n"
830  "{\n"
831  " \"addresses\"\n"
832  " [\n"
833  " \"address\" (string) The base58check encoded address\n"
834  " ,...\n"
835  " ]\n"
836  "}\n"
837  "\nResult:\n"
838  "{\n"
839  " \"balance\" (string) The current balance in duffs\n"
840  " \"received\" (string) The total number of duffs received (including change)\n"
841  "}\n"
842  "\nExamples:\n"
843  + HelpExampleCli("getaddressbalance", "'{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}'")
844  + HelpExampleRpc("getaddressbalance", "{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}")
845  );
846 
847  std::vector<std::pair<uint160, int> > addresses;
848 
849  if (!getAddressesFromParams(request.params, addresses)) {
850  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
851  }
852 
853  std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
854 
855  for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
856  if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) {
857  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
858  }
859  }
860 
861  CAmount balance = 0;
862  CAmount received = 0;
863 
864  for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
865  if (it->second > 0) {
866  received += it->second;
867  }
868  balance += it->second;
869  }
870 
871  UniValue result(UniValue::VOBJ);
872  result.push_back(Pair("balance", balance));
873  result.push_back(Pair("received", received));
874 
875  return result;
876 
877 }
878 
880 {
881  if (request.fHelp || request.params.size() != 1)
882  throw std::runtime_error(
883  "getaddresstxids\n"
884  "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n"
885  "\nArguments:\n"
886  "{\n"
887  " \"addresses\"\n"
888  " [\n"
889  " \"address\" (string) The base58check encoded address\n"
890  " ,...\n"
891  " ]\n"
892  " \"start\" (number) The start block height\n"
893  " \"end\" (number) The end block height\n"
894  "}\n"
895  "\nResult:\n"
896  "[\n"
897  " \"transactionid\" (string) The transaction id\n"
898  " ,...\n"
899  "]\n"
900  "\nExamples:\n"
901  + HelpExampleCli("getaddresstxids", "'{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}'")
902  + HelpExampleRpc("getaddresstxids", "{\"addresses\": [\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\"]}")
903  );
904 
905  std::vector<std::pair<uint160, int> > addresses;
906 
907  if (!getAddressesFromParams(request.params, addresses)) {
908  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
909  }
910 
911  int start = 0;
912  int end = 0;
913  if (request.params[0].isObject()) {
914  UniValue startValue = find_value(request.params[0].get_obj(), "start");
915  UniValue endValue = find_value(request.params[0].get_obj(), "end");
916  if (startValue.isNum() && endValue.isNum()) {
917  start = startValue.get_int();
918  end = endValue.get_int();
919  }
920  }
921 
922  std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
923 
924  for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
925  if (start > 0 && end > 0) {
926  if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) {
927  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
928  }
929  } else {
930  if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) {
931  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
932  }
933  }
934  }
935 
936  std::set<std::pair<int, std::string> > txids;
937  UniValue result(UniValue::VARR);
938 
939  for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
940  int height = it->first.blockHeight;
941  std::string txid = it->first.txhash.GetHex();
942 
943  if (addresses.size() > 1) {
944  txids.insert(std::make_pair(height, txid));
945  } else {
946  if (txids.insert(std::make_pair(height, txid)).second) {
947  result.push_back(txid);
948  }
949  }
950  }
951 
952  if (addresses.size() > 1) {
953  for (std::set<std::pair<int, std::string> >::const_iterator it=txids.begin(); it!=txids.end(); it++) {
954  result.push_back(it->second);
955  }
956  }
957 
958  return result;
959 
960 }
961 
963 {
964  if (request.fHelp || request.params.size() != 1 || !request.params[0].isObject())
965  throw std::runtime_error(
966  "getspentinfo\n"
967  "\nReturns the txid and index where an output is spent.\n"
968  "\nArguments:\n"
969  "{\n"
970  " \"txid\" (string) The hex string of the txid\n"
971  " \"index\" (number) The start block height\n"
972  "}\n"
973  "\nResult:\n"
974  "{\n"
975  " \"txid\" (string) The transaction id\n"
976  " \"index\" (number) The spending input index\n"
977  " ,...\n"
978  "}\n"
979  "\nExamples:\n"
980  + HelpExampleCli("getspentinfo", "'{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}'")
981  + HelpExampleRpc("getspentinfo", "{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}")
982  );
983 
984  UniValue txidValue = find_value(request.params[0].get_obj(), "txid");
985  UniValue indexValue = find_value(request.params[0].get_obj(), "index");
986 
987  if (!txidValue.isStr() || !indexValue.isNum()) {
988  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid txid or index");
989  }
990 
991  uint256 txid = ParseHashV(txidValue, "txid");
992  int outputIndex = indexValue.get_int();
993 
994  CSpentIndexKey key(txid, outputIndex);
995  CSpentIndexValue value;
996 
997  if (!GetSpentIndex(key, value)) {
998  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info");
999  }
1000 
1001  UniValue obj(UniValue::VOBJ);
1002  obj.push_back(Pair("txid", value.txid.GetHex()));
1003  obj.push_back(Pair("index", (int)value.inputIndex));
1004  obj.push_back(Pair("height", value.blockHeight));
1005 
1006  return obj;
1007 }
1008 
1010 {
1012  UniValue obj(UniValue::VOBJ);
1013  obj.push_back(Pair("used", uint64_t(stats.used)));
1014  obj.push_back(Pair("free", uint64_t(stats.free)));
1015  obj.push_back(Pair("total", uint64_t(stats.total)));
1016  obj.push_back(Pair("locked", uint64_t(stats.locked)));
1017  obj.push_back(Pair("chunks_used", uint64_t(stats.chunks_used)));
1018  obj.push_back(Pair("chunks_free", uint64_t(stats.chunks_free)));
1019  return obj;
1020 }
1021 
1022 #ifdef HAVE_MALLOC_INFO
1023 static std::string RPCMallocInfo()
1024 {
1025  char *ptr = nullptr;
1026  size_t size = 0;
1027  FILE *f = open_memstream(&ptr, &size);
1028  if (f) {
1029  malloc_info(0, f);
1030  fclose(f);
1031  if (ptr) {
1032  std::string rv(ptr, size);
1033  free(ptr);
1034  return rv;
1035  }
1036  }
1037  return "";
1038 }
1039 #endif
1040 
1042 {
1043  /* Please, avoid using the word "pool" here in the RPC interface or help,
1044  * as users will undoubtedly confuse it with the other "memory pool"
1045  */
1046  if (request.fHelp || request.params.size() > 1)
1047  throw std::runtime_error(
1048  "getmemoryinfo (\"mode\")\n"
1049  "Returns an object containing information about memory usage.\n"
1050  "\nArguments:\n"
1051  "1. \"mode\" (string, optional, default: \"stats\") Determines what kind of information is returned.\n"
1052  " - \"stats\" returns general statistics about memory usage in the daemon.\n"
1053  " - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc 2.10+).\n"
1054  "\nResult (mode \"stats\"):\n"
1055  "{\n"
1056  " \"locked\": { (json object) Information about locked memory manager\n"
1057  " \"used\": xxxxx, (numeric) Number of bytes used\n"
1058  " \"free\": xxxxx, (numeric) Number of bytes available in current arenas\n"
1059  " \"total\": xxxxxxx, (numeric) Total number of bytes managed\n"
1060  " \"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"
1061  " \"chunks_used\": xxxxx, (numeric) Number allocated chunks\n"
1062  " \"chunks_free\": xxxxx, (numeric) Number unused chunks\n"
1063  " }\n"
1064  "}\n"
1065  "\nResult (mode \"mallocinfo\"):\n"
1066  "\"<malloc version=\"1\">...\"\n"
1067  "\nExamples:\n"
1068  + HelpExampleCli("getmemoryinfo", "")
1069  + HelpExampleRpc("getmemoryinfo", "")
1070  );
1071 
1072  std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str();
1073  if (mode == "stats") {
1074  UniValue obj(UniValue::VOBJ);
1075  obj.push_back(Pair("locked", RPCLockedMemoryInfo()));
1076  return obj;
1077  } else if (mode == "mallocinfo") {
1078 #ifdef HAVE_MALLOC_INFO
1079  return RPCMallocInfo();
1080 #else
1081  throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo is only available when compiled with glibc 2.10+");
1082 #endif
1083  } else {
1084  throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode);
1085  }
1086 }
1087 
1088 uint64_t getCategoryMask(UniValue cats) {
1089  cats = cats.get_array();
1090  uint64_t mask = 0;
1091  for (unsigned int i = 0; i < cats.size(); ++i) {
1092  uint64_t flag = 0;
1093  std::string cat = cats[i].get_str();
1094  if (!GetLogCategory(&flag, &cat)) {
1095  throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown logging category " + cat);
1096  }
1097  if (flag == BCLog::NONE) {
1098  return 0;
1099  }
1100  mask |= flag;
1101  }
1102  return mask;
1103 }
1104 
1106 {
1107  if (request.fHelp || request.params.size() > 2) {
1108  throw std::runtime_error(
1109  "logging ( <include> <exclude> )\n"
1110  "Gets and sets the logging configuration.\n"
1111  "When called without an argument, returns the list of categories with status that are currently being debug logged or not.\n"
1112  "When called with arguments, adds or removes categories from debug logging and return the lists above.\n"
1113  "The arguments are evaluated in order \"include\", \"exclude\".\n"
1114  "If an item is both included and excluded, it will thus end up being excluded.\n"
1115  "The valid logging categories are: " + ListLogCategories() + "\n"
1116  "In addition, the following are available as category names with special meanings:\n"
1117  " - \"all\", \"1\" : represent all logging categories.\n"
1118  " - \"dash\" activates all Dash-specific categories at once.\n"
1119  "To deactivate all categories at once you can specify \"all\" in <exclude>.\n"
1120  " - \"none\", \"0\" : even if other logging categories are specified, ignore all of them.\n"
1121  "\nArguments:\n"
1122  "1. \"include\" (array of strings, optional) A json array of categories to add debug logging\n"
1123  " [\n"
1124  " \"category\" (string) the valid logging category\n"
1125  " ,...\n"
1126  " ]\n"
1127  "2. \"exclude\" (array of strings, optional) A json array of categories to remove debug logging\n"
1128  " [\n"
1129  " \"category\" (string) the valid logging category\n"
1130  " ,...\n"
1131  " ]\n"
1132  "\nResult:\n"
1133  "{ (json object where keys are the logging categories, and values indicates its status\n"
1134  " \"category\": 0|1, (numeric) if being debug logged or not. 0:inactive, 1:active\n"
1135  " ...\n"
1136  "}\n"
1137  "\nExamples:\n"
1138  + HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"")
1139  + HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"")
1140  );
1141  }
1142 
1143  uint64_t originalLogCategories = logCategories;
1144  if (request.params[0].isArray()) {
1145  logCategories |= getCategoryMask(request.params[0]);
1146  }
1147 
1148  if (request.params[1].isArray()) {
1149  logCategories &= ~getCategoryMask(request.params[1]);
1150  }
1151 
1152  // Update libevent logging if BCLog::LIBEVENT has changed.
1153  // If the library version doesn't allow it, UpdateHTTPServerLogging() returns false,
1154  // in which case we should clear the BCLog::LIBEVENT flag.
1155  // Throw an error if the user has explicitly asked to change only the libevent
1156  // flag and it failed.
1157  uint64_t changedLogCategories = originalLogCategories ^ logCategories;
1158  if (changedLogCategories & BCLog::LIBEVENT) {
1161  if (changedLogCategories == BCLog::LIBEVENT) {
1162  throw JSONRPCError(RPC_INVALID_PARAMETER, "libevent logging cannot be updated when using libevent before v2.1.1.");
1163  }
1164  }
1165  }
1166 
1167  UniValue result(UniValue::VOBJ);
1168  std::vector<CLogCategoryActive> vLogCatActive = ListActiveLogCategories();
1169  for (const auto& logCatActive : vLogCatActive) {
1170  result.pushKV(logCatActive.category, logCatActive.active);
1171  }
1172 
1173  return result;
1174 }
1175 
1177 {
1178  if (request.fHelp)
1179  throw std::runtime_error(
1180  "echo|echojson \"message\" ...\n"
1181  "\nSimply echo back the input arguments. This command is for testing.\n"
1182  "\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in"
1183  "dash-cli and the GUI. There is no server-side difference."
1184  );
1185 
1186  return request.params;
1187 }
1188 
1190 {
1192  "getinfo\n"
1193  "\nThis call was removed in version 0.16.0. Use the appropriate fields from:\n"
1194  "- getblockchaininfo: blocks, difficulty, chain\n"
1195  "- getnetworkinfo: version, protocolversion, timeoffset, connections, proxy, relayfee, warnings\n"
1196  "- getwalletinfo: balance, privatesend_balance, keypoololdest, keypoolsize, paytxfee, unlocked_until, walletversion\n"
1197  "\ndash-cli has the option -getinfo to collect and format these in the old format."
1198  );
1199 }
1200 
1201 static const CRPCCommand commands[] =
1202 { // category name actor (function) argNames
1203  // --------------------- ------------------------ ----------------------- ----------
1204  { "control", "debug", &debug, {} },
1205  { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} },
1206  { "control", "logging", &logging, {"include", "exclude"}},
1207  { "util", "validateaddress", &validateaddress, {"address"} }, /* uses wallet if enabled */
1208  { "util", "createmultisig", &createmultisig, {"nrequired","keys"} },
1209  { "util", "verifymessage", &verifymessage, {"address","signature","message"} },
1210  { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
1211  { "blockchain", "getspentinfo", &getspentinfo, {"json"} },
1212 
1213  /* Address index */
1214  { "addressindex", "getaddressmempool", &getaddressmempool, {"addresses"} },
1215  { "addressindex", "getaddressutxos", &getaddressutxos, {"addresses"} },
1216  { "addressindex", "getaddressdeltas", &getaddressdeltas, {"addresses"} },
1217  { "addressindex", "getaddresstxids", &getaddresstxids, {"addresses"} },
1218  { "addressindex", "getaddressbalance", &getaddressbalance, {"addresses"} },
1219 
1220  /* Dash features */
1221  { "dash", "mnsync", &mnsync, {} },
1222  { "dash", "spork", &spork, {"arg0","value"} },
1223 
1224  /* Not shown in help */
1225  { "hidden", "setmocktime", &setmocktime, {"timestamp"}},
1226  { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
1227  { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
1228  { "hidden", "getinfo", &getinfo_deprecated, {}},
1229 };
1230 
1232 {
1233  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1234  t.appendCommand(commands[vcidx].name, &commands[vcidx]);
1235 }
void SwitchToNextAsset(CConnman &connman)
CTxMemPool mempool
bool isObject() const
Definition: univalue.h:85
CScript CreateMultisigRedeemscript(const int required, const std::vector< CPubKey > &pubkeys)
Definition: util.cpp:48
CPubKey AddrToPubKey(CKeyStore *const keystore, const std::string &addr_in)
Definition: util.cpp:27
std::string ListLogCategories()
Returns a string with the log categories.
Definition: util.cpp:322
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:80
CMasternodeSync masternodeSync
std::string ListActiveLogCategoriesString()
Returns a string with the list of active log categories.
Definition: util.cpp:352
bool UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman &connman)
UpdateSpork is used by the spork RPC command to set a new spork value, sign and broadcast the spork m...
Definition: spork.cpp:185
const std::vector< UniValue > & getValues() const
bool getAddressIndex(std::vector< std::pair< uint160, int > > &addresses, std::vector< std::pair< CMempoolAddressDeltaKey, CMempoolAddressDelta > > &results)
Definition: txmempool.cpp:525
std::vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
Dash RPC command dispatcher.
Definition: server.h:140
CKey GetKey()
Definition: base58.cpp:304
bool GetAddressUnspent(uint160 addressHash, int type, std::vector< std::pair< CAddressUnspentKey, CAddressUnspentValue > > &unspentOutputs)
Definition: validation.cpp:934
static LockedPoolManager & Instance()
Return the current instance, or create it once.
Definition: lockedpool.h:213
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:906
CCriticalSection cs_wallet
Definition: wallet.h:836
Definition: util.h:107
unsigned int inputIndex
Definition: spentindex.h:44
#define strprintf
Definition: tinyformat.h:1066
bool EnsureWalletIsAvailable(CWallet *const pwallet, bool avoidException)
Definition: rpcwallet.cpp:66
bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
Definition: keystore.cpp:90
void SetMockTime(int64_t nMockTimeIn)
For testing.
Definition: utiltime.cpp:46
SporkId GetSporkIDByName(const std::string &strName)
GetSporkIDByName returns the internal Spork ID given the spork name.
Definition: spork.cpp:235
CCriticalSection cs_main
Definition: validation.cpp:213
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:281
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:336
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
uint256 GetID() const
Definition: hdchain.h:110
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:14
const std::string & get_str() const
bool isNum() const
Definition: univalue.h:83
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:583
const UniValue & get_array() const
bool isStr() const
Definition: univalue.h:82
UniValue verifymessage(const JSONRPCRequest &request)
Definition: misc.cpp:402
int64_t get_int64() const
bool pushKVs(const UniValue &obj)
Definition: univalue.cpp:148
int64_t GetAssetStartTime()
UniValue getaddressbalance(const JSONRPCRequest &request)
Definition: misc.cpp:823
bool IsBlockchainSynced()
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:353
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:149
const std::string strMessageMagic
Definition: validation.cpp:257
void RPCTypeCheck(const UniValue &params, const std::list< UniValue::VType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: server.cpp:54
UniValue debug(const JSONRPCRequest &request)
Definition: misc.cpp:42
std::map< CScriptID, CKeyMetadata > m_script_metadata
Definition: wallet.h:856
Invalid, missing or duplicate parameter.
Definition: protocol.h:53
UniValue createmultisig(const JSONRPCRequest &request)
Definition: misc.cpp:337
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: server.cpp:121
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
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:221
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
Parse a standard scriptPubKey with one or more destination addresses.
Definition: standard.cpp:188
bool SetString(const char *pszSecret)
Definition: base58.cpp:319
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
iterator end()
Definition: prevector.h:320
#define LOCK2(cs1, cs2)
Definition: sync.h:179
std::string name
Definition: server.h:132
void push_back(const T &value)
Definition: prevector.h:455
UniValue spork(const JSONRPCRequest &request)
Definition: misc.cpp:165
bool push_back(const UniValue &val)
Definition: univalue.cpp:110
bool MineBlocksOnDemand() const
Make miner stop after a block is found.
Definition: chainparams.h:68
UniValue params
Definition: server.h:42
bool GetLogCategory(uint64_t *f, const std::string *str)
Return true if str parses as a log category and set the flags in f.
Definition: util.cpp:291
isminetype
IsMine() return codes.
Definition: ismine.h:17
std::atomic< uint64_t > logCategories
#define LOCK(cs)
Definition: sync.h:178
A base58-encoded secret key.
Definition: base58.h:101
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:186
static UniValue getinfo_deprecated(const JSONRPCRequest &request)
Definition: misc.cpp:1189
std::string GetAssetName()
An encapsulated public key.
Definition: pubkey.h:30
virtual bool GetHDChain(CHDChain &hdChainRet) const override
Definition: crypter.cpp:539
bool IsHex(const std::string &str)
Unexpected type was passed as parameter.
Definition: protocol.h:50
const char * GetTxnOutputType(txnouttype t)
Get the name of a txnouttype as a C string, or nullptr if unknown.
Definition: standard.cpp:21
int64_t GetSporkValue(SporkId nSporkID)
GetSporkValue returns the spork value given a Spork ID.
Definition: spork.cpp:217
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:135
UniValue getaddressdeltas(const JSONRPCRequest &request)
Definition: misc.cpp:735
int get_int() const
Invalid address or key.
Definition: protocol.h:51
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:256
SporkId
Definition: spork.h:23
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:578
bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
Definition: validation.cpp:908
static std::pair< std::string, UniValue > Pair(const char *cKey, const char *cVal)
Definition: univalue.h:185
UniValue getaddresstxids(const JSONRPCRequest &request)
Definition: misc.cpp:879
int64_t nCreateTime
Definition: walletdb.h:64
static const CRPCCommand commands[]
Definition: misc.cpp:1201
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:447
bool isNull() const
Definition: univalue.h:78
UniValue setmocktime(const JSONRPCRequest &request)
Definition: misc.cpp:500
static UniValue RPCLockedMemoryInfo()
Definition: misc.cpp:1009
UniValue validateaddress(const JSONRPCRequest &request)
Definition: misc.cpp:238
UniValue getmemoryinfo(const JSONRPCRequest &request)
Definition: misc.cpp:1041
UniValue getaddressutxos(const JSONRPCRequest &request)
Definition: misc.cpp:668
UniValue signmessagewithprivkey(const JSONRPCRequest &request)
Definition: misc.cpp:458
bool heightSort(std::pair< CAddressUnspentKey, CAddressUnspentValue > a, std::pair< CAddressUnspentKey, CAddressUnspentValue > b)
Definition: misc.cpp:587
constexpr T mask
Definition: bits.hpp:45
UniValue mnsync(const JSONRPCRequest &request)
Definition: misc.cpp:82
CSporkManager sporkManager
Definition: spork.cpp:29
uint256 GetHash()
Definition: hash.h:203
bool fHelp
Definition: server.h:43
txnouttype
Definition: standard.h:56
256-bit opaque blob.
Definition: uint256.h:123
#define ARRAYLEN(array)
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:329
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:389
std::map< CKeyID, CHDPubKey > mapHdPubKeys
Definition: wallet.h:912
void RegisterMiscRPCCommands(CRPCTable &t)
Register miscellaneous RPC commands.
Definition: misc.cpp:1231
const UniValue & get_obj() const
uint64_t getCategoryMask(UniValue cats)
Definition: misc.cpp:1088
UniValue getaddressmempool(const JSONRPCRequest &request)
Definition: misc.cpp:597
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
UniValue logging(const JSONRPCRequest &request)
Definition: misc.cpp:1105
std::string GetHex() const
Definition: uint256.cpp:21
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:715
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
160-bit opaque blob.
Definition: uint256.h:112
const UniValue NullUniValue
Definition: univalue.cpp:15
CWallet * GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: rpcwallet.cpp:45
std::map< CKeyID, CKeyMetadata > mapKeyMetadata
Definition: wallet.h:853
iterator begin()
Definition: prevector.h:318
bool GetAddressIndex(uint160 addressHash, int type, std::vector< std::pair< CAddressIndexKey, CAmount > > &addressIndex, int start, int end)
Definition: validation.cpp:922
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:22
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:184
bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address)
Definition: misc.cpp:527
std::vector< CSporkDef > sporkDefs
Definition: spork.cpp:19
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:54
No valid connection manager instance found.
Definition: protocol.h:74
size_t size() const
Definition: univalue.h:69
An encapsulated private key.
Definition: key.h:27
bool IsSporkActive(SporkId nSporkID)
IsSporkActive returns a bool for time-based sporks, and should be used to determine whether the spork...
Definition: spork.cpp:211
Stats stats() const
Get pool usage statistics.
Definition: lockedpool.cpp:305
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
GetPubKey implementation that also checks the mapHdPubKeys.
Definition: wallet.cpp:286
UniValue getspentinfo(const JSONRPCRequest &request)
Definition: misc.cpp:962
UniValue echo(const JSONRPCRequest &request)
Definition: misc.cpp:1176
bool isArray() const
Definition: univalue.h:84
bool getAddressesFromParams(const UniValue &params, std::vector< std::pair< uint160, int > > &addresses)
Definition: misc.cpp:553
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: ismine.cpp:28
std::vector< CLogCategoryActive > ListActiveLogCategories()
Returns a vector of the active log categories.
Definition: util.cpp:337
bool getIndexKey(const std::string &str, uint160 &hashBytes, int &type)
Definition: misc.cpp:539
bool timestampSort(std::pair< CMempoolAddressDeltaKey, CMempoolAddressDelta > a, std::pair< CMempoolAddressDeltaKey, CMempoolAddressDelta > b)
Definition: misc.cpp:592
std::string EncodeBase64(const unsigned char *pch, size_t len)
bool UpdateHTTPServerLogging(bool enable)
Change logging level for libevent.
Definition: httpserver.cpp:413
Memory statistics.
Definition: lockedpool.h:136
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:93
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:174
void Reset(bool fForce=false, bool fNotifyReset=true)
Released under the MIT license