PIVX Core  5.6.99
P2P Digital Currency
blockchain.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2014-2015 The Dash developers
4 // Copyright (c) 2015-2022 The PIVX Core developers
5 // Distributed under the MIT software license, see the accompanying
6 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
7 
8 #include "budget/budgetmanager.h"
9 #include "chainparams.h"
10 #include "checkpoints.h"
11 #include "clientversion.h"
12 #include "consensus/upgrades.h"
13 #include "core_io.h"
14 #include "hash.h"
15 #include "kernel.h"
16 #include "key_io.h"
18 #include "masternodeman.h"
19 #include "policy/feerate.h"
20 #include "policy/policy.h"
21 #include "rpc/server.h"
22 #include "script/descriptor.h"
23 #include "sync.h"
24 #include "txdb.h"
25 #include "util/system.h"
26 #include "utilmoneystr.h"
27 #include "utilstrencodings.h"
28 #include "validation.h"
29 #include "validationinterface.h"
30 #include "wallet/wallet.h"
31 #include "warnings.h"
32 
33 #include <stdint.h>
34 #include <univalue.h>
35 #include <numeric>
36 #include <condition_variable>
37 
38 #include <boost/thread/thread.hpp> // boost::thread::interrupt
39 
40 
42 {
44  int height;
45 };
46 static std::mutex cs_blockchange;
47 static std::condition_variable cond_blockchange;
48 static CUpdatedBlock latestblock;
49 
50 extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const CBlockIndex* tip, const CBlockIndex* blockindex, UniValue& entry);
51 
53 {
54  if (request.fHelp || request.params.size() > 0) {
55  throw std::runtime_error(
56  "syncwithvalidationinterfacequeue\n"
57  "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n"
58  "\nExamples:\n"
59  + HelpExampleCli("syncwithvalidationinterfacequeue","")
60  + HelpExampleRpc("syncwithvalidationinterfacequeue","")
61  );
62  }
64  return NullUniValue;
65 }
66 
67 double GetDifficulty(const CBlockIndex* blockindex)
68 {
69  // Floating point number that is a multiple of the minimum difficulty,
70  // minimum difficulty = 1.0.
71  if (blockindex == nullptr) {
72  const CBlockIndex* pChainTip = GetChainTip();
73  if (!pChainTip)
74  return 1.0;
75  else
76  blockindex = pChainTip;
77  }
78 
79  int nShift = (blockindex->nBits >> 24) & 0xff;
80 
81  double dDiff =
82  (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
83 
84  while (nShift < 29) {
85  dDiff *= 256.0;
86  nShift++;
87  }
88  while (nShift > 29) {
89  dDiff /= 256.0;
90  nShift--;
91  }
92 
93  return dDiff;
94 }
95 
96 static UniValue ValuePoolDesc(
97  const Optional<CAmount> chainValue,
98  const Optional<CAmount> valueDelta)
99 {
101  rv.pushKV("chainValue", ValueFromAmount(chainValue ? *chainValue : 0));
102  rv.pushKV("valueDelta", ValueFromAmount(valueDelta ? *valueDelta : 0));
103  return rv;
104 }
105 
106 int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
107 {
108  next = tip->GetAncestor(blockindex->nHeight + 1);
109  if (next && next->pprev == blockindex) {
110  return tip->nHeight - blockindex->nHeight + 1;
111  }
112  next = nullptr;
113  return blockindex == tip ? 1 : -1;
114 }
115 
116 UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
117 {
118  UniValue result(UniValue::VOBJ);
119  result.pushKV("hash", blockindex->GetBlockHash().GetHex());
120  const CBlockIndex* pnext;
121  int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
122  result.pushKV("confirmations", confirmations);
123  result.pushKV("height", blockindex->nHeight);
124  result.pushKV("version", blockindex->nVersion);
125  result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex());
126  result.pushKV("time", (int64_t)blockindex->nTime);
127  result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast());
128  result.pushKV("nonce", (uint64_t)blockindex->nNonce);
129  result.pushKV("bits", strprintf("%08x", blockindex->nBits));
130  result.pushKV("difficulty", GetDifficulty(blockindex));
131  result.pushKV("chainwork", blockindex->nChainWork.GetHex());
132  result.pushKV("acc_checkpoint", blockindex->nAccumulatorCheckpoint.GetHex());
133  // Sapling shield pool value
134  result.pushKV("shield_pool_value", ValuePoolDesc(blockindex->nChainSaplingValue, blockindex->nSaplingValue));
135  if (blockindex->pprev)
136  result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
137  if (pnext)
138  result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
139  result.pushKV("chainlock", llmq::chainLocksHandler->HasChainLock(blockindex->nHeight, blockindex->GetBlockHash()));
140  return result;
141 }
142 
143 UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false)
144 {
145  UniValue result(UniValue::VOBJ);
146  result.pushKV("hash", block.GetHash().GetHex());
147  const CBlockIndex* pnext;
148  int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
149  result.pushKV("confirmations", confirmations);
150  result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
151  result.pushKV("height", blockindex->nHeight);
152  result.pushKV("version", block.nVersion);
153  result.pushKV("merkleroot", block.hashMerkleRoot.GetHex());
154  result.pushKV("acc_checkpoint", block.nAccumulatorCheckpoint.GetHex());
155  result.pushKV("finalsaplingroot", block.hashFinalSaplingRoot.GetHex());
157  for (const auto& txIn : block.vtx) {
158  const CTransaction& tx = *txIn;
159  if (txDetails) {
160  UniValue objTx(UniValue::VOBJ);
161  TxToJSON(nullptr, tx, nullptr, nullptr, objTx);
162  txs.push_back(objTx);
163  } else
164  txs.push_back(tx.GetHash().GetHex());
165  }
166  result.pushKV("tx", txs);
167  result.pushKV("time", block.GetBlockTime());
168  result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast());
169  result.pushKV("nonce", (uint64_t)block.nNonce);
170  result.pushKV("bits", strprintf("%08x", block.nBits));
171  result.pushKV("difficulty", GetDifficulty(blockindex));
172  result.pushKV("chainwork", blockindex->nChainWork.GetHex());
173 
174  if (blockindex->pprev)
175  result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
176  if (pnext)
177  result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
178 
182  if (block.IsProofOfStake()) {
183  uint256 hashProofOfStakeRet{UINT256_ZERO};
184  if (blockindex->pprev && !GetStakeKernelHash(hashProofOfStakeRet, block, blockindex->pprev))
185  throw JSONRPCError(RPC_INTERNAL_ERROR, "Cannot get proof of stake hash");
186 
187  std::string stakeModifier = (Params().GetConsensus().NetworkUpgradeActive(blockindex->nHeight, Consensus::UPGRADE_V3_4) ?
188  blockindex->GetStakeModifierV2().GetHex() :
189  strprintf("%016x", blockindex->GetStakeModifierV1()));
190  result.pushKV("stakeModifier", stakeModifier);
191  result.pushKV("hashProofOfStake", hashProofOfStakeRet.GetHex());
192  }
193  result.pushKV("chainlock", llmq::chainLocksHandler->HasChainLock(blockindex->nHeight, blockindex->GetBlockHash()));
194 
195  return result;
196 }
197 
199 {
200  if (request.fHelp || request.params.size() != 0)
201  throw std::runtime_error(
202  "getblockcount\n"
203  "\nReturns the number of blocks in the longest block chain.\n"
204 
205  "\nResult:\n"
206  "n (numeric) The current block count\n"
207 
208  "\nExamples:\n" +
209  HelpExampleCli("getblockcount", "") + HelpExampleRpc("getblockcount", ""));
210 
211  LOCK(cs_main);
212  return chainActive.Height();
213 }
214 
216 {
217  if (request.fHelp || request.params.size() != 0)
218  throw std::runtime_error(
219  "getbestblockhash\n"
220  "\nReturns the hash of the best (tip) block in the longest block chain.\n"
221 
222  "\nResult\n"
223  "\"hex\" (string) the block hash hex encoded\n"
224 
225  "\nExamples\n" +
226  HelpExampleCli("getbestblockhash", "") + HelpExampleRpc("getbestblockhash", ""));
227 
228  LOCK(cs_main);
229  return chainActive.Tip()->GetBlockHash().GetHex();
230 }
231 
233 {
234  if (request.fHelp || request.params.size() != 0)
235  throw std::runtime_error(
236  "getbestsaplinganchor\n"
237  "\nReturns the most recent SaplingMerkleTree root.\n"
238 
239  "\nResult\n"
240  "\"hex\" (string) the sapling anchor hex encoded\n"
241 
242  "\nExamples\n" +
243  HelpExampleCli("getbestsaplinganchor", "") + HelpExampleRpc("getbestsaplinganchor", ""));
244 
245  return pcoinsTip->GetBestAnchor().ToString();
246 }
247 
249 {
250  if (request.fHelp || request.params.size() != 0)
251  throw std::runtime_error(
252  "getbestchainlock\n"
253  "\nReturns the block hash of the best chainlock. Throws an error if there is no known chainlock yet.\n"
254  "\nResult:\n"
255  "{\n"
256  " \"blockhash\" : \"hash\", (string) The block hash hex encoded\n"
257  " \"height\" : n, (numeric) The block height or index\n"
258  " \"known_block\" : true|false (boolean) True if the block is known by our node\n"
259  "}\n"
260  "\nExamples:\n" +
261  HelpExampleCli("getbestchainlock", "") + HelpExampleRpc("getbestchainlock", ""));
262  UniValue result(UniValue::VOBJ);
263  llmq::CChainLockSig clsig = llmq::chainLocksHandler->GetBestChainLock();
264  if (clsig.IsNull()) {
265  throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to find any chainlock");
266  }
267  result.pushKV("blockhash", clsig.blockHash.GetHex());
268  result.pushKV("height", clsig.nHeight);
269  LOCK(cs_main);
270  result.pushKV("known_block", mapBlockIndex.count(clsig.blockHash) > 0);
271  return result;
272 }
273 
274 void RPCNotifyBlockChange(bool fInitialDownload, const CBlockIndex* pindex)
275 {
276  if(pindex) {
277  std::lock_guard<std::mutex> lock(cs_blockchange);
278  latestblock.hash = pindex->GetBlockHash();
279  latestblock.height = pindex->nHeight;
280  }
281  cond_blockchange.notify_all();
282 }
283 
285 {
286  if (request.fHelp || request.params.size() > 1)
287  throw std::runtime_error(
288  "waitfornewblock ( timeout )\n"
289  "\nWaits for a specific new block and returns useful info about it.\n"
290  "\nReturns the current block on timeout or exit.\n"
291 
292  "\nArguments:\n"
293  "1. timeout (numeric, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
294 
295  "\nResult:\n"
296  "{ (json object)\n"
297  " \"hash\": \"hash\", (string) The blockhash\n"
298  " \"height\": n (numeric) Block height\n"
299  "}\n"
300 
301  "\nExamples:\n"
302  + HelpExampleCli("waitfornewblock", "1000")
303  + HelpExampleRpc("waitfornewblock", "1000")
304  );
305  int timeout = 0;
306  if (request.params.size() > 0)
307  timeout = request.params[0].get_int();
308 
309  CUpdatedBlock block;
310  {
311  std::unique_lock<std::mutex> lock(cs_blockchange);
312  block = latestblock;
313  if(timeout)
314  cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
315  else
316  cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
317  block = latestblock;
318  }
320  ret.pushKV("hash", block.hash.GetHex());
321  ret.pushKV("height", block.height);
322  return ret;
323 }
324 
326 {
327  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
328  throw std::runtime_error(
329  "waitforblock blockhash ( timeout )\n"
330  "\nWaits for a specific new block and returns useful info about it.\n"
331  "\nReturns the current block on timeout or exit.\n"
332 
333  "\nArguments:\n"
334  "1. \"blockhash\" (string, required) Block hash to wait for.\n"
335  "2. timeout (numeric, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
336 
337  "\nResult:\n"
338  "{ (json object)\n"
339  " \"hash\": \"hash\", (string) The blockhash\n"
340  " \"height\": n (numeric) Block height\n"
341  "}\n"
342 
343  "\nExamples:\n"
344  + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
345  + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
346  );
347  int timeout = 0;
348 
349  uint256 hash(ParseHashV(request.params[0], "blockhash"));
350 
351  if (request.params.size() > 1)
352  timeout = request.params[1].get_int();
353 
354  CUpdatedBlock block;
355  {
356  std::unique_lock<std::mutex> lock(cs_blockchange);
357  if(timeout)
358  cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
359  else
360  cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); });
361  block = latestblock;
362  }
363 
365  ret.pushKV("hash", block.hash.GetHex());
366  ret.pushKV("height", block.height);
367  return ret;
368 }
369 
371 {
372  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
373  throw std::runtime_error(
374  "waitforblockheight height ( timeout )\n"
375  "\nWaits for (at least) block height and returns the height and hash\n"
376  "of the current tip.\n"
377  "\nReturns the current block on timeout or exit.\n"
378 
379  "\nArguments:\n"
380  "1. height (numeric, required) Block height to wait for\n"
381  "2. timeout (numeric, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
382 
383  "\nResult:\n"
384  "{ (json object)\n"
385  " \"hash\": \"hash\", (string) The blockhash\n"
386  " \"height\": n (int) Block height\n"
387  "}\n"
388 
389  "\nExamples:\n"
390  + HelpExampleCli("waitforblockheight", "\"100\", 1000")
391  + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
392  );
393  int timeout = 0;
394 
395  int height = request.params[0].get_int();
396 
397  if (request.params.size() > 1)
398  timeout = request.params[1].get_int();
399 
400  CUpdatedBlock block;
401  {
402  std::unique_lock<std::mutex> lock(cs_blockchange);
403  if(timeout)
404  cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
405  else
406  cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); });
407  block = latestblock;
408  }
410  ret.pushKV("hash", block.hash.GetHex());
411  ret.pushKV("height", block.height);
412  return ret;
413 }
414 
416 {
417  if (request.fHelp || request.params.size() != 0)
418  throw std::runtime_error(
419  "getdifficulty\n"
420  "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
421 
422  "\nResult:\n"
423  "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
424 
425  "\nExamples:\n" +
426  HelpExampleCli("getdifficulty", "") + HelpExampleRpc("getdifficulty", ""));
427 
428  LOCK(cs_main);
429  return GetDifficulty();
430 }
431 
432 static std::string EntryDescriptionString()
433 {
434  return " \"size\" : n, (numeric) transaction size in bytes\n"
435  " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
436  " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
437  " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
438  " \"height\" : n, (numeric) block height when transaction entered pool\n"
439  " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
440  " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
441  " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
442  " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
443  " \"transactionid\", (string) parent transaction id\n"
444  " ... ]\n";
445 }
446 
447 static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
448 {
450 
451  info.pushKV("size", (int)e.GetTxSize());
452  info.pushKV("fee", ValueFromAmount(e.GetFee()));
453  info.pushKV("modifiedfee", ValueFromAmount(e.GetModifiedFee()));
454  info.pushKV("time", e.GetTime());
455  info.pushKV("height", (int)e.GetHeight());
456  info.pushKV("descendantcount", e.GetCountWithDescendants());
457  info.pushKV("descendantsize", e.GetSizeWithDescendants());
458  info.pushKV("descendantfees", e.GetModFeesWithDescendants());
459  const CTransaction& tx = e.GetTx();
460  std::set<std::string> setDepends;
461  for (const CTxIn& txin : tx.vin) {
462  if (mempool.exists(txin.prevout.hash))
463  setDepends.insert(txin.prevout.hash.ToString());
464  }
465 
466  UniValue depends(UniValue::VARR);
467  for (const std::string& dep : setDepends) {
468  depends.push_back(dep);
469  }
470 
471  info.pushKV("depends", depends);
472 }
473 
474 UniValue mempoolToJSON(bool fVerbose = false)
475 {
476  if (fVerbose) {
477  LOCK(mempool.cs);
479  for (const CTxMemPoolEntry& e : mempool.mapTx) {
480  const uint256& hash = e.GetTx().GetHash();
481  UniValue info(UniValue::VOBJ);
482  entryToJSON(info, e);
483  o.pushKV(hash.ToString(), info);
484  }
485  return o;
486  } else {
487  std::vector<uint256> vtxid;
488  mempool.queryHashes(vtxid);
489 
491  for (const uint256& hash : vtxid)
492  a.push_back(hash.ToString());
493 
494  return a;
495  }
496 }
497 
499 {
500  if (request.fHelp || request.params.size() > 1)
501  throw std::runtime_error(
502  "getrawmempool ( verbose )\n"
503  "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
504 
505  "\nArguments:\n"
506  "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
507 
508  "\nResult: (for verbose = false):\n"
509  "[ (json array of string)\n"
510  " \"transactionid\" (string) The transaction id\n"
511  " ,...\n"
512  "]\n"
513 
514  "\nResult: (for verbose = true):\n"
515  "{ (json object)\n"
516  " \"transactionid\" : { (json object)\n"
517  + EntryDescriptionString()
518  + " }, ...\n"
519  "}\n"
520  "\nExamples\n" +
521  HelpExampleCli("getrawmempool", "true") + HelpExampleRpc("getrawmempool", "true"));
522 
523  LOCK(cs_main);
524 
525  bool fVerbose = false;
526  if (request.params.size() > 0)
527  fVerbose = request.params[0].get_bool();
528 
529  return mempoolToJSON(fVerbose);
530 }
531 
533 {
534  if (request.fHelp || request.params.size() != 1)
535  throw std::runtime_error(
536  "getblockhash height\n"
537  "\nReturns hash of block in best-block-chain at height provided.\n"
538 
539  "\nArguments:\n"
540  "1. height (numeric, required) The height index\n"
541 
542  "\nResult:\n"
543  "\"hash\" (string) The block hash\n"
544 
545  "\nExamples:\n" +
546  HelpExampleCli("getblockhash", "1000") + HelpExampleRpc("getblockhash", "1000"));
547 
548  LOCK(cs_main);
549 
550  int nHeight = request.params[0].get_int();
551  if (nHeight < 0 || nHeight > chainActive.Height())
552  throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
553 
554  CBlockIndex* pblockindex = chainActive[nHeight];
555  return pblockindex->GetBlockHash().GetHex();
556 }
557 
559 {
560  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
561  throw std::runtime_error(
562  "getblock \"blockhash\" ( verbosity )\n"
563  "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
564  "If verbosity is 1, returns an Object with information about block <hash>.\n"
565  "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.\n"
566 
567  "\nArguments:\n"
568  "1. \"blockhash\" (string, required) The block hash\n"
569  "2. verbosity (numeric, optional, default=1) 0 for hex encoded data, 1 for a json object, and 2 for json object with transaction data\n"
570 
571  "\nResult (for verbosity = 0):\n"
572  "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
573 
574  "\nResult (for verbosity = 1):\n"
575  "{\n"
576  " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
577  " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
578  " \"size\" : n, (numeric) The block size\n"
579  " \"height\" : n, (numeric) The block height or index\n"
580  " \"version\" : n, (numeric) The block version\n"
581  " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
582  " \"finalsaplingroot\" : \"xxxx\", (string) The root of the Sapling commitment tree after applying this block\n"
583  " \"tx\" : [ (array of string) The transaction ids\n"
584  " \"transactionid\" (string) The transaction id\n"
585  " ,...\n"
586  " ],\n"
587  " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
588  " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
589  " \"nonce\" : n, (numeric) The nonce\n"
590  " \"bits\" : \"1d00ffff\", (string) The bits\n"
591  " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
592  " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
593  " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
594  " \"stakeModifier\" : \"xxx\", (string) Proof of Stake modifier\n"
595  " \"hashProofOfStake\" : \"hash\", (string) Proof of Stake hash\n"
596  " }\n"
597  "}\n"
598 
599  "\nResult (for verbosity = 2):\n"
600  "{\n"
601  " ..., Same output as verbosity = 1.\n"
602  " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
603  " ,...\n"
604  " ],\n"
605  " ,... Same output as verbosity = 1.\n"
606  "}\n"
607 
608  "\nExamples:\n" +
609  HelpExampleCli("getblock", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") +
610  HelpExampleRpc("getblock", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\""));
611 
612  LOCK(cs_main);
613 
614  uint256 hash(ParseHashV(request.params[0], "blockhash"));
615 
616  int verbosity = 1;
617  if (!request.params[1].isNull()) {
618  if(request.params[1].isNum())
619  verbosity = request.params[1].get_int();
620  else
621  verbosity = request.params[1].get_bool() ? 1 : 0;
622  }
623 
624  CBlockIndex* pblockindex = LookupBlockIndex(hash);
625  if (pblockindex == nullptr)
626  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
627 
628  CBlock block;
629  if (!ReadBlockFromDisk(block, pblockindex))
630  throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
631 
632  if (verbosity <= 0) {
633  CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
634  ssBlock << block;
635  std::string strHex = HexStr(ssBlock);
636  return strHex;
637  }
638 
639  return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2);
640 }
641 
643 {
644  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
645  throw std::runtime_error(
646  "getblockheader \"blockhash\" ( verbose )\n"
647  "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash' header.\n"
648  "If verbose is true, returns an Object with information about block <hash> header.\n"
649 
650  "\nArguments:\n"
651  "1. \"blockhash\" (string, required) The block hash\n"
652  "2. verbose (boolean, optional, default=true) True for a json object, false for the hex encoded data\n"
653 
654  "\nResult (for verbose = true):\n"
655  "{\n"
656  " \"version\" : n, (numeric) The block version\n"
657  " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
658  " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
659  " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
660  " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
661  " \"nonce\" : n, (numeric) The nonce\n"
662  " \"bits\" : \"1d00ffff\", (string) The bits\n"
663  " \"shield_pool_value\": (object) Block shield pool value\n"
664  " {\n"
665  " \"chainValue\": (numeric) Total value held by the Sapling circuit up to and including this block\n"
666  " \"valueDelta\": (numeric) Change in value held by the Sapling circuit over this block\n"
667  " }\n"
668  "}"
669  "}\n"
670 
671  "\nResult (for verbose=false):\n"
672  "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash' header.\n"
673 
674  "\nExamples:\n" +
675  HelpExampleCli("getblockheader", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") +
676  HelpExampleRpc("getblockheader", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\""));
677 
678 
679  uint256 hash(ParseHashV(request.params[0], "blockhash"));
680 
681  bool fVerbose = true;
682  if (request.params.size() > 1)
683  fVerbose = request.params[1].get_bool();
684 
685  LOCK(cs_main);
686 
687  CBlockIndex* pblockindex = LookupBlockIndex(hash);
688  if (pblockindex == nullptr)
689  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
690 
691  if (!fVerbose) {
692  CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
693  ssBlock << pblockindex->GetBlockHeader();
694  std::string strHex = HexStr(ssBlock);
695  return strHex;
696  }
697 
698  return blockheaderToJSON(chainActive.Tip(), pblockindex);
699 }
700 
702 {
703  if (request.fHelp || request.params.size() > 1)
704  throw std::runtime_error(
705  "getsupplyinfo ( force_update )\n"
706  "\nIf force_update=false (default if no argument is given): return the last cached money supply"
707  "\n(sum of spendable transaction outputs) and the height of the chain when it was last updated"
708  "\n(it is updated periodically, whenever the chainstate is flushed)."
709  "\n"
710  "\nIf force_update=true: Flush the chainstate to disk and return the money supply updated to"
711  "\nthe current chain height.\n"
712 
713  "\nArguments:\n"
714  "1. force_update (boolean, optional, default=false) flush chainstate to disk and update cache\n"
715 
716  "\nResult:\n"
717  "{\n"
718  " \"updateheight\" : n, (numeric) The chain height when the transparent supply was updated\n"
719  " \"transparentsupply\" : n (numeric) The sum of all spendable transaction outputs at height updateheight\n"
720  " \"shieldsupply\": n (numeric) Chain tip shield pool value\n"
721  " \"totalsupply\": n (numeric) The sum of transparentsupply and shieldsupply\n"
722  "}\n"
723 
724  "\nExamples:\n" +
725  HelpExampleCli("getsupplyinfo", "") + HelpExampleCli("getsupplyinfo", "true") +
726  HelpExampleRpc("getsupplyinfo", ""));
727 
728  const bool fForceUpdate = request.params.size() > 0 ? request.params[0].get_bool() : false;
729 
730  if (fForceUpdate) {
731  // Flush state to disk (which updates the cached supply)
733  }
734 
736  const CAmount tSupply = MoneySupply.Get();
737  ret.pushKV("updateheight", MoneySupply.GetCacheHeight());
738  ret.pushKV("transparentsupply", ValueFromAmount(tSupply));
739  Optional<CAmount> shieldedPoolValue = WITH_LOCK(cs_main, return (chainActive.Tip() ? chainActive.Tip()->nChainSaplingValue : nullopt); );
740  ret.pushKV("shieldsupply", ValuePoolDesc(shieldedPoolValue, nullopt)["chainValue"]);
741  const CAmount totalSupply = tSupply + (shieldedPoolValue ? *shieldedPoolValue : 0);
742  ret.pushKV("totalsupply", ValueFromAmount(totalSupply));
743 
744  return ret;
745 }
746 
748 {
749  int nHeight{0};
751  uint64_t nTransactions{0};
752  uint64_t nTransactionOutputs{0};
754  uint64_t nDiskSize{0};
756 };
757 
758 static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
759 {
760  assert(!outputs.empty());
761  ss << hash;
762  const Coin& coin = outputs.begin()->second;
763  ss << VARINT(coin.nHeight * 4 + (coin.fCoinBase ? 2u : 0u) + (coin.fCoinStake ? 1u : 0u));
764  stats.nTransactions++;
765  for (const auto& output : outputs) {
766  ss << VARINT(output.first + 1);
767  ss << output.second.out.scriptPubKey;
768  ss << VARINT_MODE(output.second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED);
769  stats.nTransactionOutputs++;
770  stats.nTotalAmount += output.second.out.nValue;
771  }
772  ss << VARINT(0u);
773 }
774 
776 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
777 {
778  std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
779  assert(pcursor);
780 
781  CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
782  stats.hashBlock = pcursor->GetBestBlock();
783  {
784  LOCK(cs_main);
785  stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
786  }
787  ss << stats.hashBlock;
788  uint256 prevkey;
789  std::map<uint32_t, Coin> outputs;
790  while (pcursor->Valid()) {
791  boost::this_thread::interruption_point();
792  COutPoint key;
793  Coin coin;
794  if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
795  if (!outputs.empty() && key.hash != prevkey) {
796  ApplyStats(stats, ss, prevkey, outputs);
797  outputs.clear();
798  }
799  prevkey = key.hash;
800  outputs[key.n] = std::move(coin);
801  } else {
802  return error("%s: unable to read value", __func__);
803  }
804  pcursor->Next();
805  }
806  if (!outputs.empty()) {
807  ApplyStats(stats, ss, prevkey, outputs);
808  }
809  stats.hashSerialized = ss.GetHash();
810  stats.nDiskSize = view->EstimateSize();
811  return true;
812 }
813 
815 {
816  if (request.fHelp || request.params.size() != 0)
817  throw std::runtime_error(
818  "gettxoutsetinfo\n"
819  "\nReturns statistics about the unspent transaction output set.\n"
820  "Note this call may take some time.\n"
821 
822  "\nResult:\n"
823  "{\n"
824  " \"height\":n, (numeric) The current block height (index)\n"
825  " \"bestblock\": \"hex\", (string) the best block hash hex\n"
826  " \"transactions\": n, (numeric) The number of transactions\n"
827  " \"txouts\": n, (numeric) The number of output transactions\n"
828  " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
829  " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
830  " \"total_amount\": x.xxx (numeric) The total amount\n"
831  "}\n"
832 
833  "\nExamples:\n" +
834  HelpExampleCli("gettxoutsetinfo", "") + HelpExampleRpc("gettxoutsetinfo", ""));
835 
837 
838  CCoinsStats stats;
840  if (GetUTXOStats(pcoinsTip.get(), stats)) {
841  ret.pushKV("height", (int64_t)stats.nHeight);
842  ret.pushKV("bestblock", stats.hashBlock.GetHex());
843  ret.pushKV("transactions", (int64_t)stats.nTransactions);
844  ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs);
845  ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex());
846  ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount));
847  ret.pushKV("disk_size", stats.nDiskSize);
848  }
849  return ret;
850 }
851 
853 {
854  if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
855  throw std::runtime_error(
856  "gettxout \"txid\" n ( include_mempool )\n"
857  "\nReturns details about an unspent transaction output.\n"
858 
859  "\nArguments:\n"
860  "1. \"txid\" (string, required) The transaction id\n"
861  "2. n (numeric, required) vout value\n"
862  "3. include_mempool (boolean, optional) Whether to included the mem pool\n"
863 
864  "\nResult:\n"
865  "{\n"
866  " \"bestblock\" : \"hash\", (string) the block hash\n"
867  " \"confirmations\" : n, (numeric) The number of confirmations\n"
868  " \"value\" : x.xxx, (numeric) The transaction value in PIV\n"
869  " \"scriptPubKey\" : { (json object)\n"
870  " \"asm\" : \"code\", (string) \n"
871  " \"hex\" : \"hex\", (string) \n"
872  " \"reqSigs\" : n, (numeric) Number of required signatures\n"
873  " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
874  " \"addresses\" : [ (array of string) array of pivx addresses\n"
875  " \"pivxaddress\" (string) pivx address\n"
876  " ,...\n"
877  " ]\n"
878  " },\n"
879  " \"coinbase\" : true|false (boolean) Coinbase or not\n"
880  "}\n"
881 
882  "\nExamples:\n"
883  "\nGet unspent transactions\n" +
884  HelpExampleCli("listunspent", "") +
885  "\nView the details\n" +
886  HelpExampleCli("gettxout", "\"txid\" 1") +
887  "\nAs a json rpc call\n" +
888  HelpExampleRpc("gettxout", "\"txid\", 1"));
889 
890  LOCK(cs_main);
891 
893  uint256 hash(ParseHashV(request.params[0], "txid"));
894  int n = request.params[1].get_int();
895  COutPoint out(hash, n);
896  bool fMempool = true;
897  if (request.params.size() > 2)
898  fMempool = request.params[2].get_bool();
899 
900  Coin coin;
901  if (fMempool) {
902  LOCK(mempool.cs);
903  CCoinsViewMemPool view(pcoinsTip.get(), mempool);
904  if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {// TODO: filtering spent coins should be done by the CCoinsViewMemPool
905  return NullUniValue;
906  }
907  } else {
908  if (!pcoinsTip->GetCoin(out, coin)) {
909  return NullUniValue;
910  }
911  }
912 
913  CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock());
914  assert(pindex != nullptr);
915  ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
916  if (coin.nHeight == MEMPOOL_HEIGHT) {
917  ret.pushKV("confirmations", 0);
918  } else {
919  ret.pushKV("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1));
920  }
921  ret.pushKV("value", ValueFromAmount(coin.out.nValue));
923  ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
924  ret.pushKV("scriptPubKey", o);
925  ret.pushKV("coinbase", (bool)coin.fCoinBase);
926 
927  return ret;
928 }
929 
931 {
932  if (request.fHelp || request.params.size() > 1)
933  throw std::runtime_error(
934  "verifychain ( nblocks )\n"
935  "\nVerifies blockchain database.\n"
936 
937  "\nArguments:\n"
938  "1. nblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
939 
940  "\nResult:\n"
941  "true|false (boolean) Verified or not\n"
942 
943  "\nExamples:\n" +
944  HelpExampleCli("verifychain", "") + HelpExampleRpc("verifychain", ""));
945 
946  LOCK(cs_main);
947 
948  int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL);
949  int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
950  if (request.params.size() > 0)
951  nCheckDepth = request.params[0].get_int();
952 
953  return CVerifyDB().VerifyDB(pcoinsTip.get(), nCheckLevel, nCheckDepth);
954 }
955 
957 static UniValue SoftForkMajorityDesc(int version, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
958 {
961  switch(version) {
962  case 1:
963  case 2:
964  case 3:
966  break;
967  case 4:
968  idx = Consensus::UPGRADE_ZC;
969  break;
970  case 5:
972  break;
973  case 6:
975  break;
976  case 7:
978  break;
979  default:
980  rv.pushKV("status", false);
981  return rv;
982  }
983  rv.pushKV("status", pindex && consensusParams.NetworkUpgradeActive(pindex->nHeight, idx));
984  return rv;
985 }
986 
987 static UniValue SoftForkDesc(const std::string &name, int version, const CBlockIndex* pindex)
988 {
989  const Consensus::Params& consensus = Params().GetConsensus();
991  rv.pushKV("id", name);
992  rv.pushKV("version", version);
993  rv.pushKV("reject", SoftForkMajorityDesc(version, pindex, consensus));
994  return rv;
995 }
996 
997 static UniValue NetworkUpgradeDesc(const Consensus::Params& consensusParams, Consensus::UpgradeIndex idx, int height)
998 {
1000  auto upgrade = NetworkUpgradeInfo[idx];
1001  rv.pushKV("activationheight", consensusParams.vUpgrades[idx].nActivationHeight);
1002  switch (NetworkUpgradeState(height, consensusParams, idx)) {
1003  case UPGRADE_DISABLED: rv.pushKV("status", "disabled"); break;
1004  case UPGRADE_PENDING: rv.pushKV("status", "pending"); break;
1005  case UPGRADE_ACTIVE: rv.pushKV("status", "active"); break;
1006  }
1007  rv.pushKV("info", upgrade.strInfo);
1008  return rv;
1009 }
1010 
1012  UniValue& networkUpgrades,
1013  const Consensus::Params& consensusParams,
1015  int height)
1016 {
1017  // Network upgrades with an activation height of NO_ACTIVATION_HEIGHT are
1018  // hidden. This is used when network upgrade implementations are merged
1019  // without specifying the activation height.
1021  std::string name = NetworkUpgradeInfo[idx].strName;
1022  std::replace(name.begin(), name.end(), '_', ' '); // Beautify the name
1023  networkUpgrades.pushKV(name, NetworkUpgradeDesc(consensusParams, idx, height));
1024  }
1025 }
1026 
1028 {
1029  if (request.fHelp || request.params.size() != 0)
1030  throw std::runtime_error(
1031  "getblockchaininfo\n"
1032  "Returns an object containing various state info regarding block chain processing.\n"
1033 
1034  "\nResult:\n"
1035  "{\n"
1036  " \"chain\": \"xxxx\", (string) current network name (main, test, regtest)\n"
1037  " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1038  " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1039  " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1040  " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1041  " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1042  " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1043  " \"shield_pool_value\": { (object) Chain tip shield pool value\n"
1044  " \"chainValue\": (numeric) Total value held by the Sapling circuit up to and including the chain tip\n"
1045  " \"valueDelta\": (numeric) Change in value held by the Sapling circuit over the chain tip block\n"
1046  " },\n"
1047  " \"initial_block_downloading\": true|false, (boolean) whether the node is in initial block downloading state or not\n"
1048  " \"softforks\": [ (array) status of softforks in progress\n"
1049  " {\n"
1050  " \"id\": \"xxxx\", (string) name of softfork\n"
1051  " \"version\": xx, (numeric) block version\n"
1052  " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1053  " \"status\": xx, (boolean) true if threshold reached\n"
1054  " },\n"
1055  " }, ...\n"
1056  " ],\n"
1057  " \"upgrades\": { (object) status of network upgrades\n"
1058  " \"name\" : { (string) name of upgrade\n"
1059  " \"activationheight\": xxxxxx, (numeric) block height of activation\n"
1060  " \"status\": \"xxxx\", (string) status of upgrade\n"
1061  " \"info\": \"xxxx\", (string) additional information about upgrade\n"
1062  " }, ...\n"
1063  "}\n"
1064  " \"warnings\" : \"...\", (string) any network and blockchain warnings.\n"
1065 
1066  "\nExamples:\n" +
1067  HelpExampleCli("getblockchaininfo", "") + HelpExampleRpc("getblockchaininfo", ""));
1068 
1069  LOCK(cs_main);
1070 
1071  const Consensus::Params& consensusParams = Params().GetConsensus();
1072  const CBlockIndex* pChainTip = chainActive.Tip();
1073  int nTipHeight = pChainTip ? pChainTip->nHeight : -1;
1074 
1075  UniValue obj(UniValue::VOBJ);
1076  obj.pushKV("chain", Params().NetworkIDString());
1077  obj.pushKV("blocks", nTipHeight);
1078  obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1);
1079  obj.pushKV("bestblockhash", pChainTip ? pChainTip->GetBlockHash().GetHex() : "");
1080  obj.pushKV("difficulty", (double)GetDifficulty());
1081  obj.pushKV("verificationprogress", Checkpoints::GuessVerificationProgress(pChainTip));
1082  obj.pushKV("chainwork", pChainTip ? pChainTip->nChainWork.GetHex() : "");
1083  // Sapling shield pool value
1084  obj.pushKV("shield_pool_value", pChainTip ? ValuePoolDesc(pChainTip->nChainSaplingValue, pChainTip->nSaplingValue) : 0);
1085  obj.pushKV("initial_block_downloading", IsInitialBlockDownload());
1086  UniValue softforks(UniValue::VARR);
1087  softforks.push_back(SoftForkDesc("bip65", 5, pChainTip));
1088  obj.pushKV("softforks", softforks);
1089  UniValue upgrades(UniValue::VOBJ);
1090  for (int i = Consensus::BASE_NETWORK + 1; i < (int) Consensus::MAX_NETWORK_UPGRADES; i++) {
1091  NetworkUpgradeDescPushBack(upgrades, consensusParams, Consensus::UpgradeIndex(i), nTipHeight);
1092  }
1093  obj.pushKV("upgrades", upgrades);
1094  obj.pushKV("warnings", GetWarnings("statusbar"));
1095  return obj;
1096 }
1097 
1100  bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1101  {
1102  /* Make sure that unequal blocks with the same height do not compare
1103  equal. Use the pointers themselves to make a distinction. */
1104 
1105  if (a->nHeight != b->nHeight)
1106  return (a->nHeight > b->nHeight);
1107 
1108  return a < b;
1109  }
1110 };
1111 
1113 {
1114  if (request.fHelp || request.params.size() != 0)
1115  throw std::runtime_error(
1116  "getchaintips\n"
1117  "Return information about all known tips in the block tree,"
1118  " including the main chain as well as orphaned branches.\n"
1119 
1120  "\nResult:\n"
1121  "[\n"
1122  " {\n"
1123  " \"height\": xxxx, (numeric) height of the chain tip\n"
1124  " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1125  " \"branchlen\": 0 (numeric) zero for main chain\n"
1126  " \"status\": \"active\" (string) \"active\" for the main chain\n"
1127  " },\n"
1128  " {\n"
1129  " \"height\": n, (numeric) height of the chain tip\n"
1130  " \"hash\": \"hash\", (string) block hash of the tip\n"
1131  " \"branchlen\": n, (numeric) length of branch connecting the tip to the main chain\n"
1132  " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1133  " }\n"
1134  " ,...\n"
1135  "]\n"
1136 
1137  "Possible values for status:\n"
1138  "1. \"invalid\" This branch contains at least one invalid block\n"
1139  "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1140  "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1141  "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1142  "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1143 
1144  "\nExamples:\n" +
1145  HelpExampleCli("getchaintips", "") + HelpExampleRpc("getchaintips", ""));
1146 
1147  LOCK(cs_main);
1148 
1149  /* Build up a list of chain tips. We start with the list of all
1150  known blocks, and successively remove blocks that appear as pprev
1151  of another block. */
1152  std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1153  for (const std::pair<const uint256, CBlockIndex*> & item : mapBlockIndex)
1154  setTips.insert(item.second);
1155  for (const std::pair<const uint256, CBlockIndex*> & item : mapBlockIndex) {
1156  const CBlockIndex* pprev = item.second->pprev;
1157  if (pprev)
1158  setTips.erase(pprev);
1159  }
1160 
1161  // Always report the currently active tip.
1162  setTips.insert(chainActive.Tip());
1163 
1164  /* Construct the output array. */
1165  UniValue res(UniValue::VARR);
1166  for (const CBlockIndex* block : setTips) {
1167  UniValue obj(UniValue::VOBJ);
1168  obj.pushKV("height", block->nHeight);
1169  obj.pushKV("hash", block->phashBlock->GetHex());
1170 
1171  const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1172  obj.pushKV("branchlen", branchLen);
1173 
1174  std::string status;
1175  if (chainActive.Contains(block)) {
1176  // This block is part of the currently active chain.
1177  status = "active";
1178  } else if (block->nStatus & BLOCK_FAILED_MASK) {
1179  // This block or one of its ancestors is invalid.
1180  status = "invalid";
1181  } else if (block->nChainTx == 0) {
1182  // This block cannot be connected because full block data for it or one of its parents is missing.
1183  status = "headers-only";
1184  } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1185  // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1186  status = "valid-fork";
1187  } else if (block->IsValid(BLOCK_VALID_TREE)) {
1188  // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1189  status = "valid-headers";
1190  } else {
1191  // No clue.
1192  status = "unknown";
1193  }
1194  obj.pushKV("status", status);
1195 
1196  res.push_back(obj);
1197  }
1198 
1199  return res;
1200 }
1201 
1203 {
1204  UniValue ret(UniValue::VOBJ);
1205  ret.pushKV("loaded", mempool.IsLoaded());
1206  ret.pushKV("size", (int64_t) mempool.size());
1207  ret.pushKV("bytes", (int64_t) mempool.GetTotalTxSize());
1208  ret.pushKV("usage", (int64_t) mempool.DynamicMemoryUsage());
1209  size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1210  ret.pushKV("mempoolminfee", ValueFromAmount(std::max(mempool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
1211  ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
1212 
1213  return ret;
1214 }
1215 
1217 {
1218  if (request.fHelp || request.params.size() != 0)
1219  throw std::runtime_error(
1220  "getmempoolinfo\n"
1221  "\nReturns details on the active state of the TX memory pool.\n"
1222 
1223  "\nResult:\n"
1224  "{\n"
1225  " \"loaded\": true|false (boolean) True if the mempool is fully loaded\n"
1226  " \"size\": xxxxx (numeric) Current tx count\n"
1227  " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
1228  " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n"
1229  " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1230  " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee\n"
1231  " \"minrelaytxfee\": xxxxx (numeric) Current minimum relay fee for transactions\n"
1232  "}\n"
1233 
1234  "\nExamples:\n" +
1235  HelpExampleCli("getmempoolinfo", "") + HelpExampleRpc("getmempoolinfo", ""));
1236 
1237  return mempoolInfoToJSON();
1238 }
1239 
1241 {
1242  if (request.fHelp || request.params.size() != 1)
1243  throw std::runtime_error(
1244  "invalidateblock \"blockhash\"\n"
1245  "\nPermanently marks a block as invalid, as if it violated a consensus rule. Note: it might take up to some minutes and after calling it's recommended to run recover transactions. \n"
1246 
1247  "\nArguments:\n"
1248  "1. blockhash (string, required) the hash of the block to mark as invalid\n"
1249 
1250  "\nExamples:\n" +
1251  HelpExampleCli("invalidateblock", "\"blockhash\"") + HelpExampleRpc("invalidateblock", "\"blockhash\""));
1252 
1253  uint256 hash(ParseHashV(request.params[0], "blockhash"));
1254  CValidationState state;
1255 
1256  {
1257  LOCK(cs_main);
1258  if (mapBlockIndex.count(hash) == 0)
1259  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1260 
1261  CBlockIndex* pblockindex = mapBlockIndex[hash];
1262  // For each wallet in your wallet list
1263  std::string errString = "";
1264  for (auto* pwallet : vpwallets) {
1265  //Do we need to recreate the witnesscache or is the current one enough?
1266  if (pwallet->GetSaplingScriptPubKeyMan()->nWitnessCacheSize <= (chainActive.Height() - pblockindex->nHeight + 1)) {
1267  if (!pwallet->GetSaplingScriptPubKeyMan()->BuildWitnessChain(pblockindex, Params().GetConsensus(), errString)) {
1268  throw JSONRPCError(RPC_DATABASE_ERROR, errString);
1269  }
1270  }
1271  }
1272  InvalidateBlock(state, Params(), pblockindex);
1273  }
1274 
1275  if (state.IsValid()) {
1276  ActivateBestChain(state);
1277  int nHeight = WITH_LOCK(cs_main, return chainActive.Height(); );
1278  g_budgetman.SetBestHeight(nHeight);
1279  mnodeman.SetBestHeight(nHeight);
1280  }
1281 
1282  if (!state.IsValid()) {
1284  }
1285 
1286  return NullUniValue;
1287 }
1288 
1290 {
1291  if (request.fHelp || request.params.size() != 1)
1292  throw std::runtime_error(
1293  "reconsiderblock \"blockhash\"\n"
1294  "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1295  "This can be used to undo the effects of invalidateblock.\n"
1296 
1297  "\nArguments:\n"
1298  "1. blockhash (string, required) the hash of the block to reconsider\n"
1299 
1300  "\nExamples:\n" +
1301  HelpExampleCli("reconsiderblock", "\"blockhash\"") + HelpExampleRpc("reconsiderblock", "\"blockhash\""));
1302 
1303  uint256 hash(ParseHashV(request.params[0], "blockhash"));
1304  CValidationState state;
1305 
1306  {
1307  LOCK(cs_main);
1308  if (mapBlockIndex.count(hash) == 0)
1309  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1310 
1311  CBlockIndex* pblockindex = mapBlockIndex[hash];
1312  ReconsiderBlock(state, pblockindex);
1313  }
1314 
1315  if (state.IsValid()) {
1316  ActivateBestChain(state);
1317  int nHeight = WITH_LOCK(cs_main, return chainActive.Height(); );
1318  g_budgetman.SetBestHeight(nHeight);
1319  mnodeman.SetBestHeight(nHeight);
1320  }
1321 
1322  if (!state.IsValid()) {
1324  }
1325 
1326  return NullUniValue;
1327 }
1328 
1329 void validaterange(const UniValue& params, int& heightStart, int& heightEnd, int minHeightStart = 1)
1330 {
1331  if (params.size() < 2) {
1332  throw JSONRPCError(RPC_INVALID_PARAMETER, "Not enough parameters in validaterange");
1333  }
1334 
1335  int nBestHeight;
1336  {
1337  LOCK(cs_main);
1338  nBestHeight = chainActive.Height();
1339  }
1340 
1341  heightStart = params[0].get_int();
1342  if (heightStart > nBestHeight) {
1343  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid starting block (%d). Out of range.", heightStart));
1344  }
1345 
1346  const int range = params[1].get_int();
1347  if (range < 1) {
1348  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block range. Must be strictly positive.");
1349  }
1350 
1351  heightEnd = heightStart + range - 1;
1352 
1353  if (heightStart < minHeightStart && heightEnd >= minHeightStart) {
1354  heightStart = minHeightStart;
1355  }
1356 
1357  if (heightEnd > nBestHeight) {
1358  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid ending block (%d). Out of range.", heightEnd));
1359  }
1360 }
1361 
1363  if (request.fHelp || request.params.size() != 2)
1364  throw std::runtime_error(
1365  "getblockindexstats height range\n"
1366  "\nReturns aggregated BlockIndex data for blocks "
1367  "\n[height, height+1, height+2, ..., height+range-1]\n"
1368 
1369  "\nArguments:\n"
1370  "1. height (numeric, required) block height where the search starts.\n"
1371  "2. range (numeric, required) number of blocks to include.\n"
1372 
1373  "\nResult:\n"
1374  "{\n"
1375  " \"first_block\": \"x\" (integer) First counted block\n"
1376  " \"last_block\": \"x\" (integer) Last counted block\n"
1377  " \"txcount\": xxxxx (numeric) tx count (excluding coinbase/coinstake)\n"
1378  " \"txcount_all\": xxxxx (numeric) tx count (including coinbase/coinstake)\n"
1379  " \"txbytes\": xxxxx (numeric) Sum of the size of all txes over block range\n"
1380  " \"ttlfee\": xxxxx (numeric) Sum of the fee amount of all txes over block range\n"
1381  " \"feeperkb\": xxxxx (numeric) Average fee per kb (excluding zc txes)\n"
1382  "}\n"
1383 
1384  "\nExamples:\n" +
1385  HelpExampleCli("getblockindexstats", "1200000 1000") +
1386  HelpExampleRpc("getblockindexstats", "1200000, 1000"));
1387 
1388  int heightStart, heightEnd;
1389  validaterange(request.params, heightStart, heightEnd);
1390  // return object
1391  UniValue ret(UniValue::VOBJ);
1392  ret.pushKV("Starting block", heightStart);
1393  ret.pushKV("Ending block", heightEnd);
1394 
1395  CAmount nFees = 0;
1396  int64_t nBytes = 0;
1397  int64_t nTxCount = 0;
1398  int64_t nTxCount_all = 0;
1399 
1400  const CBlockIndex* pindex = WITH_LOCK(cs_main, return chainActive[heightEnd]);
1401  if (!pindex)
1402  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid block height");
1403 
1404  while (pindex && pindex->nHeight >= heightStart) {
1405  CBlock block;
1406  if (!ReadBlockFromDisk(block, pindex)) {
1407  throw JSONRPCError(RPC_DATABASE_ERROR, "failed to read block from disk");
1408  }
1409 
1410  CAmount nValueIn = 0;
1411  CAmount nValueOut = 0;
1412  const int ntx = block.vtx.size();
1413  const int firstTxIndex = block.IsProofOfStake() ? 2 : 1;
1414  nTxCount_all += ntx;
1415  nTxCount = nTxCount + ntx - firstTxIndex;
1416 
1417  // loop through each tx in block and save size and fee (except for coinbase/coinstake)
1418  for (int idx = firstTxIndex; idx < ntx; idx++) {
1419  const CTransaction& tx = *(block.vtx[idx]);
1420 
1421  // zerocoin txes have fixed fee, don't count them here.
1422  if (tx.ContainsZerocoins())
1423  continue;
1424 
1425  // Transaction size
1426  nBytes += GetSerializeSize(tx, CLIENT_VERSION);
1427 
1428  // Transparent inputs
1429  for (unsigned int j = 0; j < tx.vin.size(); j++) {
1430  COutPoint prevout = tx.vin[j].prevout;
1431  CTransactionRef txPrev;
1432  uint256 hashBlock;
1433  if(!GetTransaction(prevout.hash, txPrev, hashBlock, true))
1434  throw JSONRPCError(RPC_DATABASE_ERROR, "failed to read tx from disk");
1435  nValueIn += txPrev->vout[prevout.n].nValue;
1436  }
1437  // Shield inputs
1438  nValueIn += tx.GetShieldedValueIn();
1439 
1440  // Transparent/Shield outputs
1441  nValueOut += tx.GetValueOut();
1442 
1443  // update fee
1444  nFees += nValueIn - nValueOut;
1445  }
1446  pindex = pindex->pprev;
1447  }
1448 
1449  // get fee rate
1450  CFeeRate nFeeRate = CFeeRate(nFees, nBytes);
1451 
1452  // return UniValue object
1453  ret.pushKV("txcount", (int64_t)nTxCount);
1454  ret.pushKV("txcount_all", (int64_t)nTxCount_all);
1455  ret.pushKV("txbytes", (int64_t)nBytes);
1456  ret.pushKV("ttlfee", FormatMoney(nFees));
1457  ret.pushKV("feeperkb", FormatMoney(nFeeRate.GetFeePerK()));
1458 
1459  return ret;
1460 }
1461 
1463 {
1464  if (request.fHelp || request.params.size() != 1)
1465  throw std::runtime_error(
1466  "getfeeinfo blocks\n"
1467  "\nReturns details of transaction fees over the last n blocks.\n"
1468 
1469  "\nArguments:\n"
1470  "1. blocks (int, required) the number of blocks to get transaction data from\n"
1471 
1472  "\nResult:\n"
1473  "{\n"
1474  " \"txcount\": xxxxx (numeric) Current tx count\n"
1475  " \"txbytes\": xxxxx (numeric) Sum of all tx sizes\n"
1476  " \"ttlfee\": xxxxx (numeric) Sum of all fees\n"
1477  " \"feeperkb\": xxxxx (numeric) Average fee per kb over the block range\n"
1478  " \"rec_highpriorityfee_perkb\": xxxxx (numeric) Recommended fee per kb to use for a high priority tx\n"
1479  "}\n"
1480 
1481  "\nExamples:\n" +
1482  HelpExampleCli("getfeeinfo", "5") + HelpExampleRpc("getfeeinfo", "5"));
1483 
1484  int nBlocks = request.params[0].get_int();
1485  int nBestHeight;
1486  {
1487  LOCK(cs_main);
1488  nBestHeight = chainActive.Height();
1489  }
1490  int nStartHeight = nBestHeight - nBlocks;
1491  if (nBlocks < 0 || nStartHeight <= 0)
1492  throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid start height");
1493 
1494  JSONRPCRequest newRequest;
1495  UniValue newParams(UniValue::VARR);
1496  newParams.push_back(UniValue(nStartHeight));
1497  newParams.push_back(UniValue(nBlocks));
1498  newRequest.params = newParams;
1499 
1500  return getblockindexstats(newRequest);
1501 }
1502 
1504 bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>& should_abort, int64_t& count, CCoinsViewCursor* cursor, const std::set<CScript>& needles, std::map<COutPoint, Coin>& out_results) {
1505  scan_progress = 0;
1506  count = 0;
1507  while (cursor->Valid()) {
1508  COutPoint key;
1509  Coin coin;
1510  if (!cursor->GetKey(key) || !cursor->GetValue(coin)) return false;
1511  if (++count % 8192 == 0) {
1512  boost::this_thread::interruption_point();
1513  if (should_abort) {
1514  // allow to abort the scan via the abort reference
1515  return false;
1516  }
1517  }
1518  if (count % 256 == 0) {
1519  // update progress reference every 256 item
1520  uint32_t high = 0x100 * *key.hash.begin() + *(key.hash.begin() + 1);
1521  scan_progress = (int)(high * 100.0 / 65536.0 + 0.5);
1522  }
1523  if (needles.count(coin.out.scriptPubKey)) {
1524  out_results.emplace(key, coin);
1525  }
1526  cursor->Next();
1527  }
1528  scan_progress = 100;
1529  return true;
1530 }
1531 
1533 static std::mutex g_utxosetscan;
1534 static std::atomic<int> g_scan_progress;
1535 static std::atomic<bool> g_scan_in_progress;
1536 static std::atomic<bool> g_should_abort_scan;
1538 {
1539 private:
1541 public:
1543 
1544  bool reserve() {
1545  assert (!m_could_reserve);
1546  std::lock_guard<std::mutex> lock(g_utxosetscan);
1547  if (g_scan_in_progress) {
1548  return false;
1549  }
1550  g_scan_in_progress = true;
1551  m_could_reserve = true;
1552  return true;
1553  }
1554 
1556  if (m_could_reserve) {
1557  std::lock_guard<std::mutex> lock(g_utxosetscan);
1558  g_scan_in_progress = false;
1559  }
1560  }
1561 };
1562 
1564 {
1565  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1566  throw std::runtime_error(
1567  "scantxoutset <action> ( <scanobjects> )\n"
1568  "\nEXPERIMENTAL warning: this call may be removed or changed in future releases.\n"
1569  "\nScans the unspent transaction output set for entries that match certain output descriptors.\n"
1570  "Examples of output descriptors are:\n"
1571  " addr(<address>) Outputs whose scriptPubKey corresponds to the specified address (does not include P2PK)\n"
1572  " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n"
1573  " combo(<pubkey>) P2PK and P2PKH outputs for the given pubkey\n"
1574  " pkh(<pubkey>) P2PKH outputs for the given pubkey\n"
1575  " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"
1576  "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an DRKV/DRKP optionally followed by one\n"
1577  "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
1578  "unhardened or hardened child keys.\n"
1579  "In the latter case, a range needs to be specified by below if different from 1000.\n"
1580  "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"
1581  "\nArguments:\n"
1582  "1. \"action\" (string, required) The action to execute\n"
1583  " \"start\" for starting a scan\n"
1584  " \"abort\" for aborting the current scan (returns true when abort was successful)\n"
1585  " \"status\" for progress report (in %) of the current scan\n"
1586  "2. \"scanobjects\" (array, required) Array of scan objects\n"
1587  " [ Every scan object is either a string descriptor or an object:\n"
1588  " \"descriptor\", (string, optional) An output descriptor\n"
1589  " { (object, optional) An object with output descriptor and metadata\n"
1590  " \"desc\": \"descriptor\", (string, required) An output descriptor\n"
1591  " \"range\": n, (numeric, optional) Up to what child index HD chains should be explored (default: 1000)\n"
1592  " },\n"
1593  " ...\n"
1594  " ]\n"
1595  "\nResult:\n"
1596  "{\n"
1597  " \"unspents\": [\n"
1598  " {\n"
1599  " \"txid\" : \"transactionid\", (string) The transaction id\n"
1600  " \"vout\": n, (numeric) the vout value\n"
1601  " \"scriptPubKey\" : \"script\", (string) the script key\n"
1602  " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " of the unspent output\n"
1603  " \"height\" : n, (numeric) Height of the unspent transaction output\n"
1604  " }\n"
1605  " ,...], \n"
1606  " \"total_amount\" : x.xxx, (numeric) The total amount of all found unspent outputs in " + CURRENCY_UNIT + "\n"
1607  "]\n"
1608  );
1609 
1610  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
1611 
1612  UniValue result(UniValue::VOBJ);
1613  if (request.params[0].get_str() == "status") {
1614  CoinsViewScanReserver reserver;
1615  if (reserver.reserve()) {
1616  // no scan in progress
1617  return NullUniValue;
1618  }
1619  result.pushKV("progress", g_scan_progress);
1620  return result;
1621  } else if (request.params[0].get_str() == "abort") {
1622  CoinsViewScanReserver reserver;
1623  if (reserver.reserve()) {
1624  // reserve was possible which means no scan was running
1625  return false;
1626  }
1627  // set the abort flag
1628  g_should_abort_scan = true;
1629  return true;
1630  } else if (request.params[0].get_str() == "start") {
1631  CoinsViewScanReserver reserver;
1632  if (!reserver.reserve()) {
1633  throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\"");
1634  }
1635  std::set<CScript> needles;
1636  CAmount total_in = 0;
1637 
1638  // loop through the scan objects
1639  for (const UniValue& scanobject : request.params[1].get_array().getValues()) {
1640  std::string desc_str;
1641  int range = 1000;
1642  if (scanobject.isStr()) {
1643  desc_str = scanobject.get_str();
1644  } else if (scanobject.isObject()) {
1645  UniValue desc_uni = find_value(scanobject, "desc");
1646  if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object");
1647  desc_str = desc_uni.get_str();
1648  UniValue range_uni = find_value(scanobject, "range");
1649  if (!range_uni.isNull()) {
1650  range = range_uni.get_int();
1651  if (range < 0 || range > 1000000) throw JSONRPCError(RPC_INVALID_PARAMETER, "range out of range");
1652  }
1653  } else {
1654  throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan object needs to be either a string or an object");
1655  }
1656 
1657  FlatSigningProvider provider;
1658  auto desc = Parse(desc_str, provider);
1659  if (!desc) {
1660  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid descriptor '%s'", desc_str));
1661  }
1662  if (!desc->IsRange()) range = 0;
1663  for (int i = 0; i <= range; ++i) {
1664  std::vector<CScript> scripts;
1665  if (!desc->Expand(i, provider, scripts, provider)) {
1666  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str));
1667  }
1668  needles.insert(scripts.begin(), scripts.end());
1669  }
1670  }
1671 
1672  // Scan the unspent transaction output set for inputs
1673  UniValue unspents(UniValue::VARR);
1674  std::vector<CTxOut> input_txos;
1675  std::map<COutPoint, Coin> coins;
1676  g_should_abort_scan = false;
1677  g_scan_progress = 0;
1678  int64_t count = 0;
1679  std::unique_ptr<CCoinsViewCursor> pcursor;
1680  {
1681  LOCK(cs_main);
1682  FlushStateToDisk();
1683  pcursor = std::unique_ptr<CCoinsViewCursor>(pcoinsdbview->Cursor());
1684  assert(pcursor);
1685  }
1686  bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins);
1687  result.pushKV("success", res);
1688  result.pushKV("searched_items", count);
1689 
1690  for (const auto& it : coins) {
1691  const COutPoint& outpoint = it.first;
1692  const Coin& coin = it.second;
1693  const CTxOut& txo = coin.out;
1694  input_txos.push_back(txo);
1695  total_in += txo.nValue;
1696 
1697  UniValue unspent(UniValue::VOBJ);
1698  unspent.pushKV("txid", outpoint.hash.GetHex());
1699  unspent.pushKV("vout", (int32_t)outpoint.n);
1700  unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey));
1701  unspent.pushKV("amount", ValueFromAmount(txo.nValue));
1702  unspent.pushKV("height", (int32_t)coin.nHeight);
1703 
1704  unspents.push_back(unspent);
1705  }
1706  result.pushKV("unspents", unspents);
1707  result.pushKV("total_amount", ValueFromAmount(total_in));
1708  } else {
1709  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command");
1710  }
1711  return result;
1712 }
1713 
1714 // clang-format off
1715 static const CRPCCommand commands[] =
1716 { // category name actor (function) okSafe argNames
1717  // --------------------- ------------------------ ----------------------- ------ --------
1718  { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
1719  { "blockchain", "getbestsaplinganchor", &getbestsaplinganchor, true, {} },
1720  { "blockchain", "getblock", &getblock, true, {"blockhash","verbose|verbosity"} },
1721  { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
1722  { "blockchain", "getbestchainlock", &getbestchainlock, true, {} },
1723  { "blockchain", "getblockcount", &getblockcount, true, {} },
1724  { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
1725  { "blockchain", "getblockheader", &getblockheader, false, {"blockhash","verbose"} },
1726  { "blockchain", "getblockindexstats", &getblockindexstats, true, {"height","range"} },
1727  { "blockchain", "getchaintips", &getchaintips, true, {} },
1728  { "blockchain", "getdifficulty", &getdifficulty, true, {} },
1729  { "blockchain", "getfeeinfo", &getfeeinfo, true, {"blocks"} },
1730  { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
1731  { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
1732  { "blockchain", "getsupplyinfo", &getsupplyinfo, true, {"force_update"} },
1733  { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
1734  { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
1735  { "blockchain", "scantxoutset", &scantxoutset, true, {"action", "scanobjects"} },
1736  { "blockchain", "verifychain", &verifychain, true, {"nblocks"} },
1737 
1738  /* Not shown in help */
1739  { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
1740  { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
1741  { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
1742  { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
1743  { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
1744  { "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, true, {} },
1745 };
1746 // clang-format on
1747 
1749 {
1750  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1751  tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
1752 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
void validaterange(const UniValue &params, int &heightStart, int &heightEnd, int minHeightStart=1)
UniValue gettxout(const JSONRPCRequest &request)
Definition: blockchain.cpp:852
UniValue getbestblockhash(const JSONRPCRequest &request)
Definition: blockchain.cpp:215
UniValue getdifficulty(const JSONRPCRequest &request)
Definition: blockchain.cpp:415
UniValue getbestsaplinganchor(const JSONRPCRequest &request)
Definition: blockchain.cpp:232
UniValue getmempoolinfo(const JSONRPCRequest &request)
void RPCNotifyBlockChange(bool fInitialDownload, const CBlockIndex *pindex)
Definition: blockchain.cpp:274
UniValue getbestchainlock(const JSONRPCRequest &request)
Definition: blockchain.cpp:248
UniValue gettxoutsetinfo(const JSONRPCRequest &request)
Definition: blockchain.cpp:814
UniValue mempoolToJSON(bool fVerbose=false)
Definition: blockchain.cpp:474
UniValue getblockchaininfo(const JSONRPCRequest &request)
bool FindScriptPubKey(std::atomic< int > &scan_progress, const std::atomic< bool > &should_abort, int64_t &count, CCoinsViewCursor *cursor, const std::set< CScript > &needles, std::map< COutPoint, Coin > &out_results)
Search for a given set of pubkey scripts.
UniValue getblockheader(const JSONRPCRequest &request)
Definition: blockchain.cpp:642
UniValue getblockhash(const JSONRPCRequest &request)
Definition: blockchain.cpp:532
double GetDifficulty(const CBlockIndex *blockindex)
Definition: blockchain.cpp:67
UniValue mempoolInfoToJSON()
UniValue getrawmempool(const JSONRPCRequest &request)
Definition: blockchain.cpp:498
UniValue reconsiderblock(const JSONRPCRequest &request)
void TxToJSON(CWallet *const pwallet, const CTransaction &tx, const CBlockIndex *tip, const CBlockIndex *blockindex, UniValue &entry)
UniValue waitforblock(const JSONRPCRequest &request)
Definition: blockchain.cpp:325
void NetworkUpgradeDescPushBack(UniValue &networkUpgrades, const Consensus::Params &consensusParams, Consensus::UpgradeIndex idx, int height)
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails=false)
Definition: blockchain.cpp:143
UniValue waitforblockheight(const JSONRPCRequest &request)
Definition: blockchain.cpp:370
UniValue invalidateblock(const JSONRPCRequest &request)
int ComputeNextBlockAndDepth(const CBlockIndex *tip, const CBlockIndex *blockindex, const CBlockIndex *&next)
Definition: blockchain.cpp:106
UniValue getsupplyinfo(const JSONRPCRequest &request)
getinfo depends on getsupplyinfo defined in rpc/blockchain.cpp
Definition: blockchain.cpp:701
UniValue getchaintips(const JSONRPCRequest &request)
UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest &request)
Definition: blockchain.cpp:52
UniValue getfeeinfo(const JSONRPCRequest &request)
UniValue getblock(const JSONRPCRequest &request)
Definition: blockchain.cpp:558
UniValue blockheaderToJSON(const CBlockIndex *tip, const CBlockIndex *blockindex)
Definition: blockchain.cpp:116
UniValue verifychain(const JSONRPCRequest &request)
Definition: blockchain.cpp:930
UniValue getblockcount(const JSONRPCRequest &request)
Definition: blockchain.cpp:198
void RegisterBlockchainRPCCommands(CRPCTable &tableRPC)
Register block chain RPC commands.
UniValue waitfornewblock(const JSONRPCRequest &request)
Definition: blockchain.cpp:284
UniValue getblockindexstats(const JSONRPCRequest &request)
UniValue scantxoutset(const JSONRPCRequest &request)
false
Definition: bls_dkg.cpp:151
CBudgetManager g_budgetman
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Definition: chain.h:110
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
Definition: chain.h:96
@ BLOCK_FAILED_MASK
descends from failed block
Definition: chain.h:123
const CChainParams & Params()
Return the currently selected parameters.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:449
uint256 hash
Definition: transaction.h:35
uint32_t n
Definition: transaction.h:36
uint32_t nNonce
Definition: block.h:32
uint256 hashFinalSaplingRoot
Definition: block.h:34
uint32_t nBits
Definition: block.h:31
uint256 nAccumulatorCheckpoint
Definition: block.h:33
int64_t GetBlockTime() const
Definition: block.h:72
int32_t nVersion
Definition: block.h:27
uint256 hashMerkleRoot
Definition: block.h:29
uint256 GetHash() const
Definition: block.cpp:15
Definition: block.h:80
std::vector< CTransactionRef > vtx
Definition: block.h:83
bool IsProofOfStake() const
Definition: block.h:134
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
uint256 hashMerkleRoot
Definition: chain.h:194
uint256 GetStakeModifierV2() const
Definition: chain.cpp:289
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:145
CBlockHeader GetBlockHeader() const
Definition: chain.cpp:166
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: chain.h:163
uint32_t nTime
Definition: chain.h:196
uint32_t nNonce
Definition: chain.h:198
uint256 nAccumulatorCheckpoint
Definition: chain.h:199
uint256 GetBlockHash() const
Definition: chain.h:215
int64_t GetMedianTimePast() const
Definition: chain.cpp:204
CAmount nSaplingValue
Change in value held by the Sapling circuit over this block.
Definition: chain.h:186
uint32_t nBits
Definition: chain.h:197
int32_t nVersion
block header
Definition: chain.h:193
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:113
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:151
Optional< CAmount > nChainSaplingValue
(memory only) Total value held by the Sapling circuit up to and including this block.
Definition: chain.h:190
uint64_t GetStakeModifierV1() const
Definition: chain.cpp:279
void SetBestHeight(int height)
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
int Height() const
Return the maximal height in the chain.
Definition: chain.h:450
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:56
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:435
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
Cursor for iterating over CoinsView state.
Definition: coins.h:181
virtual void Next()=0
virtual bool Valid() const =0
virtual bool GetKey(COutPoint &key) const =0
virtual bool GetValue(Coin &coin) const =0
Abstract view on the open txout dataset.
Definition: coins.h:201
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:20
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:234
CCoinsView that brings transactions from a memorypool into view.
Definition: txmempool.h:729
bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txmempool.cpp:1300
Fee rate in PIV per kilobyte: CAmount / kB.
Definition: feerate.h:20
CAmount GetFeePerK() const
Definition: feerate.h:29
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:216
uint256 GetHash()
Definition: hash.h:236
void SetBestHeight(int height)
CAmount Get() const
Definition: moneysupply.h:31
int64_t GetCacheHeight() const
Definition: moneysupply.h:32
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
std::string name
Definition: server.h:137
PIVX RPC command dispatcher.
Definition: server.h:147
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:314
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
std::vector< CTxIn > vin
Definition: transaction.h:270
bool ContainsZerocoins() const
Definition: transaction.h:371
const uint256 & GetHash() const
Definition: transaction.h:301
CAmount GetShieldedValueIn() const
CAmount GetValueOut() const
An input of a transaction.
Definition: transaction.h:94
COutPoint prevout
Definition: transaction.h:96
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: txmempool.h:55
const CTransaction & GetTx() const
Definition: txmempool.h:90
unsigned int GetHeight() const
Definition: txmempool.h:95
uint64_t GetCountWithDescendants() const
Definition: txmempool.h:110
CAmount GetModFeesWithDescendants() const
Definition: txmempool.h:112
size_t GetTxSize() const
Definition: txmempool.h:93
int64_t GetTime() const
Definition: txmempool.h:94
uint64_t GetSizeWithDescendants() const
Definition: txmempool.h:111
int64_t GetModifiedFee() const
Definition: txmempool.h:99
const CAmount & GetFee() const
Definition: txmempool.h:92
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:471
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
Definition: txmempool.cpp:1412
void queryHashes(std::vector< uint256 > &vtxid)
Definition: txmempool.cpp:1088
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:1327
bool exists(uint256 hash) const
Definition: txmempool.h:640
bool IsLoaded() const
Definition: txmempool.cpp:1497
indexed_transaction_set mapTx
Definition: txmempool.h:472
uint64_t GetTotalTxSize()
Definition: txmempool.h:634
unsigned long size() const
Definition: txmempool.h:629
bool isSpent(const COutPoint &outpoint)
Definition: txmempool.cpp:345
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
CAmount nValue
Definition: transaction.h:139
Capture information about block/transaction validation.
Definition: validation.h:24
bool IsValid() const
Definition: validation.h:69
std::string GetRejectReason() const
Definition: validation.h:94
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
Definition: validation.h:335
bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
Definition: wallet.h:577
A UTXO entry.
Definition: coins.h:32
bool fCoinStake
whether the containing transaction was a coinstake
Definition: coins.h:38
CTxOut out
unspent transaction output
Definition: coins.h:41
bool fCoinBase
whether the containing transaction was a coinbase
Definition: coins.h:35
uint32_t nHeight
at which height the containing transaction was included in the active block chain
Definition: coins.h:44
UniValue params
Definition: server.h:47
bool fHelp
Definition: server.h:48
const std::string & get_str() const
@ VOBJ
Definition: univalue.h:21
@ VARR
Definition: univalue.h:21
bool isNull() const
Definition: univalue.h:77
size_t size() const
Definition: univalue.h:68
const std::vector< UniValue > & getValues() const
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
const UniValue & get_array() const
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
bool isNum() const
Definition: univalue.h:82
bool get_bool() const
int get_int() const
std::string ToString() const
Definition: uint256.cpp:65
std::string GetHex() const
Definition: uint256.cpp:21
unsigned char * begin()
Definition: uint256.h:63
std::string GetHex() const
256-bit opaque blob.
Definition: uint256.h:138
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:123
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out)
Parse a descriptor string.
Definition: descriptor.cpp:540
const std::string CURRENCY_UNIT
Definition: feerate.cpp:11
sph_u32 high
Definition: keccak.c:370
bool GetStakeKernelHash(uint256 &hashRet, const CBlock &block, const CBlockIndex *pindexPrev)
Definition: kernel.cpp:188
@ LOCK
Definition: lockunlock.h:16
CMasternodeMan mnodeman
Masternode manager.
double GuessVerificationProgress(const CBlockIndex *pindex, bool fSigchecks)
Guess how far we are in the verification process at the given block index.
Definition: checkpoints.cpp:43
UpgradeIndex
Index into Params.vUpgrades and NetworkUpgradeInfo.
Definition: params.h:26
@ UPGRADE_V4_0
Definition: params.h:35
@ BASE_NETWORK
Definition: params.h:27
@ UPGRADE_V3_4
Definition: params.h:34
@ MAX_NETWORK_UPGRADES
Definition: params.h:44
@ UPGRADE_BIP65
Definition: params.h:32
@ UPGRADE_ZC
Definition: params.h:30
std::unique_ptr< CChainLocksHandler > chainLocksHandler
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
const char * name
Definition: rest.cpp:37
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:53
@ RPC_INVALID_PARAMETER
Ran out of memory during operation.
Definition: protocol.h:46
@ RPC_INTERNAL_ERROR
Definition: protocol.h:37
@ RPC_DATABASE_ERROR
Invalid, missing or duplicate parameter.
Definition: protocol.h:47
@ RPC_INVALID_ADDRESS_OR_KEY
Unexpected type was passed as parameter.
Definition: protocol.h:44
@ SER_NETWORK
Definition: serialize.h:174
@ SER_GETHASH
Definition: serialize.h:176
#define VARINT(obj)
Definition: serialize.h:513
#define VARINT_MODE(obj, mode)
Definition: serialize.h:512
@ NONNEGATIVE_SIGNED
unsigned int GetSerializeSize(const std::array< T, N > &item)
array
Definition: serialize.h:847
UniValue ValueFromAmount(const CAmount &amount)
Definition: server.cpp:128
bool IsRPCRunning()
Query whether RPC is running.
Definition: server.cpp:351
std::string HelpExampleCli(std::string methodname, std::string args)
Definition: server.cpp:527
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:63
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: server.cpp:138
std::string HelpExampleRpc(std::string methodname, std::string args)
Definition: server.cpp:532
CRPCTable tableRPC
Definition: server.cpp:565
uint64_t nTransactionOutputs
Definition: blockchain.cpp:752
uint64_t nTransactions
Definition: blockchain.cpp:751
uint256 hashSerialized
Definition: blockchain.cpp:753
uint64_t nDiskSize
Definition: blockchain.cpp:754
uint256 hashBlock
Definition: blockchain.cpp:750
CAmount nTotalAmount
Definition: blockchain.cpp:755
uint256 hash
Definition: blockchain.cpp:43
Comparison function for sorting the getchaintips heads.
bool operator()(const CBlockIndex *a, const CBlockIndex *b) const
int nActivationHeight
Height of the first block for which the new consensus rules will be active.
Definition: params.h:56
static constexpr int NO_ACTIVATION_HEIGHT
Special value for nActivationHeight indicating that the upgrade will never activate.
Definition: params.h:74
Parameters that influence chain consensus.
Definition: params.h:171
NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES]
Definition: params.h:213
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const
Returns true if the given network upgrade is active as of the given block height.
Definition: params.cpp:12
std::string strName
User-facing name for the upgrade.
Definition: upgrades.h:20
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247
#define AssertLockHeld(cs)
Definition: sync.h:75
ArgsManager gArgs
Definition: system.cpp:89
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
#define strprintf
Definition: tinyformat.h:1056
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:456
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:175
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:234
const UniValue NullUniValue
Definition: univalue.cpp:13
UpgradeState NetworkUpgradeState(int nHeight, const Consensus::Params &params, Consensus::UpgradeIndex idx)
Checks the state of a given network upgrade based on block height.
Definition: upgrades.cpp:82
const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES]
General information about each network upgrade.
Definition: upgrades.cpp:15
@ UPGRADE_PENDING
Definition: upgrades.h:14
@ UPGRADE_DISABLED
Definition: upgrades.h:13
@ UPGRADE_ACTIVE
Definition: upgrades.h:15
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
#define ARRAYLEN(array)
void FlushStateToDisk()
Flush all state, indexes and buffers to disk.
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock.
Definition: validation.cpp:671
CMoneySupply MoneySupply
Definition: validation.cpp:114
CTxMemPool mempool(::minRelayTxFee)
CFeeRate minRelayTxFee
Fees smaller than this (in upiv) are considered zero fee (for relaying, mining and transaction creati...
Definition: validation.cpp:108
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network)
Definition: validation.cpp:862
bool ActivateBestChain(CValidationState &state, std::shared_ptr< const CBlock > pblock)
Make the best chain active, in multiple steps.
std::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:206
bool ReconsiderBlock(CValidationState &state, CBlockIndex *pindex)
Remove invalidity status from a block and its descendants.
BlockMap mapBlockIndex
Definition: validation.cpp:82
std::unique_ptr< CCoinsViewDB > pcoinsdbview
Global variable that points to the coins database (protected by cs_main)
Definition: validation.cpp:205
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos)
Definition: validation.cpp:758
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
Definition: validation.cpp:85
CBlockIndex * GetChainTip()
Return a reliable pointer (in mapBlockIndex) to the chain's tip index.
Definition: validation.cpp:194
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:84
bool InvalidateBlock(CValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex)
Mark a block as invalid.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:345
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:33
std::string GetWarnings(const std::string &strFor)
Definition: warnings.cpp:47