Bitcoin ABC  0.25.11
P2P Digital Currency
blockchain.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <rpc/blockchain.h>
7 
8 #include <amount.h>
9 #include <blockdb.h>
10 #include <blockfilter.h>
11 #include <chain.h>
12 #include <chainparams.h>
13 #include <coins.h>
14 #include <config.h>
15 #include <consensus/validation.h>
16 #include <core_io.h>
17 #include <hash.h>
18 #include <index/blockfilterindex.h>
19 #include <index/coinstatsindex.h>
20 #include <node/blockstorage.h>
21 #include <node/coinstats.h>
22 #include <node/context.h>
23 #include <node/utxo_snapshot.h>
24 #include <policy/policy.h>
25 #include <primitives/transaction.h>
26 #include <rpc/server.h>
27 #include <rpc/util.h>
28 #include <script/descriptor.h>
29 #include <streams.h>
30 #include <txdb.h>
31 #include <txmempool.h>
32 #include <undo.h>
33 #include <util/strencodings.h>
34 #include <util/system.h>
35 #include <util/translation.h>
36 #include <validation.h>
37 #include <validationinterface.h>
38 #include <versionbitsinfo.h> // For VersionBitsDeploymentInfo
39 #include <warnings.h>
40 
41 #include <condition_variable>
42 #include <cstdint>
43 #include <memory>
44 #include <mutex>
45 
46 struct CUpdatedBlock {
48  int height;
49 };
50 
52 static std::condition_variable cond_blockchange;
53 static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);
54 
55 NodeContext &EnsureAnyNodeContext(const std::any &context) {
56  auto node_context = util::AnyPtr<NodeContext>(context);
57  if (!node_context) {
58  throw JSONRPCError(RPC_INTERNAL_ERROR, "Node context not found");
59  }
60  return *node_context;
61 }
62 
64  if (!node.mempool) {
66  "Mempool disabled or instance not found");
67  }
68  return *node.mempool;
69 }
70 
71 CTxMemPool &EnsureAnyMemPool(const std::any &context) {
72  return EnsureMemPool(EnsureAnyNodeContext(context));
73 }
74 
76  if (!node.chainman) {
77  throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
78  }
79  return *node.chainman;
80 }
81 
82 ChainstateManager &EnsureAnyChainman(const std::any &context) {
83  return EnsureChainman(EnsureAnyNodeContext(context));
84 }
85 
89 double GetDifficulty(const CBlockIndex *blockindex) {
90  CHECK_NONFATAL(blockindex);
91 
92  int nShift = (blockindex->nBits >> 24) & 0xff;
93  double dDiff = double(0x0000ffff) / double(blockindex->nBits & 0x00ffffff);
94 
95  while (nShift < 29) {
96  dDiff *= 256.0;
97  nShift++;
98  }
99  while (nShift > 29) {
100  dDiff /= 256.0;
101  nShift--;
102  }
103 
104  return dDiff;
105 }
106 
107 static int ComputeNextBlockAndDepth(const CBlockIndex *tip,
108  const CBlockIndex *blockindex,
109  const CBlockIndex *&next) {
110  next = tip->GetAncestor(blockindex->nHeight + 1);
111  if (next && next->pprev == blockindex) {
112  return tip->nHeight - blockindex->nHeight + 1;
113  }
114  next = nullptr;
115  return blockindex == tip ? 1 : -1;
116 }
117 
119  ChainstateManager &chainman) {
120  LOCK(::cs_main);
121  CChain &active_chain = chainman.ActiveChain();
122 
123  if (param.isNum()) {
124  const int height{param.get_int()};
125  if (height < 0) {
126  throw JSONRPCError(
128  strprintf("Target block height %d is negative", height));
129  }
130  const int current_tip{active_chain.Height()};
131  if (height > current_tip) {
132  throw JSONRPCError(
134  strprintf("Target block height %d after current tip %d", height,
135  current_tip));
136  }
137 
138  return active_chain[height];
139  } else {
140  const BlockHash hash{ParseHashV(param, "hash_or_height")};
141  CBlockIndex *pindex = chainman.m_blockman.LookupBlockIndex(hash);
142 
143  if (!pindex) {
144  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
145  }
146 
147  return pindex;
148  }
149 }
151  const CBlockIndex *blockindex) {
152  // Serialize passed information without accessing chain state of the active
153  // chain!
154  // For performance reasons
156 
157  UniValue result(UniValue::VOBJ);
158  result.pushKV("hash", blockindex->GetBlockHash().GetHex());
159  const CBlockIndex *pnext;
160  int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
161  result.pushKV("confirmations", confirmations);
162  result.pushKV("height", blockindex->nHeight);
163  result.pushKV("version", blockindex->nVersion);
164  result.pushKV("versionHex", strprintf("%08x", blockindex->nVersion));
165  result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex());
166  result.pushKV("time", int64_t(blockindex->nTime));
167  result.pushKV("mediantime", int64_t(blockindex->GetMedianTimePast()));
168  result.pushKV("nonce", uint64_t(blockindex->nNonce));
169  result.pushKV("bits", strprintf("%08x", blockindex->nBits));
170  result.pushKV("difficulty", GetDifficulty(blockindex));
171  result.pushKV("chainwork", blockindex->nChainWork.GetHex());
172  result.pushKV("nTx", uint64_t(blockindex->nTx));
173 
174  if (blockindex->pprev) {
175  result.pushKV("previousblockhash",
176  blockindex->pprev->GetBlockHash().GetHex());
177  }
178  if (pnext) {
179  result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
180  }
181  return result;
182 }
183 
184 UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip,
185  const CBlockIndex *blockindex, bool txDetails) {
186  UniValue result = blockheaderToJSON(tip, blockindex);
187 
188  result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
190  for (const auto &tx : block.vtx) {
191  if (txDetails) {
192  UniValue objTx(UniValue::VOBJ);
193  TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags());
194  txs.push_back(objTx);
195  } else {
196  txs.push_back(tx->GetId().GetHex());
197  }
198  }
199  result.pushKV("tx", txs);
200 
201  return result;
202 }
203 
205  return RPCHelpMan{
206  "getblockcount",
207  "Returns the height of the most-work fully-validated chain.\n"
208  "The genesis block has height 0.\n",
209  {},
210  RPCResult{RPCResult::Type::NUM, "", "The current block count"},
211  RPCExamples{HelpExampleCli("getblockcount", "") +
212  HelpExampleRpc("getblockcount", "")},
213  [&](const RPCHelpMan &self, const Config &config,
214  const JSONRPCRequest &request) -> UniValue {
215  ChainstateManager &chainman = EnsureAnyChainman(request.context);
216  LOCK(cs_main);
217  return chainman.ActiveHeight();
218  },
219  };
220 }
221 
223  return RPCHelpMan{
224  "getbestblockhash",
225  "Returns the hash of the best (tip) block in the "
226  "most-work fully-validated chain.\n",
227  {},
228  RPCResult{RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"},
229  RPCExamples{HelpExampleCli("getbestblockhash", "") +
230  HelpExampleRpc("getbestblockhash", "")},
231  [&](const RPCHelpMan &self, const Config &config,
232  const JSONRPCRequest &request) -> UniValue {
233  ChainstateManager &chainman = EnsureAnyChainman(request.context);
234  LOCK(cs_main);
235  return chainman.ActiveTip()->GetBlockHash().GetHex();
236  },
237  };
238 }
239 
241  return RPCHelpMan{
242  "getfinalizedblockhash",
243  "Returns the hash of the currently finalized block\n",
244  {},
245  RPCResult{RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"},
246  RPCExamples{HelpExampleCli("getfinalizedblockhash", "") +
247  HelpExampleRpc("getfinalizedblockhash", "")},
248  [&](const RPCHelpMan &self, const Config &config,
249  const JSONRPCRequest &request) -> UniValue {
250  ChainstateManager &chainman = EnsureAnyChainman(request.context);
251  LOCK(cs_main);
252  CChainState &active_chainstate = chainman.ActiveChainstate();
253  const CBlockIndex *blockIndexFinalized =
254  active_chainstate.GetFinalizedBlock();
255  if (blockIndexFinalized) {
256  return blockIndexFinalized->GetBlockHash().GetHex();
257  }
258  return UniValue(UniValue::VSTR);
259  },
260  };
261 }
262 
263 void RPCNotifyBlockChange(const CBlockIndex *pindex) {
264  if (pindex) {
266  latestblock.hash = pindex->GetBlockHash();
267  latestblock.height = pindex->nHeight;
268  }
269  cond_blockchange.notify_all();
270 }
271 
273  return RPCHelpMan{
274  "waitfornewblock",
275  "Waits for a specific new block and returns useful info about it.\n"
276  "\nReturns the current block on timeout or exit.\n",
277  {
278  {"timeout", RPCArg::Type::NUM, /* default */ "0",
279  "Time in milliseconds to wait for a response. 0 indicates no "
280  "timeout."},
281  },
283  "",
284  "",
285  {
286  {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
287  {RPCResult::Type::NUM, "height", "Block height"},
288  }},
289  RPCExamples{HelpExampleCli("waitfornewblock", "1000") +
290  HelpExampleRpc("waitfornewblock", "1000")},
291  [&](const RPCHelpMan &self, const Config &config,
292  const JSONRPCRequest &request) -> UniValue {
293  int timeout = 0;
294  if (!request.params[0].isNull()) {
295  timeout = request.params[0].get_int();
296  }
297 
298  CUpdatedBlock block;
299  {
300  WAIT_LOCK(cs_blockchange, lock);
301  block = latestblock;
302  if (timeout) {
303  cond_blockchange.wait_for(
304  lock, std::chrono::milliseconds(timeout),
306  return latestblock.height != block.height ||
307  latestblock.hash != block.hash ||
308  !IsRPCRunning();
309  });
310  } else {
311  cond_blockchange.wait(
312  lock,
314  return latestblock.height != block.height ||
315  latestblock.hash != block.hash ||
316  !IsRPCRunning();
317  });
318  }
319  block = latestblock;
320  }
322  ret.pushKV("hash", block.hash.GetHex());
323  ret.pushKV("height", block.height);
324  return ret;
325  },
326  };
327 }
328 
330  return RPCHelpMan{
331  "waitforblock",
332  "Waits for a specific new block and returns useful info about it.\n"
333  "\nReturns the current block on timeout or exit.\n",
334  {
336  "Block hash to wait for."},
337  {"timeout", RPCArg::Type::NUM, /* default */ "0",
338  "Time in milliseconds to wait for a response. 0 indicates no "
339  "timeout."},
340  },
342  "",
343  "",
344  {
345  {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
346  {RPCResult::Type::NUM, "height", "Block height"},
347  }},
348  RPCExamples{HelpExampleCli("waitforblock",
349  "\"0000000000079f8ef3d2c688c244eb7a4570b24c9"
350  "ed7b4a8c619eb02596f8862\" 1000") +
351  HelpExampleRpc("waitforblock",
352  "\"0000000000079f8ef3d2c688c244eb7a4570b24c9"
353  "ed7b4a8c619eb02596f8862\", 1000")},
354  [&](const RPCHelpMan &self, const Config &config,
355  const JSONRPCRequest &request) -> UniValue {
356  int timeout = 0;
357 
358  BlockHash hash(ParseHashV(request.params[0], "blockhash"));
359 
360  if (!request.params[1].isNull()) {
361  timeout = request.params[1].get_int();
362  }
363 
364  CUpdatedBlock block;
365  {
366  WAIT_LOCK(cs_blockchange, lock);
367  if (timeout) {
368  cond_blockchange.wait_for(
369  lock, std::chrono::milliseconds(timeout),
371  return latestblock.hash == hash || !IsRPCRunning();
372  });
373  } else {
374  cond_blockchange.wait(
375  lock,
377  return latestblock.hash == hash || !IsRPCRunning();
378  });
379  }
380  block = latestblock;
381  }
382 
384  ret.pushKV("hash", block.hash.GetHex());
385  ret.pushKV("height", block.height);
386  return ret;
387  },
388  };
389 }
390 
392  return RPCHelpMan{
393  "waitforblockheight",
394  "Waits for (at least) block height and returns the height and "
395  "hash\nof the current tip.\n"
396  "\nReturns the current block on timeout or exit.\n",
397  {
399  "Block height to wait for."},
400  {"timeout", RPCArg::Type::NUM, /* default */ "0",
401  "Time in milliseconds to wait for a response. 0 indicates no "
402  "timeout."},
403  },
405  "",
406  "",
407  {
408  {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
409  {RPCResult::Type::NUM, "height", "Block height"},
410  }},
411  RPCExamples{HelpExampleCli("waitforblockheight", "100 1000") +
412  HelpExampleRpc("waitforblockheight", "100, 1000")},
413  [&](const RPCHelpMan &self, const Config &config,
414  const JSONRPCRequest &request) -> UniValue {
415  int timeout = 0;
416 
417  int height = request.params[0].get_int();
418 
419  if (!request.params[1].isNull()) {
420  timeout = request.params[1].get_int();
421  }
422 
423  CUpdatedBlock block;
424  {
425  WAIT_LOCK(cs_blockchange, lock);
426  if (timeout) {
427  cond_blockchange.wait_for(
428  lock, std::chrono::milliseconds(timeout),
430  return latestblock.height >= height ||
431  !IsRPCRunning();
432  });
433  } else {
434  cond_blockchange.wait(
435  lock,
437  return latestblock.height >= height ||
438  !IsRPCRunning();
439  });
440  }
441  block = latestblock;
442  }
444  ret.pushKV("hash", block.hash.GetHex());
445  ret.pushKV("height", block.height);
446  return ret;
447  },
448  };
449 }
450 
452  return RPCHelpMan{
453  "syncwithvalidationinterfacequeue",
454  "Waits for the validation interface queue to catch up on everything "
455  "that was there when we entered this function.\n",
456  {},
458  RPCExamples{HelpExampleCli("syncwithvalidationinterfacequeue", "") +
459  HelpExampleRpc("syncwithvalidationinterfacequeue", "")},
460  [&](const RPCHelpMan &self, const Config &config,
461  const JSONRPCRequest &request) -> UniValue {
463  return NullUniValue;
464  },
465  };
466 }
467 
469  return RPCHelpMan{
470  "getdifficulty",
471  "Returns the proof-of-work difficulty as a multiple of the minimum "
472  "difficulty.\n",
473  {},
475  "the proof-of-work difficulty as a multiple of the minimum "
476  "difficulty."},
477  RPCExamples{HelpExampleCli("getdifficulty", "") +
478  HelpExampleRpc("getdifficulty", "")},
479  [&](const RPCHelpMan &self, const Config &config,
480  const JSONRPCRequest &request) -> UniValue {
481  ChainstateManager &chainman = EnsureAnyChainman(request.context);
482  LOCK(cs_main);
483  return GetDifficulty(chainman.ActiveTip());
484  },
485  };
486 }
487 
488 static std::vector<RPCResult> MempoolEntryDescription() {
489  const auto &ticker = Currency::get().ticker;
490  return {
491  RPCResult{RPCResult::Type::NUM, "size", "transaction size."},
493  "transaction fee in " + ticker + " (DEPRECATED)"},
494  RPCResult{RPCResult::Type::STR_AMOUNT, "modifiedfee",
495  "transaction fee with fee deltas used for mining priority "
496  "(DEPRECATED)"},
498  "local time transaction entered pool in seconds since 1 Jan "
499  "1970 GMT"},
501  "block height when transaction entered pool"},
502  RPCResult{RPCResult::Type::NUM, "descendantcount",
503  "number of in-mempool descendant transactions (including "
504  "this one)"},
505  RPCResult{RPCResult::Type::NUM, "descendantsize",
506  "transaction size of in-mempool descendants "
507  "(including this one)"},
508  RPCResult{RPCResult::Type::STR_AMOUNT, "descendantfees",
509  "modified fees (see above) of in-mempool descendants "
510  "(including this one) (DEPRECATED)"},
511  RPCResult{
512  RPCResult::Type::NUM, "ancestorcount",
513  "number of in-mempool ancestor transactions (including this one)"},
514  RPCResult{
515  RPCResult::Type::NUM, "ancestorsize",
516  "transaction size of in-mempool ancestors (including this one)"},
517  RPCResult{RPCResult::Type::STR_AMOUNT, "ancestorfees",
518  "modified fees (see above) of in-mempool ancestors "
519  "(including this one) (DEPRECATED)"},
521  "fees",
522  "",
523  {
525  "transaction fee in " + ticker},
527  "transaction fee with fee deltas used for "
528  "mining priority in " +
529  ticker},
531  "modified fees (see above) of in-mempool "
532  "ancestors (including this one) in " +
533  ticker},
535  "modified fees (see above) of in-mempool "
536  "descendants (including this one) in " +
537  ticker},
538  }},
539  RPCResult{
541  "depends",
542  "unconfirmed transactions used as inputs for this transaction",
543  {RPCResult{RPCResult::Type::STR_HEX, "transactionid",
544  "parent transaction id"}}},
545  RPCResult{
547  "spentby",
548  "unconfirmed transactions spending outputs from this transaction",
549  {RPCResult{RPCResult::Type::STR_HEX, "transactionid",
550  "child transaction id"}}},
551  RPCResult{RPCResult::Type::BOOL, "unbroadcast",
552  "Whether this transaction is currently unbroadcast (initial "
553  "broadcast not yet acknowledged by any peers)"},
554  };
555 }
556 
557 static void entryToJSON(const CTxMemPool &pool, UniValue &info,
558  const CTxMemPoolEntry &e)
559  EXCLUSIVE_LOCKS_REQUIRED(pool.cs) {
560  AssertLockHeld(pool.cs);
561 
562  UniValue fees(UniValue::VOBJ);
563  fees.pushKV("base", e.GetFee());
564  fees.pushKV("modified", e.GetModifiedFee());
565  fees.pushKV("ancestor", e.GetModFeesWithAncestors());
566  fees.pushKV("descendant", e.GetModFeesWithDescendants());
567  info.pushKV("fees", fees);
568 
569  info.pushKV("size", (int)e.GetTxSize());
570  info.pushKV("fee", e.GetFee());
571  info.pushKV("modifiedfee", e.GetModifiedFee());
572  info.pushKV("time", count_seconds(e.GetTime()));
573  info.pushKV("height", (int)e.GetHeight());
574  info.pushKV("descendantcount", e.GetCountWithDescendants());
575  info.pushKV("descendantsize", e.GetSizeWithDescendants());
576  info.pushKV("descendantfees", e.GetModFeesWithDescendants() / SATOSHI);
577  info.pushKV("ancestorcount", e.GetCountWithAncestors());
578  info.pushKV("ancestorsize", e.GetSizeWithAncestors());
579  info.pushKV("ancestorfees", e.GetModFeesWithAncestors() / SATOSHI);
580  const CTransaction &tx = e.GetTx();
581  std::set<std::string> setDepends;
582  for (const CTxIn &txin : tx.vin) {
583  if (pool.exists(txin.prevout.GetTxId())) {
584  setDepends.insert(txin.prevout.GetTxId().ToString());
585  }
586  }
587 
588  UniValue depends(UniValue::VARR);
589  for (const std::string &dep : setDepends) {
590  depends.push_back(dep);
591  }
592 
593  info.pushKV("depends", depends);
594 
595  UniValue spent(UniValue::VARR);
596  const CTxMemPool::txiter &it = pool.mapTx.find(tx.GetId());
597  const CTxMemPoolEntry::Children &children = it->GetMemPoolChildrenConst();
598  for (const CTxMemPoolEntry &child : children) {
599  spent.push_back(child.GetTx().GetId().ToString());
600  }
601 
602  info.pushKV("spentby", spent);
603  info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetId()));
604 }
605 
606 UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose,
607  bool include_mempool_sequence) {
608  if (verbose) {
609  if (include_mempool_sequence) {
610  throw JSONRPCError(
612  "Verbose results cannot contain mempool sequence values.");
613  }
614  LOCK(pool.cs);
616  for (const CTxMemPoolEntry &e : pool.mapTx) {
617  const uint256 &txid = e.GetTx().GetId();
618  UniValue info(UniValue::VOBJ);
619  entryToJSON(pool, info, e);
620  // Mempool has unique entries so there is no advantage in using
621  // UniValue::pushKV, which checks if the key already exists in O(N).
622  // UniValue::__pushKV is used instead which currently is O(1).
623  o.__pushKV(txid.ToString(), info);
624  }
625  return o;
626  } else {
627  uint64_t mempool_sequence;
628  std::vector<uint256> vtxids;
629  {
630  LOCK(pool.cs);
631  pool.queryHashes(vtxids);
632  mempool_sequence = pool.GetSequence();
633  }
635  for (const uint256 &txid : vtxids) {
636  a.push_back(txid.ToString());
637  }
638 
639  if (!include_mempool_sequence) {
640  return a;
641  } else {
643  o.pushKV("txids", a);
644  o.pushKV("mempool_sequence", mempool_sequence);
645  return o;
646  }
647  }
648 }
649 
651  return RPCHelpMan{
652  "getrawmempool",
653  "Returns all transaction ids in memory pool as a json array of "
654  "string transaction ids.\n"
655  "\nHint: use getmempoolentry to fetch a specific transaction from the "
656  "mempool.\n",
657  {
658  {"verbose", RPCArg::Type::BOOL, /* default */ "false",
659  "True for a json object, false for array of transaction ids"},
660  {"mempool_sequence", RPCArg::Type::BOOL, /* default */ "false",
661  "If verbose=false, returns a json object with transaction list "
662  "and mempool sequence number attached."},
663  },
664  {
665  RPCResult{"for verbose = false",
667  "",
668  "",
669  {
670  {RPCResult::Type::STR_HEX, "", "The transaction id"},
671  }},
672  RPCResult{"for verbose = true",
674  "",
675  "",
676  {
677  {RPCResult::Type::OBJ, "transactionid", "",
679  }},
680  RPCResult{
681  "for verbose = false and mempool_sequence = true",
683  "",
684  "",
685  {
687  "txids",
688  "",
689  {
690  {RPCResult::Type::STR_HEX, "", "The transaction id"},
691  }},
692  {RPCResult::Type::NUM, "mempool_sequence",
693  "The mempool sequence value."},
694  }},
695  },
696  RPCExamples{HelpExampleCli("getrawmempool", "true") +
697  HelpExampleRpc("getrawmempool", "true")},
698  [&](const RPCHelpMan &self, const Config &config,
699  const JSONRPCRequest &request) -> UniValue {
700  bool fVerbose = false;
701  if (!request.params[0].isNull()) {
702  fVerbose = request.params[0].get_bool();
703  }
704 
705  bool include_mempool_sequence = false;
706  if (!request.params[1].isNull()) {
707  include_mempool_sequence = request.params[1].get_bool();
708  }
709 
710  return MempoolToJSON(EnsureAnyMemPool(request.context), fVerbose,
711  include_mempool_sequence);
712  },
713  };
714 }
715 
717  return RPCHelpMan{
718  "getmempoolancestors",
719  "If txid is in the mempool, returns all in-mempool ancestors.\n",
720  {
722  "The transaction id (must be in mempool)"},
723  {"verbose", RPCArg::Type::BOOL, /* default */ "false",
724  "True for a json object, false for array of transaction ids"},
725  },
726  {
727  RPCResult{
728  "for verbose = false",
730  "",
731  "",
733  "The transaction id of an in-mempool ancestor transaction"}}},
734  RPCResult{"for verbose = true",
736  "",
737  "",
738  {
739  {RPCResult::Type::OBJ, "transactionid", "",
741  }},
742  },
743  RPCExamples{HelpExampleCli("getmempoolancestors", "\"mytxid\"") +
744  HelpExampleRpc("getmempoolancestors", "\"mytxid\"")},
745  [&](const RPCHelpMan &self, const Config &config,
746  const JSONRPCRequest &request) -> UniValue {
747  bool fVerbose = false;
748  if (!request.params[1].isNull()) {
749  fVerbose = request.params[1].get_bool();
750  }
751 
752  TxId txid(ParseHashV(request.params[0], "parameter 1"));
753 
754  const CTxMemPool &mempool = EnsureAnyMemPool(request.context);
755  LOCK(mempool.cs);
756 
757  CTxMemPool::txiter it = mempool.mapTx.find(txid);
758  if (it == mempool.mapTx.end()) {
760  "Transaction not in mempool");
761  }
762 
763  CTxMemPool::setEntries setAncestors;
764  uint64_t noLimit = std::numeric_limits<uint64_t>::max();
765  std::string dummy;
766  mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit,
767  noLimit, noLimit, noLimit, dummy,
768  false);
769 
770  if (!fVerbose) {
772  for (CTxMemPool::txiter ancestorIt : setAncestors) {
773  o.push_back(ancestorIt->GetTx().GetId().ToString());
774  }
775  return o;
776  } else {
778  for (CTxMemPool::txiter ancestorIt : setAncestors) {
779  const CTxMemPoolEntry &e = *ancestorIt;
780  const TxId &_txid = e.GetTx().GetId();
781  UniValue info(UniValue::VOBJ);
782  entryToJSON(mempool, info, e);
783  o.pushKV(_txid.ToString(), info);
784  }
785  return o;
786  }
787  },
788  };
789 }
790 
792  return RPCHelpMan{
793  "getmempooldescendants",
794  "If txid is in the mempool, returns all in-mempool descendants.\n",
795  {
797  "The transaction id (must be in mempool)"},
798  {"verbose", RPCArg::Type::BOOL, /* default */ "false",
799  "True for a json object, false for array of transaction ids"},
800  },
801  {
802  RPCResult{"for verbose = false",
804  "",
805  "",
807  "The transaction id of an in-mempool descendant "
808  "transaction"}}},
809  RPCResult{"for verbose = true",
811  "",
812  "",
813  {
814  {RPCResult::Type::OBJ, "transactionid", "",
816  }},
817  },
818  RPCExamples{HelpExampleCli("getmempooldescendants", "\"mytxid\"") +
819  HelpExampleRpc("getmempooldescendants", "\"mytxid\"")},
820  [&](const RPCHelpMan &self, const Config &config,
821  const JSONRPCRequest &request) -> UniValue {
822  bool fVerbose = false;
823  if (!request.params[1].isNull()) {
824  fVerbose = request.params[1].get_bool();
825  }
826 
827  TxId txid(ParseHashV(request.params[0], "parameter 1"));
828 
829  const CTxMemPool &mempool = EnsureAnyMemPool(request.context);
830  LOCK(mempool.cs);
831 
832  CTxMemPool::txiter it = mempool.mapTx.find(txid);
833  if (it == mempool.mapTx.end()) {
835  "Transaction not in mempool");
836  }
837 
838  CTxMemPool::setEntries setDescendants;
839  mempool.CalculateDescendants(it, setDescendants);
840  // CTxMemPool::CalculateDescendants will include the given tx
841  setDescendants.erase(it);
842 
843  if (!fVerbose) {
845  for (CTxMemPool::txiter descendantIt : setDescendants) {
846  o.push_back(descendantIt->GetTx().GetId().ToString());
847  }
848 
849  return o;
850  } else {
852  for (CTxMemPool::txiter descendantIt : setDescendants) {
853  const CTxMemPoolEntry &e = *descendantIt;
854  const TxId &_txid = e.GetTx().GetId();
855  UniValue info(UniValue::VOBJ);
856  entryToJSON(mempool, info, e);
857  o.pushKV(_txid.ToString(), info);
858  }
859  return o;
860  }
861  },
862  };
863 }
864 
866  return RPCHelpMan{
867  "getmempoolentry",
868  "Returns mempool data for given transaction\n",
869  {
871  "The transaction id (must be in mempool)"},
872  },
874  RPCExamples{HelpExampleCli("getmempoolentry", "\"mytxid\"") +
875  HelpExampleRpc("getmempoolentry", "\"mytxid\"")},
876  [&](const RPCHelpMan &self, const Config &config,
877  const JSONRPCRequest &request) -> UniValue {
878  TxId txid(ParseHashV(request.params[0], "parameter 1"));
879 
880  const CTxMemPool &mempool = EnsureAnyMemPool(request.context);
881  LOCK(mempool.cs);
882 
883  CTxMemPool::txiter it = mempool.mapTx.find(txid);
884  if (it == mempool.mapTx.end()) {
886  "Transaction not in mempool");
887  }
888 
889  const CTxMemPoolEntry &e = *it;
890  UniValue info(UniValue::VOBJ);
891  entryToJSON(mempool, info, e);
892  return info;
893  },
894  };
895 }
896 
898  return RPCHelpMan{
899  "getblockhash",
900  "Returns hash of block in best-block-chain at height provided.\n",
901  {
903  "The height index"},
904  },
905  RPCResult{RPCResult::Type::STR_HEX, "", "The block hash"},
906  RPCExamples{HelpExampleCli("getblockhash", "1000") +
907  HelpExampleRpc("getblockhash", "1000")},
908  [&](const RPCHelpMan &self, const Config &config,
909  const JSONRPCRequest &request) -> UniValue {
910  ChainstateManager &chainman = EnsureAnyChainman(request.context);
911  LOCK(cs_main);
912  const CChain &active_chain = chainman.ActiveChain();
913 
914  int nHeight = request.params[0].get_int();
915  if (nHeight < 0 || nHeight > active_chain.Height()) {
917  "Block height out of range");
918  }
919 
920  CBlockIndex *pblockindex = active_chain[nHeight];
921  return pblockindex->GetBlockHash().GetHex();
922  },
923  };
924 }
925 
927  return RPCHelpMan{
928  "getblockheader",
929  "If verbose is false, returns a string that is serialized, hex-encoded "
930  "data for blockheader 'hash'.\n"
931  "If verbose is true, returns an Object with information about "
932  "blockheader <hash>.\n",
933  {
935  "The block hash"},
936  {"verbose", RPCArg::Type::BOOL, /* default */ "true",
937  "true for a json object, false for the hex-encoded data"},
938  },
939  {
940  RPCResult{
941  "for verbose = true",
943  "",
944  "",
945  {
946  {RPCResult::Type::STR_HEX, "hash",
947  "the block hash (same as provided)"},
948  {RPCResult::Type::NUM, "confirmations",
949  "The number of confirmations, or -1 if the block is not "
950  "on the main chain"},
951  {RPCResult::Type::NUM, "height",
952  "The block height or index"},
953  {RPCResult::Type::NUM, "version", "The block version"},
954  {RPCResult::Type::STR_HEX, "versionHex",
955  "The block version formatted in hexadecimal"},
956  {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
957  {RPCResult::Type::NUM_TIME, "time",
958  "The block time expressed in " + UNIX_EPOCH_TIME},
959  {RPCResult::Type::NUM_TIME, "mediantime",
960  "The median block time expressed in " + UNIX_EPOCH_TIME},
961  {RPCResult::Type::NUM, "nonce", "The nonce"},
962  {RPCResult::Type::STR_HEX, "bits", "The bits"},
963  {RPCResult::Type::NUM, "difficulty", "The difficulty"},
964  {RPCResult::Type::STR_HEX, "chainwork",
965  "Expected number of hashes required to produce the "
966  "current chain"},
967  {RPCResult::Type::NUM, "nTx",
968  "The number of transactions in the block"},
969  {RPCResult::Type::STR_HEX, "previousblockhash",
970  /* optional */ true,
971  "The hash of the previous block (if available)"},
972  {RPCResult::Type::STR_HEX, "nextblockhash",
973  /* optional */ true,
974  "The hash of the next block (if available)"},
975  }},
976  RPCResult{"for verbose=false", RPCResult::Type::STR_HEX, "",
977  "A string that is serialized, hex-encoded data for block "
978  "'hash'"},
979  },
980  RPCExamples{HelpExampleCli("getblockheader",
981  "\"00000000c937983704a73af28acdec37b049d214a"
982  "dbda81d7e2a3dd146f6ed09\"") +
983  HelpExampleRpc("getblockheader",
984  "\"00000000c937983704a73af28acdec37b049d214a"
985  "dbda81d7e2a3dd146f6ed09\"")},
986  [&](const RPCHelpMan &self, const Config &config,
987  const JSONRPCRequest &request) -> UniValue {
988  BlockHash hash(ParseHashV(request.params[0], "hash"));
989 
990  bool fVerbose = true;
991  if (!request.params[1].isNull()) {
992  fVerbose = request.params[1].get_bool();
993  }
994 
995  const CBlockIndex *pblockindex;
996  const CBlockIndex *tip;
997  {
998  ChainstateManager &chainman =
999  EnsureAnyChainman(request.context);
1000  LOCK(cs_main);
1001  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
1002  tip = chainman.ActiveTip();
1003  }
1004 
1005  if (!pblockindex) {
1007  "Block not found");
1008  }
1009 
1010  if (!fVerbose) {
1012  ssBlock << pblockindex->GetBlockHeader();
1013  std::string strHex = HexStr(ssBlock);
1014  return strHex;
1015  }
1016 
1017  return blockheaderToJSON(tip, pblockindex);
1018  },
1019  };
1020 }
1021 
1022 static CBlock GetBlockChecked(const Config &config,
1023  const CBlockIndex *pblockindex) {
1024  CBlock block;
1025  if (IsBlockPruned(pblockindex)) {
1026  throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
1027  }
1028 
1029  if (!ReadBlockFromDisk(block, pblockindex,
1030  config.GetChainParams().GetConsensus())) {
1031  // Block not found on disk. This could be because we have the block
1032  // header in our index but not yet have the block or did not accept the
1033  // block.
1034  throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
1035  }
1036 
1037  return block;
1038 }
1039 
1040 static CBlockUndo GetUndoChecked(const CBlockIndex *pblockindex) {
1041  CBlockUndo blockUndo;
1042  if (IsBlockPruned(pblockindex)) {
1044  "Undo data not available (pruned data)");
1045  }
1046 
1047  if (!UndoReadFromDisk(blockUndo, pblockindex)) {
1048  throw JSONRPCError(RPC_MISC_ERROR, "Can't read undo data from disk");
1049  }
1050 
1051  return blockUndo;
1052 }
1053 
1055  return RPCHelpMan{
1056  "getblock",
1057  "If verbosity is 0 or false, returns a string that is serialized, "
1058  "hex-encoded data for block 'hash'.\n"
1059  "If verbosity is 1 or true, returns an Object with information about "
1060  "block <hash>.\n"
1061  "If verbosity is 2, returns an Object with information about block "
1062  "<hash> and information about each transaction.\n",
1063  {
1065  "The block hash"},
1066  {"verbosity|verbose", RPCArg::Type::NUM, /* default */ "1",
1067  "0 for hex-encoded data, 1 for a json object, and 2 for json "
1068  "object with transaction data"},
1069  },
1070  {
1071  RPCResult{"for verbosity = 0", RPCResult::Type::STR_HEX, "",
1072  "A string that is serialized, hex-encoded data for block "
1073  "'hash'"},
1074  RPCResult{
1075  "for verbosity = 1",
1077  "",
1078  "",
1079  {
1080  {RPCResult::Type::STR_HEX, "hash",
1081  "the block hash (same as provided)"},
1082  {RPCResult::Type::NUM, "confirmations",
1083  "The number of confirmations, or -1 if the block is not "
1084  "on the main chain"},
1085  {RPCResult::Type::NUM, "size", "The block size"},
1086  {RPCResult::Type::NUM, "height",
1087  "The block height or index"},
1088  {RPCResult::Type::NUM, "version", "The block version"},
1089  {RPCResult::Type::STR_HEX, "versionHex",
1090  "The block version formatted in hexadecimal"},
1091  {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
1093  "tx",
1094  "The transaction ids",
1095  {{RPCResult::Type::STR_HEX, "", "The transaction id"}}},
1096  {RPCResult::Type::NUM_TIME, "time",
1097  "The block time expressed in " + UNIX_EPOCH_TIME},
1098  {RPCResult::Type::NUM_TIME, "mediantime",
1099  "The median block time expressed in " + UNIX_EPOCH_TIME},
1100  {RPCResult::Type::NUM, "nonce", "The nonce"},
1101  {RPCResult::Type::STR_HEX, "bits", "The bits"},
1102  {RPCResult::Type::NUM, "difficulty", "The difficulty"},
1103  {RPCResult::Type::STR_HEX, "chainwork",
1104  "Expected number of hashes required to produce the chain "
1105  "up to this block (in hex)"},
1106  {RPCResult::Type::NUM, "nTx",
1107  "The number of transactions in the block"},
1108  {RPCResult::Type::STR_HEX, "previousblockhash",
1109  /* optional */ true,
1110  "The hash of the previous block (if available)"},
1111  {RPCResult::Type::STR_HEX, "nextblockhash",
1112  /* optional */ true,
1113  "The hash of the next block (if available)"},
1114  }},
1115  RPCResult{"for verbosity = 2",
1117  "",
1118  "",
1119  {
1121  "Same output as verbosity = 1"},
1123  "tx",
1124  "",
1125  {
1127  "",
1128  "",
1129  {
1131  "The transactions in the format of the "
1132  "getrawtransaction RPC. Different from "
1133  "verbosity = 1 \"tx\" result"},
1134  }},
1135  }},
1136  }},
1137  },
1138  RPCExamples{
1139  HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d"
1140  "214adbda81d7e2a3dd146f6ed09\"") +
1141  HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d"
1142  "214adbda81d7e2a3dd146f6ed09\"")},
1143  [&](const RPCHelpMan &self, const Config &config,
1144  const JSONRPCRequest &request) -> UniValue {
1145  BlockHash hash(ParseHashV(request.params[0], "blockhash"));
1146 
1147  int verbosity = 1;
1148  if (!request.params[1].isNull()) {
1149  if (request.params[1].isNum()) {
1150  verbosity = request.params[1].get_int();
1151  } else {
1152  verbosity = request.params[1].get_bool() ? 1 : 0;
1153  }
1154  }
1155 
1156  CBlock block;
1157  const CBlockIndex *pblockindex;
1158  const CBlockIndex *tip;
1159  {
1160  ChainstateManager &chainman =
1161  EnsureAnyChainman(request.context);
1162  LOCK(cs_main);
1163  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
1164  tip = chainman.ActiveTip();
1165 
1166  if (!pblockindex) {
1168  "Block not found");
1169  }
1170 
1171  block = GetBlockChecked(config, pblockindex);
1172  }
1173 
1174  if (verbosity <= 0) {
1175  CDataStream ssBlock(SER_NETWORK,
1177  ssBlock << block;
1178  std::string strHex = HexStr(ssBlock);
1179  return strHex;
1180  }
1181 
1182  return blockToJSON(block, tip, pblockindex, verbosity >= 2);
1183  },
1184  };
1185 }
1186 
1188  return RPCHelpMan{
1189  "pruneblockchain",
1190  "",
1191  {
1193  "The block height to prune up to. May be set to a discrete "
1194  "height, or to a " +
1195  UNIX_EPOCH_TIME +
1196  "\n"
1197  " to prune blocks whose block time is at "
1198  "least 2 hours older than the provided timestamp."},
1199  },
1200  RPCResult{RPCResult::Type::NUM, "", "Height of the last block pruned"},
1201  RPCExamples{HelpExampleCli("pruneblockchain", "1000") +
1202  HelpExampleRpc("pruneblockchain", "1000")},
1203  [&](const RPCHelpMan &self, const Config &config,
1204  const JSONRPCRequest &request) -> UniValue {
1205  if (!fPruneMode) {
1206  throw JSONRPCError(
1208  "Cannot prune blocks because node is not in prune mode.");
1209  }
1210 
1211  ChainstateManager &chainman = EnsureAnyChainman(request.context);
1212  LOCK(cs_main);
1213  CChainState &active_chainstate = chainman.ActiveChainstate();
1214  CChain &active_chain = active_chainstate.m_chain;
1215 
1216  int heightParam = request.params[0].get_int();
1217  if (heightParam < 0) {
1219  "Negative block height.");
1220  }
1221 
1222  // Height value more than a billion is too high to be a block
1223  // height, and too low to be a block time (corresponds to timestamp
1224  // from Sep 2001).
1225  if (heightParam > 1000000000) {
1226  // Add a 2 hour buffer to include blocks which might have had
1227  // old timestamps
1228  CBlockIndex *pindex = active_chain.FindEarliestAtLeast(
1229  heightParam - TIMESTAMP_WINDOW, 0);
1230  if (!pindex) {
1232  "Could not find block with at least the "
1233  "specified timestamp.");
1234  }
1235  heightParam = pindex->nHeight;
1236  }
1237 
1238  unsigned int height = (unsigned int)heightParam;
1239  unsigned int chainHeight = (unsigned int)active_chain.Height();
1240  if (chainHeight < config.GetChainParams().PruneAfterHeight()) {
1242  "Blockchain is too short for pruning.");
1243  } else if (height > chainHeight) {
1244  throw JSONRPCError(
1246  "Blockchain is shorter than the attempted prune height.");
1247  } else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
1249  "Attempt to prune blocks close to the tip. "
1250  "Retaining the minimum number of blocks.\n");
1251  height = chainHeight - MIN_BLOCKS_TO_KEEP;
1252  }
1253 
1254  PruneBlockFilesManual(active_chainstate, height);
1255  const CBlockIndex *block = active_chain.Tip();
1256  CHECK_NONFATAL(block);
1257  while (block->pprev && (block->pprev->nStatus.hasData())) {
1258  block = block->pprev;
1259  }
1260  return uint64_t(block->nHeight);
1261  },
1262  };
1263 }
1264 
1265 static CoinStatsHashType ParseHashType(const std::string &hash_type_input) {
1266  if (hash_type_input == "hash_serialized") {
1268  } else if (hash_type_input == "muhash") {
1270  } else if (hash_type_input == "none") {
1271  return CoinStatsHashType::NONE;
1272  } else {
1273  throw JSONRPCError(
1275  strprintf("%s is not a valid hash_type", hash_type_input));
1276  }
1277 }
1278 
1280  return RPCHelpMan{
1281  "gettxoutsetinfo",
1282  "Returns statistics about the unspent transaction output set.\n"
1283  "Note this call may take some time if you are not using "
1284  "coinstatsindex.\n",
1285  {
1286  {"hash_type", RPCArg::Type::STR, /* default */ "hash_serialized",
1287  "Which UTXO set hash should be calculated. Options: "
1288  "'hash_serialized' (the legacy algorithm), 'muhash', 'none'."},
1289  {"hash_or_height",
1292  "The block hash or height of the target height (only available "
1293  "with coinstatsindex).",
1294  "",
1295  {"", "string or numeric"}},
1296  {"use_index", RPCArg::Type::BOOL, /* default */ "true",
1297  "Use coinstatsindex, if available."},
1298  },
1299  RPCResult{
1301  "",
1302  "",
1303  {
1304  {RPCResult::Type::NUM, "height",
1305  "The current block height (index)"},
1306  {RPCResult::Type::STR_HEX, "bestblock",
1307  "The hash of the block at the tip of the chain"},
1308  {RPCResult::Type::NUM, "txouts",
1309  "The number of unspent transaction outputs"},
1310  {RPCResult::Type::NUM, "bogosize",
1311  "Database-independent, meaningless metric indicating "
1312  "the UTXO set size"},
1313  {RPCResult::Type::STR_HEX, "hash_serialized",
1314  /* optional */ true,
1315  "The serialized hash (only present if 'hash_serialized' "
1316  "hash_type is chosen)"},
1317  {RPCResult::Type::STR_HEX, "muhash", /* optional */ true,
1318  "The serialized hash (only present if 'muhash' "
1319  "hash_type is chosen)"},
1320  {RPCResult::Type::NUM, "transactions",
1321  "The number of transactions with unspent outputs (not "
1322  "available when coinstatsindex is used)"},
1323  {RPCResult::Type::NUM, "disk_size",
1324  "The estimated size of the chainstate on disk (not "
1325  "available when coinstatsindex is used)"},
1326  {RPCResult::Type::STR_AMOUNT, "total_amount",
1327  "The total amount"},
1328  {RPCResult::Type::STR_AMOUNT, "total_unspendable_amount",
1329  "The total amount of coins permanently excluded from the UTXO "
1330  "set (only available if coinstatsindex is used)"},
1332  "block_info",
1333  "Info on amounts in the block at this block height (only "
1334  "available if coinstatsindex is used)",
1335  {{RPCResult::Type::STR_AMOUNT, "prevout_spent", ""},
1336  {RPCResult::Type::STR_AMOUNT, "coinbase", ""},
1337  {RPCResult::Type::STR_AMOUNT, "new_outputs_ex_coinbase", ""},
1338  {RPCResult::Type::STR_AMOUNT, "unspendable", ""},
1340  "unspendables",
1341  "Detailed view of the unspendable categories",
1342  {
1343  {RPCResult::Type::STR_AMOUNT, "genesis_block", ""},
1344  {RPCResult::Type::STR_AMOUNT, "bip30",
1345  "Transactions overridden by duplicates (no longer "
1346  "possible with BIP30)"},
1347  {RPCResult::Type::STR_AMOUNT, "scripts",
1348  "Amounts sent to scripts that are unspendable (for "
1349  "example OP_RETURN outputs)"},
1350  {RPCResult::Type::STR_AMOUNT, "unclaimed_rewards",
1351  "Fee rewards that miners did not claim in their "
1352  "coinbase transaction"},
1353  }}}},
1354  }},
1355  RPCExamples{
1356  HelpExampleCli("gettxoutsetinfo", "") +
1357  HelpExampleCli("gettxoutsetinfo", R"("none")") +
1358  HelpExampleCli("gettxoutsetinfo", R"("none" 1000)") +
1360  "gettxoutsetinfo",
1361  R"("none" '"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"')") +
1362  HelpExampleRpc("gettxoutsetinfo", "") +
1363  HelpExampleRpc("gettxoutsetinfo", R"("none")") +
1364  HelpExampleRpc("gettxoutsetinfo", R"("none", 1000)") +
1366  "gettxoutsetinfo",
1367  R"("none", "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09")")},
1368  [&](const RPCHelpMan &self, const Config &config,
1369  const JSONRPCRequest &request) -> UniValue {
1370  UniValue ret(UniValue::VOBJ);
1371 
1372  CBlockIndex *pindex{nullptr};
1373  const CoinStatsHashType hash_type{
1374  request.params[0].isNull()
1376  : ParseHashType(request.params[0].get_str())};
1377  CCoinsStats stats{hash_type};
1378  stats.index_requested =
1379  request.params[2].isNull() || request.params[2].get_bool();
1380 
1381  NodeContext &node = EnsureAnyNodeContext(request.context);
1382  ChainstateManager &chainman = EnsureChainman(node);
1383  CChainState &active_chainstate = chainman.ActiveChainstate();
1384  active_chainstate.ForceFlushStateToDisk();
1385 
1386  CCoinsView *coins_view;
1387  BlockManager *blockman;
1388  {
1389  LOCK(::cs_main);
1390  coins_view = &active_chainstate.CoinsDB();
1391  blockman = &active_chainstate.m_blockman;
1392  pindex = blockman->LookupBlockIndex(coins_view->GetBestBlock());
1393  }
1394 
1395  if (!request.params[1].isNull()) {
1396  if (!g_coin_stats_index) {
1398  "Querying specific block heights "
1399  "requires coinstatsindex");
1400  }
1401 
1402  if (stats.m_hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1404  "hash_serialized hash type cannot be "
1405  "queried for a specific block");
1406  }
1407 
1408  pindex = ParseHashOrHeight(request.params[1], chainman);
1409  }
1410 
1411  if (GetUTXOStats(coins_view, *blockman, stats,
1412  node.rpc_interruption_point, pindex)) {
1413  ret.pushKV("height", int64_t(stats.nHeight));
1414  ret.pushKV("bestblock", stats.hashBlock.GetHex());
1415  ret.pushKV("txouts", int64_t(stats.nTransactionOutputs));
1416  ret.pushKV("bogosize", int64_t(stats.nBogoSize));
1417  if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1418  ret.pushKV("hash_serialized",
1419  stats.hashSerialized.GetHex());
1420  }
1421  if (hash_type == CoinStatsHashType::MUHASH) {
1422  ret.pushKV("muhash", stats.hashSerialized.GetHex());
1423  }
1424  ret.pushKV("total_amount", stats.nTotalAmount);
1425  if (!stats.index_used) {
1426  ret.pushKV("transactions",
1427  static_cast<int64_t>(stats.nTransactions));
1428  ret.pushKV("disk_size", stats.nDiskSize);
1429  } else {
1430  ret.pushKV("total_unspendable_amount",
1431  stats.total_unspendable_amount);
1432 
1433  CCoinsStats prev_stats{hash_type};
1434 
1435  if (pindex->nHeight > 0) {
1436  GetUTXOStats(coins_view, *blockman, prev_stats,
1438  pindex->pprev);
1439  }
1440 
1441  UniValue block_info(UniValue::VOBJ);
1442  block_info.pushKV(
1443  "prevout_spent",
1444  stats.total_prevout_spent_amount -
1445  prev_stats.total_prevout_spent_amount);
1446  block_info.pushKV("coinbase",
1447  stats.total_coinbase_amount -
1448  prev_stats.total_coinbase_amount);
1449  block_info.pushKV(
1450  "new_outputs_ex_coinbase",
1451  stats.total_new_outputs_ex_coinbase_amount -
1452  prev_stats.total_new_outputs_ex_coinbase_amount);
1453  block_info.pushKV("unspendable",
1454  stats.total_unspendable_amount -
1455  prev_stats.total_unspendable_amount);
1456 
1457  UniValue unspendables(UniValue::VOBJ);
1458  unspendables.pushKV(
1459  "genesis_block",
1460  stats.total_unspendables_genesis_block -
1461  prev_stats.total_unspendables_genesis_block);
1462  unspendables.pushKV(
1463  "bip30", stats.total_unspendables_bip30 -
1464  prev_stats.total_unspendables_bip30);
1465  unspendables.pushKV(
1466  "scripts", stats.total_unspendables_scripts -
1467  prev_stats.total_unspendables_scripts);
1468  unspendables.pushKV(
1469  "unclaimed_rewards",
1470  stats.total_unspendables_unclaimed_rewards -
1471  prev_stats.total_unspendables_unclaimed_rewards);
1472  block_info.pushKV("unspendables", unspendables);
1473 
1474  ret.pushKV("block_info", block_info);
1475  }
1476  } else {
1477  if (g_coin_stats_index) {
1478  const IndexSummary summary{
1479  g_coin_stats_index->GetSummary()};
1480 
1481  if (!summary.synced) {
1482  throw JSONRPCError(
1484  strprintf("Unable to read UTXO set because "
1485  "coinstatsindex is still syncing. "
1486  "Current height: %d",
1487  summary.best_block_height));
1488  }
1489  }
1491  "Unable to read UTXO set");
1492  }
1493  return ret;
1494  },
1495  };
1496 }
1497 
1499  return RPCHelpMan{
1500  "gettxout",
1501  "Returns details about an unspent transaction output.\n",
1502  {
1504  "The transaction id"},
1505  {"n", RPCArg::Type::NUM, RPCArg::Optional::NO, "vout number"},
1506  {"include_mempool", RPCArg::Type::BOOL, /* default */ "true",
1507  "Whether to include the mempool. Note that an unspent output that "
1508  "is spent in the mempool won't appear."},
1509  },
1510  {
1511  RPCResult{"If the UTXO was not found", RPCResult::Type::NONE, "",
1512  ""},
1513  RPCResult{
1514  "Otherwise",
1516  "",
1517  "",
1518  {
1519  {RPCResult::Type::STR_HEX, "bestblock",
1520  "The hash of the block at the tip of the chain"},
1521  {RPCResult::Type::NUM, "confirmations",
1522  "The number of confirmations"},
1523  {RPCResult::Type::STR_AMOUNT, "value",
1524  "The transaction value in " + Currency::get().ticker},
1526  "scriptPubKey",
1527  "",
1528  {
1529  {RPCResult::Type::STR_HEX, "asm", ""},
1530  {RPCResult::Type::STR_HEX, "hex", ""},
1531  {RPCResult::Type::NUM, "reqSigs",
1532  "Number of required signatures"},
1533  {RPCResult::Type::STR_HEX, "type",
1534  "The type, eg pubkeyhash"},
1536  "addresses",
1537  "array of eCash addresses",
1538  {{RPCResult::Type::STR, "address", "eCash address"}}},
1539  }},
1540  {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
1541  }},
1542  },
1543  RPCExamples{"\nGet unspent transactions\n" +
1544  HelpExampleCli("listunspent", "") + "\nView the details\n" +
1545  HelpExampleCli("gettxout", "\"txid\" 1") +
1546  "\nAs a JSON-RPC call\n" +
1547  HelpExampleRpc("gettxout", "\"txid\", 1")},
1548  [&](const RPCHelpMan &self, const Config &config,
1549  const JSONRPCRequest &request) -> UniValue {
1550  NodeContext &node = EnsureAnyNodeContext(request.context);
1551  ChainstateManager &chainman = EnsureChainman(node);
1552  LOCK(cs_main);
1553 
1554  UniValue ret(UniValue::VOBJ);
1555 
1556  TxId txid(ParseHashV(request.params[0], "txid"));
1557  int n = request.params[1].get_int();
1558  COutPoint out(txid, n);
1559  bool fMempool = true;
1560  if (!request.params[2].isNull()) {
1561  fMempool = request.params[2].get_bool();
1562  }
1563 
1564  Coin coin;
1565  CChainState &active_chainstate = chainman.ActiveChainstate();
1566  CCoinsViewCache *coins_view = &active_chainstate.CoinsTip();
1567 
1568  if (fMempool) {
1569  const CTxMemPool &mempool = EnsureMemPool(node);
1570  LOCK(mempool.cs);
1571  CCoinsViewMemPool view(coins_view, mempool);
1572  if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
1573  return NullUniValue;
1574  }
1575  } else {
1576  if (!coins_view->GetCoin(out, coin)) {
1577  return NullUniValue;
1578  }
1579  }
1580 
1581  const CBlockIndex *pindex =
1582  active_chainstate.m_blockman.LookupBlockIndex(
1583  coins_view->GetBestBlock());
1584  ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
1585  if (coin.GetHeight() == MEMPOOL_HEIGHT) {
1586  ret.pushKV("confirmations", 0);
1587  } else {
1588  ret.pushKV("confirmations",
1589  int64_t(pindex->nHeight - coin.GetHeight() + 1));
1590  }
1591  ret.pushKV("value", coin.GetTxOut().nValue);
1593  ScriptPubKeyToUniv(coin.GetTxOut().scriptPubKey, o, true);
1594  ret.pushKV("scriptPubKey", o);
1595  ret.pushKV("coinbase", coin.IsCoinBase());
1596 
1597  return ret;
1598  },
1599  };
1600 }
1601 
1603  return RPCHelpMan{
1604  "verifychain",
1605  "Verifies blockchain database.\n",
1606  {
1607  {"checklevel", RPCArg::Type::NUM,
1608  /* default */ strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL),
1609  strprintf("How thorough the block verification is:\n - %s",
1610  Join(CHECKLEVEL_DOC, "\n- "))},
1611  {"nblocks", RPCArg::Type::NUM,
1612  /* default */ strprintf("%d, 0=all", DEFAULT_CHECKBLOCKS),
1613  "The number of blocks to check."},
1614  },
1615  RPCResult{RPCResult::Type::BOOL, "", "Verified or not"},
1616  RPCExamples{HelpExampleCli("verifychain", "") +
1617  HelpExampleRpc("verifychain", "")},
1618  [&](const RPCHelpMan &self, const Config &config,
1619  const JSONRPCRequest &request) -> UniValue {
1620  const int check_level(request.params[0].isNull()
1622  : request.params[0].get_int());
1623  const int check_depth{request.params[1].isNull()
1625  : request.params[1].get_int()};
1626 
1627  ChainstateManager &chainman = EnsureAnyChainman(request.context);
1628  LOCK(cs_main);
1629 
1630  CChainState &active_chainstate = chainman.ActiveChainstate();
1631  return CVerifyDB().VerifyDB(active_chainstate, config,
1632  active_chainstate.CoinsTip(),
1633  check_level, check_depth);
1634  },
1635  };
1636 }
1637 
1638 static void BIP9SoftForkDescPushBack(const CBlockIndex *active_chain_tip,
1639  UniValue &softforks,
1640  const Consensus::Params &consensusParams,
1643  // For BIP9 deployments.
1644  // Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are
1645  // hidden. A timeout value of 0 guarantees a softfork will never be
1646  // activated. This is used when merging logic to implement a proposed
1647  // softfork without a specified deployment schedule.
1648  if (consensusParams.vDeployments[id].nTimeout <= 1230768000) {
1649  return;
1650  }
1651 
1652  UniValue bip9(UniValue::VOBJ);
1653  const ThresholdState thresholdState = VersionBitsState(
1654  active_chain_tip, consensusParams, id, versionbitscache);
1655  switch (thresholdState) {
1657  bip9.pushKV("status", "defined");
1658  break;
1660  bip9.pushKV("status", "started");
1661  break;
1663  bip9.pushKV("status", "locked_in");
1664  break;
1666  bip9.pushKV("status", "active");
1667  break;
1669  bip9.pushKV("status", "failed");
1670  break;
1671  }
1672  if (ThresholdState::STARTED == thresholdState) {
1673  bip9.pushKV("bit", consensusParams.vDeployments[id].bit);
1674  }
1675  bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
1676  bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
1677  int64_t since_height = VersionBitsStateSinceHeight(
1678  active_chain_tip, consensusParams, id, versionbitscache);
1679  bip9.pushKV("since", since_height);
1680  if (ThresholdState::STARTED == thresholdState) {
1681  UniValue statsUV(UniValue::VOBJ);
1682  BIP9Stats statsStruct =
1683  VersionBitsStatistics(active_chain_tip, consensusParams, id);
1684  statsUV.pushKV("period", statsStruct.period);
1685  statsUV.pushKV("threshold", statsStruct.threshold);
1686  statsUV.pushKV("elapsed", statsStruct.elapsed);
1687  statsUV.pushKV("count", statsStruct.count);
1688  statsUV.pushKV("possible", statsStruct.possible);
1689  bip9.pushKV("statistics", statsUV);
1690  }
1691 
1693  rv.pushKV("type", "bip9");
1694  rv.pushKV("bip9", bip9);
1695  if (ThresholdState::ACTIVE == thresholdState) {
1696  rv.pushKV("height", since_height);
1697  }
1698  rv.pushKV("active", ThresholdState::ACTIVE == thresholdState);
1699 
1700  softforks.pushKV(VersionBitsDeploymentInfo[id].name, rv);
1701 }
1702 
1704  return RPCHelpMan{
1705  "getblockchaininfo",
1706  "Returns an object containing various state info regarding blockchain "
1707  "processing.\n",
1708  {},
1709  RPCResult{
1711  "",
1712  "",
1713  {
1714  {RPCResult::Type::STR, "chain",
1715  "current network name (main, test, regtest)"},
1716  {RPCResult::Type::NUM, "blocks",
1717  "the height of the most-work fully-validated chain. The "
1718  "genesis block has height 0"},
1719  {RPCResult::Type::NUM, "headers",
1720  "the current number of headers we have validated"},
1721  {RPCResult::Type::STR, "bestblockhash",
1722  "the hash of the currently best block"},
1723  {RPCResult::Type::NUM, "difficulty", "the current difficulty"},
1724  {RPCResult::Type::NUM, "mediantime",
1725  "median time for the current best block"},
1726  {RPCResult::Type::NUM, "verificationprogress",
1727  "estimate of verification progress [0..1]"},
1728  {RPCResult::Type::BOOL, "initialblockdownload",
1729  "(debug information) estimate of whether this node is in "
1730  "Initial Block Download mode"},
1731  {RPCResult::Type::STR_HEX, "chainwork",
1732  "total amount of work in active chain, in hexadecimal"},
1733  {RPCResult::Type::NUM, "size_on_disk",
1734  "the estimated size of the block and undo files on disk"},
1735  {RPCResult::Type::BOOL, "pruned",
1736  "if the blocks are subject to pruning"},
1737  {RPCResult::Type::NUM, "pruneheight",
1738  "lowest-height complete block stored (only present if pruning "
1739  "is enabled)"},
1740  {RPCResult::Type::BOOL, "automatic_pruning",
1741  "whether automatic pruning is enabled (only present if "
1742  "pruning is enabled)"},
1743  {RPCResult::Type::NUM, "prune_target_size",
1744  "the target size used by pruning (only present if automatic "
1745  "pruning is enabled)"},
1747  "softforks",
1748  "status of softforks",
1749  {
1751  "xxxx",
1752  "name of the softfork",
1753  {
1754  {RPCResult::Type::STR, "type",
1755  "one of \"buried\", \"bip9\""},
1757  "bip9",
1758  "status of bip9 softforks (only for \"bip9\" type)",
1759  {
1760  {RPCResult::Type::STR, "status",
1761  "one of \"defined\", \"started\", "
1762  "\"locked_in\", \"active\", \"failed\""},
1763  {RPCResult::Type::NUM, "bit",
1764  "the bit (0-28) in the block version field "
1765  "used to signal this softfork (only for "
1766  "\"started\" status)"},
1767  {RPCResult::Type::NUM_TIME, "start_time",
1768  "the minimum median time past of a block at "
1769  "which the bit gains its meaning"},
1770  {RPCResult::Type::NUM_TIME, "timeout",
1771  "the median time past of a block at which the "
1772  "deployment is considered failed if not yet "
1773  "locked in"},
1774  {RPCResult::Type::NUM, "since",
1775  "height of the first block to which the status "
1776  "applies"},
1778  "statistics",
1779  "numeric statistics about BIP9 signalling for "
1780  "a softfork",
1781  {
1782  {RPCResult::Type::NUM, "period",
1783  "the length in blocks of the BIP9 "
1784  "signalling period"},
1785  {RPCResult::Type::NUM, "threshold",
1786  "the number of blocks with the version "
1787  "bit set required to activate the "
1788  "feature"},
1789  {RPCResult::Type::NUM, "elapsed",
1790  "the number of blocks elapsed since the "
1791  "beginning of the current period"},
1792  {RPCResult::Type::NUM, "count",
1793  "the number of blocks with the version "
1794  "bit set in the current period"},
1795  {RPCResult::Type::BOOL, "possible",
1796  "returns false if there are not enough "
1797  "blocks left in this period to pass "
1798  "activation threshold"},
1799  }},
1800  }},
1801  {RPCResult::Type::NUM, "height",
1802  "height of the first block which the rules are or "
1803  "will be enforced (only for \"buried\" type, or "
1804  "\"bip9\" type with \"active\" status)"},
1805  {RPCResult::Type::BOOL, "active",
1806  "true if the rules are enforced for the mempool and "
1807  "the next block"},
1808  }},
1809  }},
1810  {RPCResult::Type::STR, "warnings",
1811  "any network and blockchain warnings"},
1812  }},
1813  RPCExamples{HelpExampleCli("getblockchaininfo", "") +
1814  HelpExampleRpc("getblockchaininfo", "")},
1815  [&](const RPCHelpMan &self, const Config &config,
1816  const JSONRPCRequest &request) -> UniValue {
1817  const CChainParams &chainparams = config.GetChainParams();
1818 
1819  ChainstateManager &chainman = EnsureAnyChainman(request.context);
1820  LOCK(cs_main);
1821  CChainState &active_chainstate = chainman.ActiveChainstate();
1822 
1823  const CBlockIndex *tip = active_chainstate.m_chain.Tip();
1824  CHECK_NONFATAL(tip);
1825  const int height = tip->nHeight;
1826 
1827  UniValue obj(UniValue::VOBJ);
1828  obj.pushKV("chain", chainparams.NetworkIDString());
1829  obj.pushKV("blocks", height);
1830  obj.pushKV("headers",
1832  obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
1833  obj.pushKV("difficulty", double(GetDifficulty(tip)));
1834  obj.pushKV("mediantime", int64_t(tip->GetMedianTimePast()));
1835  obj.pushKV("verificationprogress",
1836  GuessVerificationProgress(Params().TxData(), tip));
1837  obj.pushKV("initialblockdownload",
1838  active_chainstate.IsInitialBlockDownload());
1839  obj.pushKV("chainwork", tip->nChainWork.GetHex());
1840  obj.pushKV("size_on_disk", CalculateCurrentUsage());
1841  obj.pushKV("pruned", fPruneMode);
1842 
1843  if (fPruneMode) {
1844  const CBlockIndex *block = tip;
1845  CHECK_NONFATAL(block);
1846  while (block->pprev && (block->pprev->nStatus.hasData())) {
1847  block = block->pprev;
1848  }
1849 
1850  obj.pushKV("pruneheight", block->nHeight);
1851 
1852  // if 0, execution bypasses the whole if block.
1853  bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1);
1854  obj.pushKV("automatic_pruning", automatic_pruning);
1855  if (automatic_pruning) {
1856  obj.pushKV("prune_target_size", nPruneTarget);
1857  }
1858  }
1859 
1860  UniValue softforks(UniValue::VOBJ);
1861  for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS;
1862  i++) {
1863  BIP9SoftForkDescPushBack(tip, softforks,
1864  chainparams.GetConsensus(),
1866  }
1867  obj.pushKV("softforks", softforks);
1868 
1869  obj.pushKV("warnings", GetWarnings(false).original);
1870  return obj;
1871  },
1872  };
1873 }
1874 
1877  bool operator()(const CBlockIndex *a, const CBlockIndex *b) const {
1878  // Make sure that unequal blocks with the same height do not compare
1879  // equal. Use the pointers themselves to make a distinction.
1880  if (a->nHeight != b->nHeight) {
1881  return (a->nHeight > b->nHeight);
1882  }
1883 
1884  return a < b;
1885  }
1886 };
1887 
1889  return RPCHelpMan{
1890  "getchaintips",
1891  "Return information about all known tips in the block tree, including "
1892  "the main chain as well as orphaned branches.\n",
1893  {},
1894  RPCResult{
1896  "",
1897  "",
1899  "",
1900  "",
1901  {
1902  {RPCResult::Type::NUM, "height", "height of the chain tip"},
1903  {RPCResult::Type::STR_HEX, "hash", "block hash of the tip"},
1904  {RPCResult::Type::NUM, "branchlen",
1905  "zero for main chain, otherwise length of branch connecting "
1906  "the tip to the main chain"},
1907  {RPCResult::Type::STR, "status",
1908  "status of the chain, \"active\" for the main chain\n"
1909  "Possible values for status:\n"
1910  "1. \"invalid\" This branch contains at "
1911  "least one invalid block\n"
1912  "2. \"parked\" This branch contains at "
1913  "least one parked block\n"
1914  "3. \"headers-only\" Not all blocks for this "
1915  "branch are available, but the headers are valid\n"
1916  "4. \"valid-headers\" All blocks are available for "
1917  "this branch, but they were never fully validated\n"
1918  "5. \"valid-fork\" This branch is not part of "
1919  "the active chain, but is fully validated\n"
1920  "6. \"active\" This is the tip of the "
1921  "active main chain, which is certainly valid"},
1922  }}}},
1923  RPCExamples{HelpExampleCli("getchaintips", "") +
1924  HelpExampleRpc("getchaintips", "")},
1925  [&](const RPCHelpMan &self, const Config &config,
1926  const JSONRPCRequest &request) -> UniValue {
1927  ChainstateManager &chainman = EnsureAnyChainman(request.context);
1928  LOCK(cs_main);
1929  CChain &active_chain = chainman.ActiveChain();
1930 
1942  std::set<const CBlockIndex *, CompareBlocksByHeight> setTips;
1943  std::set<const CBlockIndex *> setOrphans;
1944  std::set<const CBlockIndex *> setPrevs;
1945 
1946  for (const std::pair<const BlockHash, CBlockIndex *> &item :
1947  chainman.BlockIndex()) {
1948  if (!active_chain.Contains(item.second)) {
1949  setOrphans.insert(item.second);
1950  setPrevs.insert(item.second->pprev);
1951  }
1952  }
1953 
1954  for (std::set<const CBlockIndex *>::iterator it =
1955  setOrphans.begin();
1956  it != setOrphans.end(); ++it) {
1957  if (setPrevs.erase(*it) == 0) {
1958  setTips.insert(*it);
1959  }
1960  }
1961 
1962  // Always report the currently active tip.
1963  setTips.insert(active_chain.Tip());
1964 
1965  /* Construct the output array. */
1966  UniValue res(UniValue::VARR);
1967  for (const CBlockIndex *block : setTips) {
1968  UniValue obj(UniValue::VOBJ);
1969  obj.pushKV("height", block->nHeight);
1970  obj.pushKV("hash", block->phashBlock->GetHex());
1971 
1972  const int branchLen =
1973  block->nHeight - active_chain.FindFork(block)->nHeight;
1974  obj.pushKV("branchlen", branchLen);
1975 
1976  std::string status;
1977  if (active_chain.Contains(block)) {
1978  // This block is part of the currently active chain.
1979  status = "active";
1980  } else if (block->nStatus.isInvalid()) {
1981  // This block or one of its ancestors is invalid.
1982  status = "invalid";
1983  } else if (block->nStatus.isOnParkedChain()) {
1984  // This block or one of its ancestors is parked.
1985  status = "parked";
1986  } else if (!block->HaveTxsDownloaded()) {
1987  // This block cannot be connected because full block data
1988  // for it or one of its parents is missing.
1989  status = "headers-only";
1990  } else if (block->IsValid(BlockValidity::SCRIPTS)) {
1991  // This block is fully validated, but no longer part of the
1992  // active chain. It was probably the active block once, but
1993  // was reorganized.
1994  status = "valid-fork";
1995  } else if (block->IsValid(BlockValidity::TREE)) {
1996  // The headers for this block are valid, but it has not been
1997  // validated. It was probably never part of the most-work
1998  // chain.
1999  status = "valid-headers";
2000  } else {
2001  // No clue.
2002  status = "unknown";
2003  }
2004  obj.pushKV("status", status);
2005 
2006  res.push_back(obj);
2007  }
2008 
2009  return res;
2010  },
2011  };
2012 }
2013 
2015  // Make sure this call is atomic in the pool.
2016  LOCK(pool.cs);
2017  UniValue ret(UniValue::VOBJ);
2018  ret.pushKV("loaded", pool.IsLoaded());
2019  ret.pushKV("size", (int64_t)pool.size());
2020  ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
2021  ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
2022  size_t maxmempool =
2023  gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
2024  ret.pushKV("maxmempool", (int64_t)maxmempool);
2025  ret.pushKV(
2026  "mempoolminfee",
2027  std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK());
2028  ret.pushKV("minrelaytxfee", ::minRelayTxFee.GetFeePerK());
2029  ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()});
2030  return ret;
2031 }
2032 
2034  return RPCHelpMan{
2035  "getmempoolinfo",
2036  "Returns details on the active state of the TX memory pool.\n",
2037  {},
2038  RPCResult{
2040  "",
2041  "",
2042  {
2043  {RPCResult::Type::BOOL, "loaded",
2044  "True if the mempool is fully loaded"},
2045  {RPCResult::Type::NUM, "size", "Current tx count"},
2046  {RPCResult::Type::NUM, "bytes", "Sum of all transaction sizes"},
2047  {RPCResult::Type::NUM, "usage",
2048  "Total memory usage for the mempool"},
2049  {RPCResult::Type::NUM, "maxmempool",
2050  "Maximum memory usage for the mempool"},
2051  {RPCResult::Type::STR_AMOUNT, "mempoolminfee",
2052  "Minimum fee rate in " + Currency::get().ticker +
2053  "/kB for tx to be accepted. Is the maximum of "
2054  "minrelaytxfee and minimum mempool fee"},
2055  {RPCResult::Type::STR_AMOUNT, "minrelaytxfee",
2056  "Current minimum relay fee for transactions"},
2057  {RPCResult::Type::NUM, "unbroadcastcount",
2058  "Current number of transactions that haven't passed initial "
2059  "broadcast yet"},
2060  }},
2061  RPCExamples{HelpExampleCli("getmempoolinfo", "") +
2062  HelpExampleRpc("getmempoolinfo", "")},
2063  [&](const RPCHelpMan &self, const Config &config,
2064  const JSONRPCRequest &request) -> UniValue {
2065  return MempoolInfoToJSON(EnsureAnyMemPool(request.context));
2066  },
2067  };
2068 }
2069 
2071  return RPCHelpMan{
2072  "preciousblock",
2073  "Treats a block as if it were received before others with the same "
2074  "work.\n"
2075  "\nA later preciousblock call can override the effect of an earlier "
2076  "one.\n"
2077  "\nThe effects of preciousblock are not retained across restarts.\n",
2078  {
2080  "the hash of the block to mark as precious"},
2081  },
2083  RPCExamples{HelpExampleCli("preciousblock", "\"blockhash\"") +
2084  HelpExampleRpc("preciousblock", "\"blockhash\"")},
2085  [&](const RPCHelpMan &self, const Config &config,
2086  const JSONRPCRequest &request) -> UniValue {
2087  BlockHash hash(ParseHashV(request.params[0], "blockhash"));
2088  CBlockIndex *pblockindex;
2089 
2090  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2091  {
2092  LOCK(cs_main);
2093  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
2094  if (!pblockindex) {
2096  "Block not found");
2097  }
2098  }
2099 
2100  BlockValidationState state;
2101  chainman.ActiveChainstate().PreciousBlock(config, state,
2102  pblockindex);
2103 
2104  if (!state.IsValid()) {
2106  }
2107 
2108  return NullUniValue;
2109  },
2110  };
2111 }
2112 
2114  return RPCHelpMan{
2115  "finalizeblock",
2116  "Treats a block as final. It cannot be reorged. Any chain\n"
2117  "that does not contain this block is invalid. Used on a less\n"
2118  "work chain, it can effectively PUT YOU OUT OF CONSENSUS.\n"
2119  "USE WITH CAUTION!\n",
2120  {
2122  "the hash of the block to mark as invalid"},
2123  },
2125  RPCExamples{HelpExampleCli("finalizeblock", "\"blockhash\"") +
2126  HelpExampleRpc("finalizeblock", "\"blockhash\"")},
2127  [&](const RPCHelpMan &self, const Config &config,
2128  const JSONRPCRequest &request) -> UniValue {
2129  std::string strHash = request.params[0].get_str();
2130  BlockHash hash(uint256S(strHash));
2131  BlockValidationState state;
2132 
2133  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2134  CBlockIndex *pblockindex = nullptr;
2135  {
2136  LOCK(cs_main);
2137  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
2138  if (!pblockindex) {
2140  "Block not found");
2141  }
2142  } // end of locked cs_main scope
2143 
2144  chainman.ActiveChainstate().FinalizeBlock(config, state,
2145  pblockindex);
2146 
2147  if (state.IsValid()) {
2148  chainman.ActiveChainstate().ActivateBestChain(config, state);
2149  }
2150 
2151  if (!state.IsValid()) {
2152  throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
2153  }
2154 
2155  return NullUniValue;
2156  },
2157  };
2158 }
2159 
2161  return RPCHelpMan{
2162  "invalidateblock",
2163  "Permanently marks a block as invalid, as if it violated a consensus "
2164  "rule.\n",
2165  {
2167  "the hash of the block to mark as invalid"},
2168  },
2170  RPCExamples{HelpExampleCli("invalidateblock", "\"blockhash\"") +
2171  HelpExampleRpc("invalidateblock", "\"blockhash\"")},
2172  [&](const RPCHelpMan &self, const Config &config,
2173  const JSONRPCRequest &request) -> UniValue {
2174  const BlockHash hash(ParseHashV(request.params[0], "blockhash"));
2175  BlockValidationState state;
2176 
2177  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2178  CBlockIndex *pblockindex;
2179  {
2180  LOCK(cs_main);
2181  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
2182  if (!pblockindex) {
2184  "Block not found");
2185  }
2186  }
2187  chainman.ActiveChainstate().InvalidateBlock(config, state,
2188  pblockindex);
2189 
2190  if (state.IsValid()) {
2191  chainman.ActiveChainstate().ActivateBestChain(config, state);
2192  }
2193 
2194  if (!state.IsValid()) {
2195  throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
2196  }
2197 
2198  return NullUniValue;
2199  },
2200  };
2201 }
2202 
2204  return RPCHelpMan{
2205  "parkblock",
2206  "Marks a block as parked.\n",
2207  {
2209  "the hash of the block to park"},
2210  },
2212  RPCExamples{HelpExampleCli("parkblock", "\"blockhash\"") +
2213  HelpExampleRpc("parkblock", "\"blockhash\"")},
2214  [&](const RPCHelpMan &self, const Config &config,
2215  const JSONRPCRequest &request) -> UniValue {
2216  const std::string strHash = request.params[0].get_str();
2217  const BlockHash hash(uint256S(strHash));
2218  BlockValidationState state;
2219 
2220  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2221  CBlockIndex *pblockindex = nullptr;
2222  {
2223  LOCK(cs_main);
2224  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
2225  if (!pblockindex) {
2227  "Block not found");
2228  }
2229  }
2230  chainman.ActiveChainstate().ParkBlock(config, state, pblockindex);
2231 
2232  if (state.IsValid()) {
2233  chainman.ActiveChainstate().ActivateBestChain(config, state);
2234  }
2235 
2236  if (!state.IsValid()) {
2238  }
2239 
2240  return NullUniValue;
2241  },
2242  };
2243 }
2244 
2246  return RPCHelpMan{
2247  "reconsiderblock",
2248  "Removes invalidity status of a block, its ancestors and its"
2249  "descendants, reconsider them for activation.\n"
2250  "This can be used to undo the effects of invalidateblock.\n",
2251  {
2253  "the hash of the block to reconsider"},
2254  },
2256  RPCExamples{HelpExampleCli("reconsiderblock", "\"blockhash\"") +
2257  HelpExampleRpc("reconsiderblock", "\"blockhash\"")},
2258  [&](const RPCHelpMan &self, const Config &config,
2259  const JSONRPCRequest &request) -> UniValue {
2260  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2261  const BlockHash hash(ParseHashV(request.params[0], "blockhash"));
2262 
2263  {
2264  LOCK(cs_main);
2265  CBlockIndex *pblockindex =
2266  chainman.m_blockman.LookupBlockIndex(hash);
2267  if (!pblockindex) {
2269  "Block not found");
2270  }
2271 
2272  chainman.ActiveChainstate().ResetBlockFailureFlags(pblockindex);
2273  }
2274 
2275  BlockValidationState state;
2276  chainman.ActiveChainstate().ActivateBestChain(config, state);
2277 
2278  if (!state.IsValid()) {
2279  throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
2280  }
2281 
2282  return NullUniValue;
2283  },
2284  };
2285 }
2286 
2288  return RPCHelpMan{
2289  "unparkblock",
2290  "Removes parked status of a block and its descendants, reconsider "
2291  "them for activation.\n"
2292  "This can be used to undo the effects of parkblock.\n",
2293  {
2295  "the hash of the block to unpark"},
2296  },
2298  RPCExamples{HelpExampleCli("unparkblock", "\"blockhash\"") +
2299  HelpExampleRpc("unparkblock", "\"blockhash\"")},
2300  [&](const RPCHelpMan &self, const Config &config,
2301  const JSONRPCRequest &request) -> UniValue {
2302  const std::string strHash = request.params[0].get_str();
2303  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2304  const BlockHash hash(uint256S(strHash));
2305 
2306  {
2307  LOCK(cs_main);
2308 
2309  CBlockIndex *pblockindex =
2310  chainman.m_blockman.LookupBlockIndex(hash);
2311  if (!pblockindex) {
2313  "Block not found");
2314  }
2315 
2316  chainman.ActiveChainstate().UnparkBlockAndChildren(pblockindex);
2317  }
2318 
2319  BlockValidationState state;
2320  chainman.ActiveChainstate().ActivateBestChain(config, state);
2321 
2322  if (!state.IsValid()) {
2324  }
2325 
2326  return NullUniValue;
2327  },
2328  };
2329 }
2330 
2332  return RPCHelpMan{
2333  "getchaintxstats",
2334  "Compute statistics about the total number and rate of transactions "
2335  "in the chain.\n",
2336  {
2337  {"nblocks", RPCArg::Type::NUM, /* default */ "one month",
2338  "Size of the window in number of blocks"},
2339  {"blockhash", RPCArg::Type::STR_HEX, /* default */ "chain tip",
2340  "The hash of the block that ends the window."},
2341  },
2343  "",
2344  "",
2345  {
2346  {RPCResult::Type::NUM_TIME, "time",
2347  "The timestamp for the final block in the window, "
2348  "expressed in " +
2349  UNIX_EPOCH_TIME},
2350  {RPCResult::Type::NUM, "txcount",
2351  "The total number of transactions in the chain up to "
2352  "that point"},
2353  {RPCResult::Type::STR_HEX, "window_final_block_hash",
2354  "The hash of the final block in the window"},
2355  {RPCResult::Type::NUM, "window_final_block_height",
2356  "The height of the final block in the window."},
2357  {RPCResult::Type::NUM, "window_block_count",
2358  "Size of the window in number of blocks"},
2359  {RPCResult::Type::NUM, "window_tx_count",
2360  "The number of transactions in the window. Only "
2361  "returned if \"window_block_count\" is > 0"},
2362  {RPCResult::Type::NUM, "window_interval",
2363  "The elapsed time in the window in seconds. Only "
2364  "returned if \"window_block_count\" is > 0"},
2365  {RPCResult::Type::NUM, "txrate",
2366  "The average rate of transactions per second in the "
2367  "window. Only returned if \"window_interval\" is > 0"},
2368  }},
2369  RPCExamples{HelpExampleCli("getchaintxstats", "") +
2370  HelpExampleRpc("getchaintxstats", "2016")},
2371  [&](const RPCHelpMan &self, const Config &config,
2372  const JSONRPCRequest &request) -> UniValue {
2373  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2374  const CBlockIndex *pindex;
2375 
2376  // By default: 1 month
2377  int blockcount =
2378  30 * 24 * 60 * 60 /
2379  config.GetChainParams().GetConsensus().nPowTargetSpacing;
2380 
2381  if (request.params[1].isNull()) {
2382  LOCK(cs_main);
2383  pindex = chainman.ActiveTip();
2384  } else {
2385  BlockHash hash(ParseHashV(request.params[1], "blockhash"));
2386  LOCK(cs_main);
2387  pindex = chainman.m_blockman.LookupBlockIndex(hash);
2388  if (!pindex) {
2390  "Block not found");
2391  }
2392  if (!chainman.ActiveChain().Contains(pindex)) {
2394  "Block is not in main chain");
2395  }
2396  }
2397 
2398  CHECK_NONFATAL(pindex != nullptr);
2399 
2400  if (request.params[0].isNull()) {
2401  blockcount =
2402  std::max(0, std::min(blockcount, pindex->nHeight - 1));
2403  } else {
2404  blockcount = request.params[0].get_int();
2405 
2406  if (blockcount < 0 ||
2407  (blockcount > 0 && blockcount >= pindex->nHeight)) {
2409  "Invalid block count: "
2410  "should be between 0 and "
2411  "the block's height - 1");
2412  }
2413  }
2414 
2415  const CBlockIndex *pindexPast =
2416  pindex->GetAncestor(pindex->nHeight - blockcount);
2417  int nTimeDiff =
2418  pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
2419  int nTxDiff =
2420  pindex->GetChainTxCount() - pindexPast->GetChainTxCount();
2421 
2422  UniValue ret(UniValue::VOBJ);
2423  ret.pushKV("time", pindex->GetBlockTime());
2424  ret.pushKV("txcount", pindex->GetChainTxCount());
2425  ret.pushKV("window_final_block_hash",
2426  pindex->GetBlockHash().GetHex());
2427  ret.pushKV("window_final_block_height", pindex->nHeight);
2428  ret.pushKV("window_block_count", blockcount);
2429  if (blockcount > 0) {
2430  ret.pushKV("window_tx_count", nTxDiff);
2431  ret.pushKV("window_interval", nTimeDiff);
2432  if (nTimeDiff > 0) {
2433  ret.pushKV("txrate", double(nTxDiff) / nTimeDiff);
2434  }
2435  }
2436 
2437  return ret;
2438  },
2439  };
2440 }
2441 
2442 template <typename T>
2443 static T CalculateTruncatedMedian(std::vector<T> &scores) {
2444  size_t size = scores.size();
2445  if (size == 0) {
2446  return T();
2447  }
2448 
2449  std::sort(scores.begin(), scores.end());
2450  if (size % 2 == 0) {
2451  return (scores[size / 2 - 1] + scores[size / 2]) / 2;
2452  } else {
2453  return scores[size / 2];
2454  }
2455 }
2456 
2457 template <typename T> static inline bool SetHasKeys(const std::set<T> &set) {
2458  return false;
2459 }
2460 template <typename T, typename Tk, typename... Args>
2461 static inline bool SetHasKeys(const std::set<T> &set, const Tk &key,
2462  const Args &...args) {
2463  return (set.count(key) != 0) || SetHasKeys(set, args...);
2464 }
2465 
2466 // outpoint (needed for the utxo index) + nHeight + fCoinBase
2467 static constexpr size_t PER_UTXO_OVERHEAD =
2468  sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool);
2469 
2471  const auto &ticker = Currency::get().ticker;
2472  return RPCHelpMan{
2473  "getblockstats",
2474  "Compute per block statistics for a given window. All amounts are "
2475  "in " +
2476  ticker +
2477  ".\n"
2478  "It won't work for some heights with pruning.\n",
2479  {
2480  {"hash_or_height",
2483  "The block hash or height of the target block",
2484  "",
2485  {"", "string or numeric"}},
2486  {"stats",
2488  /* default */ "all values",
2489  "Values to plot (see result below)",
2490  {
2492  "Selected statistic"},
2494  "Selected statistic"},
2495  },
2496  "stats"},
2497  },
2498  RPCResult{
2500  "",
2501  "",
2502  {
2503  {RPCResult::Type::NUM, "avgfee", "Average fee in the block"},
2504  {RPCResult::Type::NUM, "avgfeerate",
2505  "Average feerate (in satoshis per virtual byte)"},
2506  {RPCResult::Type::NUM, "avgtxsize", "Average transaction size"},
2507  {RPCResult::Type::STR_HEX, "blockhash",
2508  "The block hash (to check for potential reorgs)"},
2509  {RPCResult::Type::NUM, "height", "The height of the block"},
2510  {RPCResult::Type::NUM, "ins",
2511  "The number of inputs (excluding coinbase)"},
2512  {RPCResult::Type::NUM, "maxfee", "Maximum fee in the block"},
2513  {RPCResult::Type::NUM, "maxfeerate",
2514  "Maximum feerate (in satoshis per virtual byte)"},
2515  {RPCResult::Type::NUM, "maxtxsize", "Maximum transaction size"},
2516  {RPCResult::Type::NUM, "medianfee",
2517  "Truncated median fee in the block"},
2518  {RPCResult::Type::NUM, "medianfeerate",
2519  "Truncated median feerate (in " + ticker + " per byte)"},
2520  {RPCResult::Type::NUM, "mediantime",
2521  "The block median time past"},
2522  {RPCResult::Type::NUM, "mediantxsize",
2523  "Truncated median transaction size"},
2524  {RPCResult::Type::NUM, "minfee", "Minimum fee in the block"},
2525  {RPCResult::Type::NUM, "minfeerate",
2526  "Minimum feerate (in satoshis per virtual byte)"},
2527  {RPCResult::Type::NUM, "mintxsize", "Minimum transaction size"},
2528  {RPCResult::Type::NUM, "outs", "The number of outputs"},
2529  {RPCResult::Type::NUM, "subsidy", "The block subsidy"},
2530  {RPCResult::Type::NUM, "time", "The block time"},
2531  {RPCResult::Type::NUM, "total_out",
2532  "Total amount in all outputs (excluding coinbase and thus "
2533  "reward [ie subsidy + totalfee])"},
2534  {RPCResult::Type::NUM, "total_size",
2535  "Total size of all non-coinbase transactions"},
2536  {RPCResult::Type::NUM, "totalfee", "The fee total"},
2537  {RPCResult::Type::NUM, "txs",
2538  "The number of transactions (including coinbase)"},
2539  {RPCResult::Type::NUM, "utxo_increase",
2540  "The increase/decrease in the number of unspent outputs"},
2541  {RPCResult::Type::NUM, "utxo_size_inc",
2542  "The increase/decrease in size for the utxo index (not "
2543  "discounting op_return and similar)"},
2544  }},
2545  RPCExamples{
2547  "getblockstats",
2548  R"('"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"' '["minfeerate","avgfeerate"]')") +
2549  HelpExampleCli("getblockstats",
2550  R"(1000 '["minfeerate","avgfeerate"]')") +
2552  "getblockstats",
2553  R"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") +
2554  HelpExampleRpc("getblockstats",
2555  R"(1000, ["minfeerate","avgfeerate"])")},
2556  [&](const RPCHelpMan &self, const Config &config,
2557  const JSONRPCRequest &request) -> UniValue {
2558  ChainstateManager &chainman = EnsureAnyChainman(request.context);
2559  LOCK(cs_main);
2560  CBlockIndex *pindex{ParseHashOrHeight(request.params[0], chainman)};
2561  CHECK_NONFATAL(pindex != nullptr);
2562 
2563  std::set<std::string> stats;
2564  if (!request.params[1].isNull()) {
2565  const UniValue stats_univalue = request.params[1].get_array();
2566  for (unsigned int i = 0; i < stats_univalue.size(); i++) {
2567  const std::string stat = stats_univalue[i].get_str();
2568  stats.insert(stat);
2569  }
2570  }
2571 
2572  const CBlock block = GetBlockChecked(config, pindex);
2573  const CBlockUndo blockUndo = GetUndoChecked(pindex);
2574 
2575  // Calculate everything if nothing selected (default)
2576  const bool do_all = stats.size() == 0;
2577  const bool do_mediantxsize =
2578  do_all || stats.count("mediantxsize") != 0;
2579  const bool do_medianfee = do_all || stats.count("medianfee") != 0;
2580  const bool do_medianfeerate =
2581  do_all || stats.count("medianfeerate") != 0;
2582  const bool loop_inputs =
2583  do_all || do_medianfee || do_medianfeerate ||
2584  SetHasKeys(stats, "utxo_size_inc", "totalfee", "avgfee",
2585  "avgfeerate", "minfee", "maxfee", "minfeerate",
2586  "maxfeerate");
2587  const bool loop_outputs =
2588  do_all || loop_inputs || stats.count("total_out");
2589  const bool do_calculate_size =
2590  do_mediantxsize || loop_inputs ||
2591  SetHasKeys(stats, "total_size", "avgtxsize", "mintxsize",
2592  "maxtxsize");
2593 
2594  const int64_t blockMaxSize = config.GetMaxBlockSize();
2595  Amount maxfee = Amount::zero();
2596  Amount maxfeerate = Amount::zero();
2597  Amount minfee = MAX_MONEY;
2598  Amount minfeerate = MAX_MONEY;
2599  Amount total_out = Amount::zero();
2600  Amount totalfee = Amount::zero();
2601  int64_t inputs = 0;
2602  int64_t maxtxsize = 0;
2603  int64_t mintxsize = blockMaxSize;
2604  int64_t outputs = 0;
2605  int64_t total_size = 0;
2606  int64_t utxo_size_inc = 0;
2607  std::vector<Amount> fee_array;
2608  std::vector<Amount> feerate_array;
2609  std::vector<int64_t> txsize_array;
2610 
2611  for (size_t i = 0; i < block.vtx.size(); ++i) {
2612  const auto &tx = block.vtx.at(i);
2613  outputs += tx->vout.size();
2614  Amount tx_total_out = Amount::zero();
2615  if (loop_outputs) {
2616  for (const CTxOut &out : tx->vout) {
2617  tx_total_out += out.nValue;
2618  utxo_size_inc +=
2621  }
2622  }
2623 
2624  if (tx->IsCoinBase()) {
2625  continue;
2626  }
2627 
2628  // Don't count coinbase's fake input
2629  inputs += tx->vin.size();
2630  // Don't count coinbase reward
2631  total_out += tx_total_out;
2632 
2633  int64_t tx_size = 0;
2634  if (do_calculate_size) {
2635  tx_size = tx->GetTotalSize();
2636  if (do_mediantxsize) {
2637  txsize_array.push_back(tx_size);
2638  }
2639  maxtxsize = std::max(maxtxsize, tx_size);
2640  mintxsize = std::min(mintxsize, tx_size);
2641  total_size += tx_size;
2642  }
2643 
2644  if (loop_inputs) {
2645  Amount tx_total_in = Amount::zero();
2646  const auto &txundo = blockUndo.vtxundo.at(i - 1);
2647  for (const Coin &coin : txundo.vprevout) {
2648  const CTxOut &prevoutput = coin.GetTxOut();
2649 
2650  tx_total_in += prevoutput.nValue;
2651  utxo_size_inc -=
2652  GetSerializeSize(prevoutput, PROTOCOL_VERSION) +
2654  }
2655 
2656  Amount txfee = tx_total_in - tx_total_out;
2657  CHECK_NONFATAL(MoneyRange(txfee));
2658  if (do_medianfee) {
2659  fee_array.push_back(txfee);
2660  }
2661  maxfee = std::max(maxfee, txfee);
2662  minfee = std::min(minfee, txfee);
2663  totalfee += txfee;
2664 
2665  Amount feerate = txfee / tx_size;
2666  if (do_medianfeerate) {
2667  feerate_array.push_back(feerate);
2668  }
2669  maxfeerate = std::max(maxfeerate, feerate);
2670  minfeerate = std::min(minfeerate, feerate);
2671  }
2672  }
2673 
2674  UniValue ret_all(UniValue::VOBJ);
2675  ret_all.pushKV("avgfee",
2676  block.vtx.size() > 1
2677  ? (totalfee / int((block.vtx.size() - 1)))
2678  : Amount::zero());
2679  ret_all.pushKV("avgfeerate", total_size > 0
2680  ? (totalfee / total_size)
2681  : Amount::zero());
2682  ret_all.pushKV("avgtxsize",
2683  (block.vtx.size() > 1)
2684  ? total_size / (block.vtx.size() - 1)
2685  : 0);
2686  ret_all.pushKV("blockhash", pindex->GetBlockHash().GetHex());
2687  ret_all.pushKV("height", (int64_t)pindex->nHeight);
2688  ret_all.pushKV("ins", inputs);
2689  ret_all.pushKV("maxfee", maxfee);
2690  ret_all.pushKV("maxfeerate", maxfeerate);
2691  ret_all.pushKV("maxtxsize", maxtxsize);
2692  ret_all.pushKV("medianfee", CalculateTruncatedMedian(fee_array));
2693  ret_all.pushKV("medianfeerate",
2694  CalculateTruncatedMedian(feerate_array));
2695  ret_all.pushKV("mediantime", pindex->GetMedianTimePast());
2696  ret_all.pushKV("mediantxsize",
2697  CalculateTruncatedMedian(txsize_array));
2698  ret_all.pushKV("minfee",
2699  minfee == MAX_MONEY ? Amount::zero() : minfee);
2700  ret_all.pushKV("minfeerate", minfeerate == MAX_MONEY
2701  ? Amount::zero()
2702  : minfeerate);
2703  ret_all.pushKV("mintxsize",
2704  mintxsize == blockMaxSize ? 0 : mintxsize);
2705  ret_all.pushKV("outs", outputs);
2706  ret_all.pushKV("subsidy", GetBlockSubsidy(pindex->nHeight,
2707  Params().GetConsensus()));
2708  ret_all.pushKV("time", pindex->GetBlockTime());
2709  ret_all.pushKV("total_out", total_out);
2710  ret_all.pushKV("total_size", total_size);
2711  ret_all.pushKV("totalfee", totalfee);
2712  ret_all.pushKV("txs", (int64_t)block.vtx.size());
2713  ret_all.pushKV("utxo_increase", outputs - inputs);
2714  ret_all.pushKV("utxo_size_inc", utxo_size_inc);
2715 
2716  if (do_all) {
2717  return ret_all;
2718  }
2719 
2720  UniValue ret(UniValue::VOBJ);
2721  for (const std::string &stat : stats) {
2722  const UniValue &value = ret_all[stat];
2723  if (value.isNull()) {
2724  throw JSONRPCError(
2726  strprintf("Invalid selected statistic %s", stat));
2727  }
2728  ret.pushKV(stat, value);
2729  }
2730  return ret;
2731  },
2732  };
2733 }
2734 
2736  return RPCHelpMan{
2737  "savemempool",
2738  "Dumps the mempool to disk. It will fail until the previous dump is "
2739  "fully loaded.\n",
2740  {},
2742  RPCExamples{HelpExampleCli("savemempool", "") +
2743  HelpExampleRpc("savemempool", "")},
2744  [&](const RPCHelpMan &self, const Config &config,
2745  const JSONRPCRequest &request) -> UniValue {
2746  const CTxMemPool &mempool = EnsureAnyMemPool(request.context);
2747 
2748  if (!mempool.IsLoaded()) {
2750  "The mempool was not loaded yet");
2751  }
2752 
2753  if (!DumpMempool(mempool)) {
2755  "Unable to dump mempool to disk");
2756  }
2757 
2758  return NullUniValue;
2759  },
2760  };
2761 }
2762 
2763 namespace {
2765 static bool FindScriptPubKey(std::atomic<int> &scan_progress,
2766  const std::atomic<bool> &should_abort,
2767  int64_t &count, CCoinsViewCursor *cursor,
2768  const std::set<CScript> &needles,
2769  std::map<COutPoint, Coin> &out_results,
2770  std::function<void()> &interruption_point) {
2771  scan_progress = 0;
2772  count = 0;
2773  while (cursor->Valid()) {
2774  COutPoint key;
2775  Coin coin;
2776  if (!cursor->GetKey(key) || !cursor->GetValue(coin)) {
2777  return false;
2778  }
2779  if (++count % 8192 == 0) {
2780  interruption_point();
2781  if (should_abort) {
2782  // allow to abort the scan via the abort reference
2783  return false;
2784  }
2785  }
2786  if (count % 256 == 0) {
2787  // update progress reference every 256 item
2788  const TxId &txid = key.GetTxId();
2789  uint32_t high = 0x100 * *txid.begin() + *(txid.begin() + 1);
2790  scan_progress = int(high * 100.0 / 65536.0 + 0.5);
2791  }
2792  if (needles.count(coin.GetTxOut().scriptPubKey)) {
2793  out_results.emplace(key, coin);
2794  }
2795  cursor->Next();
2796  }
2797  scan_progress = 100;
2798  return true;
2799 }
2800 } // namespace
2801 
2803 static std::atomic<int> g_scan_progress;
2804 static std::atomic<bool> g_scan_in_progress;
2805 static std::atomic<bool> g_should_abort_scan;
2807 private:
2809 
2810 public:
2812 
2813  bool reserve() {
2815  if (g_scan_in_progress.exchange(true)) {
2816  return false;
2817  }
2818  m_could_reserve = true;
2819  return true;
2820  }
2821 
2823  if (m_could_reserve) {
2824  g_scan_in_progress = false;
2825  }
2826  }
2827 };
2828 
2830  const auto &ticker = Currency::get().ticker;
2831  return RPCHelpMan{
2832  "scantxoutset",
2833  "Scans the unspent transaction output set for entries that match "
2834  "certain output descriptors.\n"
2835  "Examples of output descriptors are:\n"
2836  " addr(<address>) Outputs whose scriptPubKey "
2837  "corresponds to the specified address (does not include P2PK)\n"
2838  " raw(<hex script>) Outputs whose scriptPubKey "
2839  "equals the specified hex scripts\n"
2840  " combo(<pubkey>) P2PK and P2PKH outputs for "
2841  "the given pubkey\n"
2842  " pkh(<pubkey>) P2PKH outputs for the given "
2843  "pubkey\n"
2844  " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for "
2845  "the given threshold and pubkeys\n"
2846  "\nIn the above, <pubkey> either refers to a fixed public key in "
2847  "hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
2848  "or more path elements separated by \"/\", and optionally ending in "
2849  "\"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
2850  "unhardened or hardened child keys.\n"
2851  "In the latter case, a range needs to be specified by below if "
2852  "different from 1000.\n"
2853  "For more information on output descriptors, see the documentation in "
2854  "the doc/descriptors.md file.\n",
2855  {
2857  "The action to execute\n"
2858  " \"start\" for starting a "
2859  "scan\n"
2860  " \"abort\" for aborting the "
2861  "current scan (returns true when abort was successful)\n"
2862  " \"status\" for "
2863  "progress report (in %) of the current scan"},
2864  {"scanobjects",
2867  "Array of scan objects. Required for \"start\" action\n"
2868  " Every scan object is either a "
2869  "string descriptor or an object:",
2870  {
2872  "An output descriptor"},
2873  {
2874  "",
2877  "An object with output descriptor and metadata",
2878  {
2880  "An output descriptor"},
2881  {"range", RPCArg::Type::RANGE, /* default */ "1000",
2882  "The range of HD chain indexes to explore (either "
2883  "end or [begin,end])"},
2884  },
2885  },
2886  },
2887  "[scanobjects,...]"},
2888  },
2889  {
2890  RPCResult{"When action=='abort'", RPCResult::Type::BOOL, "", ""},
2891  RPCResult{"When action=='status' and no scan is in progress",
2892  RPCResult::Type::NONE, "", ""},
2893  RPCResult{
2894  "When action=='status' and scan is in progress",
2896  "",
2897  "",
2898  {
2899  {RPCResult::Type::NUM, "progress", "The scan progress"},
2900  }},
2901  RPCResult{
2902  "When action=='start'",
2904  "",
2905  "",
2906  {
2907  {RPCResult::Type::BOOL, "success",
2908  "Whether the scan was completed"},
2909  {RPCResult::Type::NUM, "txouts",
2910  "The number of unspent transaction outputs scanned"},
2911  {RPCResult::Type::NUM, "height",
2912  "The current block height (index)"},
2913  {RPCResult::Type::STR_HEX, "bestblock",
2914  "The hash of the block at the tip of the chain"},
2916  "unspents",
2917  "",
2918  {
2920  "",
2921  "",
2922  {
2923  {RPCResult::Type::STR_HEX, "txid",
2924  "The transaction id"},
2925  {RPCResult::Type::NUM, "vout", "The vout value"},
2926  {RPCResult::Type::STR_HEX, "scriptPubKey",
2927  "The script key"},
2928  {RPCResult::Type::STR, "desc",
2929  "A specialized descriptor for the matched "
2930  "scriptPubKey"},
2931  {RPCResult::Type::STR_AMOUNT, "amount",
2932  "The total amount in " + ticker +
2933  " of the unspent output"},
2934  {RPCResult::Type::NUM, "height",
2935  "Height of the unspent transaction output"},
2936  }},
2937  }},
2938  {RPCResult::Type::STR_AMOUNT, "total_amount",
2939  "The total amount of all found unspent outputs in " +
2940  ticker},
2941  }},
2942  },
2943  RPCExamples{""},
2944  [&](const RPCHelpMan &self, const Config &config,
2945  const JSONRPCRequest &request) -> UniValue {
2946  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
2947 
2948  UniValue result(UniValue::VOBJ);
2949  if (request.params[0].get_str() == "status") {
2950  CoinsViewScanReserver reserver;
2951  if (reserver.reserve()) {
2952  // no scan in progress
2953  return NullUniValue;
2954  }
2955  result.pushKV("progress", g_scan_progress.load());
2956  return result;
2957  } else if (request.params[0].get_str() == "abort") {
2958  CoinsViewScanReserver reserver;
2959  if (reserver.reserve()) {
2960  // reserve was possible which means no scan was running
2961  return false;
2962  }
2963  // set the abort flag
2964  g_should_abort_scan = true;
2965  return true;
2966  } else if (request.params[0].get_str() == "start") {
2967  CoinsViewScanReserver reserver;
2968  if (!reserver.reserve()) {
2970  "Scan already in progress, use action "
2971  "\"abort\" or \"status\"");
2972  }
2973 
2974  if (request.params.size() < 2) {
2976  "scanobjects argument is required for "
2977  "the start action");
2978  }
2979 
2980  std::set<CScript> needles;
2981  std::map<CScript, std::string> descriptors;
2982  Amount total_in = Amount::zero();
2983 
2984  // loop through the scan objects
2985  for (const UniValue &scanobject :
2986  request.params[1].get_array().getValues()) {
2987  FlatSigningProvider provider;
2988  auto scripts =
2989  EvalDescriptorStringOrObject(scanobject, provider);
2990  for (const auto &script : scripts) {
2991  std::string inferred =
2992  InferDescriptor(script, provider)->ToString();
2993  needles.emplace(script);
2994  descriptors.emplace(std::move(script),
2995  std::move(inferred));
2996  }
2997  }
2998 
2999  // Scan the unspent transaction output set for inputs
3000  UniValue unspents(UniValue::VARR);
3001  std::vector<CTxOut> input_txos;
3002  std::map<COutPoint, Coin> coins;
3003  g_should_abort_scan = false;
3004  g_scan_progress = 0;
3005  int64_t count = 0;
3006  std::unique_ptr<CCoinsViewCursor> pcursor;
3007  CBlockIndex *tip;
3008  NodeContext &node = EnsureAnyNodeContext(request.context);
3009  {
3010  ChainstateManager &chainman = EnsureChainman(node);
3011  LOCK(cs_main);
3012  CChainState &active_chainstate =
3013  chainman.ActiveChainstate();
3014  active_chainstate.ForceFlushStateToDisk();
3015  pcursor = std::unique_ptr<CCoinsViewCursor>(
3016  active_chainstate.CoinsDB().Cursor());
3017  CHECK_NONFATAL(pcursor);
3018  tip = active_chainstate.m_chain.Tip();
3019  CHECK_NONFATAL(tip);
3020  }
3021  bool res = FindScriptPubKey(
3022  g_scan_progress, g_should_abort_scan, count, pcursor.get(),
3023  needles, coins, node.rpc_interruption_point);
3024  result.pushKV("success", res);
3025  result.pushKV("txouts", count);
3026  result.pushKV("height", tip->nHeight);
3027  result.pushKV("bestblock", tip->GetBlockHash().GetHex());
3028 
3029  for (const auto &it : coins) {
3030  const COutPoint &outpoint = it.first;
3031  const Coin &coin = it.second;
3032  const CTxOut &txo = coin.GetTxOut();
3033  input_txos.push_back(txo);
3034  total_in += txo.nValue;
3035 
3036  UniValue unspent(UniValue::VOBJ);
3037  unspent.pushKV("txid", outpoint.GetTxId().GetHex());
3038  unspent.pushKV("vout", int32_t(outpoint.GetN()));
3039  unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey));
3040  unspent.pushKV("desc", descriptors[txo.scriptPubKey]);
3041  unspent.pushKV("amount", txo.nValue);
3042  unspent.pushKV("height", int32_t(coin.GetHeight()));
3043 
3044  unspents.push_back(unspent);
3045  }
3046  result.pushKV("unspents", unspents);
3047  result.pushKV("total_amount", total_in);
3048  } else {
3049  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command");
3050  }
3051  return result;
3052  },
3053  };
3054 }
3055 
3057  return RPCHelpMan{
3058  "getblockfilter",
3059  "Retrieve a BIP 157 content filter for a particular block.\n",
3060  {
3062  "The hash of the block"},
3063  {"filtertype", RPCArg::Type::STR, /*default*/ "basic",
3064  "The type name of the filter"},
3065  },
3067  "",
3068  "",
3069  {
3070  {RPCResult::Type::STR_HEX, "filter",
3071  "the hex-encoded filter data"},
3072  {RPCResult::Type::STR_HEX, "header",
3073  "the hex-encoded filter header"},
3074  }},
3075  RPCExamples{
3076  HelpExampleCli("getblockfilter",
3077  "\"00000000c937983704a73af28acdec37b049d214a"
3078  "dbda81d7e2a3dd146f6ed09\" \"basic\"") +
3079  HelpExampleRpc("getblockfilter",
3080  "\"00000000c937983704a73af28acdec37b049d214adbda81d7"
3081  "e2a3dd146f6ed09\", \"basic\"")},
3082  [&](const RPCHelpMan &self, const Config &config,
3083  const JSONRPCRequest &request) -> UniValue {
3084  const BlockHash block_hash(
3085  ParseHashV(request.params[0], "blockhash"));
3086  std::string filtertype_name = "basic";
3087  if (!request.params[1].isNull()) {
3088  filtertype_name = request.params[1].get_str();
3089  }
3090 
3091  BlockFilterType filtertype;
3092  if (!BlockFilterTypeByName(filtertype_name, filtertype)) {
3094  "Unknown filtertype");
3095  }
3096 
3097  BlockFilterIndex *index = GetBlockFilterIndex(filtertype);
3098  if (!index) {
3100  "Index is not enabled for filtertype " +
3101  filtertype_name);
3102  }
3103 
3104  const CBlockIndex *block_index;
3105  bool block_was_connected;
3106  {
3107  ChainstateManager &chainman =
3108  EnsureAnyChainman(request.context);
3109  LOCK(cs_main);
3110  block_index = chainman.m_blockman.LookupBlockIndex(block_hash);
3111  if (!block_index) {
3113  "Block not found");
3114  }
3115  block_was_connected =
3116  block_index->IsValid(BlockValidity::SCRIPTS);
3117  }
3118 
3119  bool index_ready = index->BlockUntilSyncedToCurrentChain();
3120 
3121  BlockFilter filter;
3122  uint256 filter_header;
3123  if (!index->LookupFilter(block_index, filter) ||
3124  !index->LookupFilterHeader(block_index, filter_header)) {
3125  int err_code;
3126  std::string errmsg = "Filter not found.";
3127 
3128  if (!block_was_connected) {
3129  err_code = RPC_INVALID_ADDRESS_OR_KEY;
3130  errmsg += " Block was not connected to active chain.";
3131  } else if (!index_ready) {
3132  err_code = RPC_MISC_ERROR;
3133  errmsg += " Block filters are still in the process of "
3134  "being indexed.";
3135  } else {
3136  err_code = RPC_INTERNAL_ERROR;
3137  errmsg += " This error is unexpected and indicates index "
3138  "corruption.";
3139  }
3140 
3141  throw JSONRPCError(err_code, errmsg);
3142  }
3143 
3144  UniValue ret(UniValue::VOBJ);
3145  ret.pushKV("filter", HexStr(filter.GetEncodedFilter()));
3146  ret.pushKV("header", filter_header.GetHex());
3147  return ret;
3148  },
3149  };
3150 }
3151 
3158  return RPCHelpMan{
3159  "dumptxoutset",
3160  "Write the serialized UTXO set to disk.\n",
3161  {
3163  "path to the output file. If relative, will be prefixed by "
3164  "datadir."},
3165  },
3167  "",
3168  "",
3169  {
3170  {RPCResult::Type::NUM, "coins_written",
3171  "the number of coins written in the snapshot"},
3172  {RPCResult::Type::STR_HEX, "base_hash",
3173  "the hash of the base of the snapshot"},
3174  {RPCResult::Type::NUM, "base_height",
3175  "the height of the base of the snapshot"},
3176  {RPCResult::Type::STR, "path",
3177  "the absolute path that the snapshot was written to"},
3178  }},
3179  RPCExamples{HelpExampleCli("dumptxoutset", "utxo.dat")},
3180  [&](const RPCHelpMan &self, const Config &config,
3181  const JSONRPCRequest &request) -> UniValue {
3182  fs::path path = fs::absolute(
3183  fs::u8path(request.params[0].get_str()), GetDataDir());
3184  // Write to a temporary path and then move into `path` on completion
3185  // to avoid confusion due to an interruption.
3186  fs::path temppath = fs::absolute(
3187  fs::u8path(request.params[0].get_str() + ".incomplete"),
3188  GetDataDir());
3189 
3190  if (fs::exists(path)) {
3192  path.u8string() +
3193  " already exists. If you are sure this "
3194  "is what you want, "
3195  "move it out of the way first");
3196  }
3197 
3198  FILE *file{fsbridge::fopen(temppath, "wb")};
3199  CAutoFile afile{file, SER_DISK, CLIENT_VERSION};
3200  NodeContext &node = EnsureAnyNodeContext(request.context);
3201  UniValue result = CreateUTXOSnapshot(
3202  node, node.chainman->ActiveChainstate(), afile);
3203  fs::rename(temppath, path);
3204 
3205  result.pushKV("path", path.u8string());
3206  return result;
3207  },
3208  };
3209 }
3210 
3212  CAutoFile &afile) {
3213  std::unique_ptr<CCoinsViewCursor> pcursor;
3215  CBlockIndex *tip;
3216 
3217  {
3218  // We need to lock cs_main to ensure that the coinsdb isn't
3219  // written to between (i) flushing coins cache to disk
3220  // (coinsdb), (ii) getting stats based upon the coinsdb, and
3221  // (iii) constructing a cursor to the coinsdb for use below this
3222  // block.
3223  //
3224  // Cursors returned by leveldb iterate over snapshots, so the
3225  // contents of the pcursor will not be affected by simultaneous
3226  // writes during use below this block.
3227  //
3228  // See discussion here:
3229  // https://github.com/bitcoin/bitcoin/pull/15606#discussion_r274479369
3230  //
3231  LOCK(::cs_main);
3232 
3233  chainstate.ForceFlushStateToDisk();
3234 
3235  if (!GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, stats,
3236  node.rpc_interruption_point)) {
3237  throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
3238  }
3239 
3240  pcursor =
3241  std::unique_ptr<CCoinsViewCursor>(chainstate.CoinsDB().Cursor());
3242  tip = chainstate.m_blockman.LookupBlockIndex(stats.hashBlock);
3243  CHECK_NONFATAL(tip);
3244  }
3245 
3246  SnapshotMetadata metadata{tip->GetBlockHash(), stats.coins_count,
3247  uint64_t(tip->GetChainTxCount())};
3248 
3249  afile << metadata;
3250 
3251  COutPoint key;
3252  Coin coin;
3253  unsigned int iter{0};
3254 
3255  while (pcursor->Valid()) {
3256  if (iter % 5000 == 0) {
3257  node.rpc_interruption_point();
3258  }
3259  ++iter;
3260  if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
3261  afile << key;
3262  afile << coin;
3263  }
3264 
3265  pcursor->Next();
3266  }
3267 
3268  afile.fclose();
3269 
3270  UniValue result(UniValue::VOBJ);
3271  result.pushKV("coins_written", stats.coins_count);
3272  result.pushKV("base_hash", tip->GetBlockHash().ToString());
3273  result.pushKV("base_height", tip->nHeight);
3274  return result;
3275 }
3276 
3278  // clang-format off
3279  static const CRPCCommand commands[] = {
3280  // category actor (function)
3281  // ------------------ ----------------------
3282  { "blockchain", getbestblockhash, },
3283  { "blockchain", getblock, },
3284  { "blockchain", getblockchaininfo, },
3285  { "blockchain", getblockcount, },
3286  { "blockchain", getblockhash, },
3287  { "blockchain", getblockheader, },
3288  { "blockchain", getblockstats, },
3289  { "blockchain", getchaintips, },
3290  { "blockchain", getchaintxstats, },
3291  { "blockchain", getdifficulty, },
3292  { "blockchain", getmempoolancestors, },
3293  { "blockchain", getmempooldescendants, },
3294  { "blockchain", getmempoolentry, },
3295  { "blockchain", getmempoolinfo, },
3296  { "blockchain", getrawmempool, },
3297  { "blockchain", gettxout, },
3298  { "blockchain", gettxoutsetinfo, },
3299  { "blockchain", pruneblockchain, },
3300  { "blockchain", savemempool, },
3301  { "blockchain", verifychain, },
3302  { "blockchain", preciousblock, },
3303  { "blockchain", scantxoutset, },
3304  { "blockchain", getblockfilter, },
3305 
3306  /* Not shown in help */
3307  { "hidden", getfinalizedblockhash, },
3308  { "hidden", finalizeblock, },
3309  { "hidden", invalidateblock, },
3310  { "hidden", parkblock, },
3311  { "hidden", reconsiderblock, },
3312  { "hidden", syncwithvalidationinterfacequeue, },
3313  { "hidden", dumptxoutset, },
3314  { "hidden", unparkblock, },
3315  { "hidden", waitfornewblock, },
3316  { "hidden", waitforblock, },
3317  { "hidden", waitforblockheight, },
3318  };
3319  // clang-format on
3320  for (const auto &c : commands) {
3321  t.appendCommand(c.name, &c);
3322  }
3323 }
CBlockIndex::IsValid
bool IsValid(enum BlockValidity nUpTo=BlockValidity::TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
Definition: blockindex.h:204
ThresholdState::STARTED
@ STARTED
CCoinsViewDB::Cursor
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: txdb.cpp:188
CBlockIndex::GetBlockTime
int64_t GetBlockTime() const
Definition: blockindex.h:169
GetSerializeSize
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1259
CTxIn
An input of a transaction.
Definition: transaction.h:61
RPC_MISC_ERROR
@ RPC_MISC_ERROR
General application defined errors std::exception thrown in command handling.
Definition: protocol.h:38
policy.h
CCoinsStats::index_requested
bool index_requested
Signals if the coinstatsindex should be used (when available).
Definition: coinstats.h:43
CalculateTruncatedMedian
static T CalculateTruncatedMedian(std::vector< T > &scores)
Definition: blockchain.cpp:2443
CTransaction::vin
const std::vector< CTxIn > vin
Definition: transaction.h:210
MoneyRange
bool MoneyRange(const Amount nValue)
Definition: amount.h:176
RPCResult::Type::ELISION
@ ELISION
Special type to denote elision (...)
CTxMemPool::GetMinFee
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:1172
CTxOut::nValue
Amount nValue
Definition: transaction.h:132
g_should_abort_scan
static std::atomic< bool > g_should_abort_scan
Definition: blockchain.cpp:2805
HelpExampleCli
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:138
fs::exists
static bool exists(const path &p)
Definition: fs.h:94
preciousblock
static RPCHelpMan preciousblock()
Definition: blockchain.cpp:2070
PER_UTXO_OVERHEAD
static constexpr size_t PER_UTXO_OVERHEAD
Definition: blockchain.cpp:2467
ChainstateManager::BlockIndex
BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
Definition: validation.h:1235
getblockfilter
static RPCHelpMan getblockfilter()
Definition: blockchain.cpp:3056
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:831
BlockValidity::SCRIPTS
@ SCRIPTS
Scripts & signatures ok.
GetBlockSubsidy
Amount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
Definition: validation.cpp:814
DEFAULT_CHECKLEVEL
static const unsigned int DEFAULT_CHECKLEVEL
Definition: validation.h:120
ThresholdState::ACTIVE
@ ACTIVE
CBlockIndex::GetAncestor
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:71
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:27
count
static int count
Definition: tests.c:31
CalculateCurrentUsage
uint64_t CalculateCurrentUsage()
BLOCK PRUNING CODE.
Definition: validation.cpp:4429
CHECKLEVEL_DOC
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
Definition: validation.cpp:71
UniValue::get_bool
bool get_bool() const
Definition: univalue_get.cpp:91
CChainState::ActivateBestChain
bool ActivateBestChain(const Config &config, BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr) LOCKS_EXCLUDED(cs_main)
Find the best known block, and make it the tip of the block chain.
Definition: validation.cpp:2952
CChainState::ForceFlushStateToDisk
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
Definition: validation.cpp:2229
CoinStatsHashType::HASH_SERIALIZED
@ HASH_SERIALIZED
verifychain
static RPCHelpMan verifychain()
Definition: blockchain.cpp:1602
CUpdatedBlock::height
int height
Definition: blockchain.cpp:48
RPC_INTERNAL_ERROR
@ RPC_INTERNAL_ERROR
Definition: protocol.h:33
CBlockIndex::nTime
uint32_t nTime
Definition: blockindex.h:90
CHECK_NONFATAL
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:34
RegisterBlockchainRPCCommands
void RegisterBlockchainRPCCommands(CRPCTable &t)
Register block chain RPC commands.
Definition: blockchain.cpp:3277
nHeight
unsigned int nHeight
Definition: mempool_eviction.cpp:13
BlockValidationState
Definition: validation.h:138
GetUTXOStats
static bool GetUTXOStats(CCoinsView *view, BlockManager &blockman, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point, const CBlockIndex *pindex)
Calculate statistics about the unspent transaction output set.
Definition: coinstats.cpp:90
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:24
VersionBitsState
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos, VersionBitsCache &cache)
Get the BIP9 state for a given deployment at the current tip.
Definition: versionbits.cpp:219
streams.h
base_uint::GetHex
std::string GetHex() const
Definition: arith_uint256.cpp:155
CUpdatedBlock::hash
BlockHash hash
Definition: blockchain.cpp:47
CBlockIndex::nTx
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:58
nPruneTarget
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
Definition: validation.cpp:105
CTxMemPoolEntry::Children
std::set< CTxMemPoolEntryRef, CompareIteratorById > Children
Definition: txmempool.h:86
GetWarnings
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:41
NodeContext::mempool
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:38
cond_blockchange
static std::condition_variable cond_blockchange
Definition: blockchain.cpp:52
RPCHelpMan
Definition: util.h:331
g_scan_progress
static std::atomic< int > g_scan_progress
RAII object to prevent concurrency issue when scanning the txout set.
Definition: blockchain.cpp:2803
blockfilterindex.h
transaction.h
CTxMemPool::txiter
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:581
waitforblockheight
static RPCHelpMan waitforblockheight()
Definition: blockchain.cpp:391
ParseHashType
static CoinStatsHashType ParseHashType(const std::string &hash_type_input)
Definition: blockchain.cpp:1265
CTxMemPool::IsLoaded
bool IsLoaded() const
Definition: txmempool.cpp:1292
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
CChainState::PreciousBlock
bool PreciousBlock(const Config &config, BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as precious and reorganize.
Definition: validation.cpp:3089
Consensus::DeploymentPos
DeploymentPos
Definition: params.h:16
getmempoolinfo
static RPCHelpMan getmempoolinfo()
Definition: blockchain.cpp:2033
CBlockIndex::nBits
uint32_t nBits
Definition: blockindex.h:91
CTxMemPool
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:497
RPC_INVALID_PARAMETER
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:46
getblockstats
static RPCHelpMan getblockstats()
Definition: blockchain.cpp:2470
CBlockIndex::pprev
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:30
CoinsViewScanReserver::m_could_reserve
bool m_could_reserve
Definition: blockchain.cpp:2808
MempoolInfoToJSON
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
Definition: blockchain.cpp:2014
BlockFilterTypeByName
bool BlockFilterTypeByName(const std::string &name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
Definition: blockfilter.cpp:181
ComputeNextBlockAndDepth
static int ComputeNextBlockAndDepth(const CBlockIndex *tip, const CBlockIndex *blockindex, const CBlockIndex *&next)
Definition: blockchain.cpp:107
ParseHashV
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition: util.cpp:99
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:36
RPCArg::Optional::NO
@ NO
Required arg.
validationinterface.h
RPCArg::Type::STR
@ STR
validation.h
BlockFilterIndex
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
Definition: blockfilterindex.h:30
RPC_CLIENT_MEMPOOL_DISABLED
@ RPC_CLIENT_MEMPOOL_DISABLED
Chain errors.
Definition: protocol.h:86
RPCArg::Type::ARR
@ ARR
CChainParams
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:74
CompareBlocksByHeight
Comparison function for sorting the getchaintips heads.
Definition: blockchain.cpp:1876
CCoinsStats
Definition: coinstats.h:28
CoinsViewScanReserver
Definition: blockchain.cpp:2806
minRelayTxFee
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
Definition: validation.cpp:111
getchaintxstats
static RPCHelpMan getchaintxstats()
Definition: blockchain.cpp:2331
CBlockIndex::nChainWork
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: blockindex.h:49
CChainState::GetFinalizedBlock
const CBlockIndex * GetFinalizedBlock() const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the currently finalized block index.
Definition: validation.cpp:3485
Consensus::MAX_VERSION_BITS_DEPLOYMENTS
@ MAX_VERSION_BITS_DEPLOYMENTS
Definition: params.h:20
NodeContext::rpc_interruption_point
std::function< void()> rpc_interruption_point
Definition: context.h:52
CChainParams::GetConsensus
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:86
AnnotatedMixin< std::mutex >
RPCResult::Type::NUM
@ NUM
IsBlockPruned
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
Definition: validation.cpp:5880
CTxMemPool::setEntries
std::set< txiter, CompareIteratorById > setEntries
Definition: txmempool.h:585
CBlockIndex::nStatus
BlockStatus nStatus
Verification status of this block. See enum BlockStatus.
Definition: blockindex.h:85
EnsureAnyChainman
ChainstateManager & EnsureAnyChainman(const std::any &context)
Definition: blockchain.cpp:82
CChainState::CoinsDB
CCoinsViewDB & CoinsDB()
Definition: validation.h:862
UniValue::isNull
bool isNull() const
Definition: univalue.h:89
GetBlockChecked
static CBlock GetBlockChecked(const Config &config, const CBlockIndex *pblockindex)
Definition: blockchain.cpp:1022
CTxMemPool::CalculateMemPoolAncestors
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
Definition: txmempool.cpp:187
versionbitscache
VersionBitsCache versionbitscache
pruneblockchain
static RPCHelpMan pruneblockchain()
Definition: blockchain.cpp:1187
MIN_BLOCKS_TO_KEEP
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
Definition: validation.h:118
BlockManager
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
Definition: validation.h:577
coinstatsindex.h
chainparams.h
ChainstateManager::ActiveChainstate
CChainState & ActiveChainstate() const
The most-work chain.
Definition: validation.cpp:6243
finalizeblock
RPCHelpMan finalizeblock()
Definition: blockchain.cpp:2113
getfinalizedblockhash
RPCHelpMan getfinalizedblockhash()
Definition: blockchain.cpp:240
UniValue::isNum
bool isNum() const
Definition: univalue.h:94
EnsureAnyNodeContext
NodeContext & EnsureAnyNodeContext(const std::any &context)
Definition: blockchain.cpp:55
syncwithvalidationinterfacequeue
static RPCHelpMan syncwithvalidationinterfacequeue()
Definition: blockchain.cpp:451
CChain::Tip
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:168
context.h
CoinStatsHashType::NONE
@ NONE
CBlockUndo::vtxundo
std::vector< CTxUndo > vtxundo
Definition: undo.h:76
core_io.h
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
fPruneMode
bool fPruneMode
True if we're running in -prune mode.
Definition: validation.cpp:101
IsRPCRunning
bool IsRPCRunning()
Query whether RPC is running.
Definition: server.cpp:373
getblockhash
static RPCHelpMan getblockhash()
Definition: blockchain.cpp:897
getblock
static RPCHelpMan getblock()
Definition: blockchain.cpp:1054
CTxMemPool::queryHashes
void queryHashes(std::vector< uint256 > &vtxid) const
Definition: txmempool.cpp:909
CBlockIndex::GetBlockHash
BlockHash GetBlockHash() const
Definition: blockindex.h:142
CChain::FindFork
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:55
UniValue
Definition: univalue.h:23
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:194
AssertLockHeld
AssertLockHeld(pool.cs)
g_coin_stats_index
std::unique_ptr< CoinStatsIndex > g_coin_stats_index
The global UTXO set hash object.
Definition: coinstatsindex.cpp:94
GUARDED_BY
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange)
ValidationState::ToString
std::string ToString() const
Definition: validation.h:124
ChainstateManager::ActiveChain
CChain & ActiveChain() const
Definition: validation.h:1231
Amount::zero
static constexpr Amount zero()
Definition: amount.h:42
txmempool.h
ScriptPubKeyToUniv
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:186
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:166
CCoinsView
Abstract view on the open txout dataset.
Definition: coins.h:177
CoinsViewScanReserver::reserve
bool reserve()
Definition: blockchain.cpp:2813
RPCArg::Type::NUM
@ NUM
CBlockIndex::GetChainTxCount
int64_t GetChainTxCount() const
Get the number of transaction in the chain so far.
Definition: blockindex.h:147
ValidationState::IsValid
bool IsValid() const
Definition: validation.h:118
getmempoolentry
static RPCHelpMan getmempoolentry()
Definition: blockchain.cpp:865
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:581
BCLog::RPC
@ RPC
Definition: logging.h:46
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:98
CChain::FindEarliestAtLeast
CBlockIndex * FindEarliestAtLeast(int64_t nTime, int height) const
Find the earliest block with timestamp equal or greater than the given time and height equal or great...
Definition: chain.cpp:68
SATOSHI
static constexpr Amount SATOSHI
Definition: amount.h:153
CCoinsViewCursor
Cursor for iterating over CoinsView state.
Definition: coins.h:157
CBlockIndex::GetBlockHeader
CBlockHeader GetBlockHeader() const
Definition: blockindex.h:129
strencodings.h
Consensus::Params
Parameters that influence chain consensus.
Definition: params.h:59
Config
Definition: config.h:17
CFeeRate::GetFeePerK
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:54
SyncWithValidationInterfaceQueue
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
Definition: validationinterface.cpp:162
CCoinsViewCache::GetCoin
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:94
blockheaderToJSON
UniValue blockheaderToJSON(const CBlockIndex *tip, const CBlockIndex *blockindex)
Block header to JSON.
Definition: blockchain.cpp:150
blockdb.h
EnsureAnyMemPool
CTxMemPool & EnsureAnyMemPool(const std::any &context)
Definition: blockchain.cpp:71
COutPoint::GetTxId
const TxId & GetTxId() const
Definition: transaction.h:37
RPCArg::Type::OBJ
@ OBJ
CTxMemPool::cs
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:578
CCoinsViewCursor::GetValue
virtual bool GetValue(Coin &coin) const =0
blockfilter.h
AssertLockNotHeld
#define AssertLockNotHeld(cs)
Definition: sync.h:92
BlockStatus::hasData
bool hasData() const
Definition: blockstatus.h:54
CTxOut
An output of a transaction.
Definition: transaction.h:130
CTransaction::GetId
const TxId GetId() const
Definition: transaction.h:244
RPCArg::Type::STR_HEX
@ STR_HEX
Special type that is a STR with only hex chars.
cs_main
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:92
RPCResult::Type::OBJ
@ OBJ
ChainstateManager::ActiveTip
CBlockIndex * ActiveTip() const
Definition: validation.h:1233
CRPCCommand
Definition: server.h:147
Coin
A UTXO entry.
Definition: coins.h:27
RPCResult::Type::NONE
@ NONE
BIP9SoftForkDescPushBack
static void BIP9SoftForkDescPushBack(const CBlockIndex *active_chain_tip, UniValue &softforks, const Consensus::Params &consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: blockchain.cpp:1638
fs::path
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:33
GetDifficulty
double GetDifficulty(const CBlockIndex *blockindex)
Calculate the difficulty for a given block index.
Definition: blockchain.cpp:89
CBlockIndex::GetMedianTimePast
int64_t GetMedianTimePast() const
Definition: blockindex.h:181
getdifficulty
static RPCHelpMan getdifficulty()
Definition: blockchain.cpp:468
CTxOut::scriptPubKey
CScript scriptPubKey
Definition: transaction.h:133
CBlockIndex::nVersion
int32_t nVersion
block header
Definition: blockindex.h:88
ChainstateManager::ActiveHeight
int ActiveHeight() const
Definition: validation.h:1232
UndoReadFromDisk
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
Definition: validation.cpp:1232
undo.h
ThresholdState::DEFINED
@ DEFINED
CBlockIndex::hashMerkleRoot
uint256 hashMerkleRoot
Definition: blockindex.h:89
BIP9Stats::count
int count
Number of blocks with the version bit set since the beginning of the current period.
Definition: versionbits.h:60
getchaintips
static RPCHelpMan getchaintips()
Definition: blockchain.cpp:1888
DumpMempool
bool DumpMempool(const CTxMemPool &pool)
Dump the mempool to disk.
Definition: validation.cpp:5815
RPC_DATABASE_ERROR
@ RPC_DATABASE_ERROR
Database error.
Definition: protocol.h:48
ParseHashOrHeight
static CBlockIndex * ParseHashOrHeight(const UniValue &param, ChainstateManager &chainman)
Definition: blockchain.cpp:118
Currency::get
static const Currency & get()
Definition: amount.cpp:18
RPCResult::Type::STR_HEX
@ STR_HEX
Special string with only hex chars.
pindexBestHeader
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
Definition: validation.cpp:94
entryToJSON
static void entryToJSON(const CTxMemPool &pool, UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
Definition: blockchain.cpp:557
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:583
base_blob::GetHex
std::string GetHex() const
Definition: uint256.cpp:16
CTxMemPool::GetSequence
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:838
RPCExamples
Definition: util.h:323
CChainParams::NetworkIDString
std::string NetworkIDString() const
Return the BIP70 network string (main, test or regtest)
Definition: chainparams.h:121
UniValue::__pushKV
void __pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:127
ReadBlockFromDisk
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &params)
Functions for disk access for blocks.
Definition: blockstorage.cpp:48
BIP9Stats::threshold
int threshold
Number of blocks with the version bit set required to activate the softfork.
Definition: versionbits.h:51
CoinsViewScanReserver::~CoinsViewScanReserver
~CoinsViewScanReserver()
Definition: blockchain.cpp:2822
RPCResult::Type::STR
@ STR
EvalDescriptorStringOrObject
std::vector< CScript > EvalDescriptorStringOrObject(const UniValue &scanobject, FlatSigningProvider &provider)
Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range ...
Definition: util.cpp:909
CoinStatsHashType::MUHASH
@ MUHASH
utxo_snapshot.h
getbestblockhash
static RPCHelpMan getbestblockhash()
Definition: blockchain.cpp:222
base_blob::ToString
std::string ToString() const
Definition: uint256.h:78
uint256
256-bit opaque blob.
Definition: uint256.h:127
uint256S
uint256 uint256S(const char *str)
uint256 from const char *.
Definition: uint256.h:141
CCoinsViewCursor::Valid
virtual bool Valid() const =0
RPCResult::Type::NUM_TIME
@ NUM_TIME
Special numeric to denote unix epoch time.
RPCResult::Type::ARR
@ ARR
TxId
A TxId is the identifier of a transaction.
Definition: txid.h:14
CChainState
CChainState stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:764
Amount
Definition: amount.h:19
LogPrint
#define LogPrint(category,...)
Definition: logging.h:203
gettxout
RPCHelpMan gettxout()
Definition: blockchain.cpp:1498
HelpExampleRpc
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:143
EnsureMemPool
CTxMemPool & EnsureMemPool(const NodeContext &node)
Definition: blockchain.cpp:63
GetUndoChecked
static CBlockUndo GetUndoChecked(const CBlockIndex *pblockindex)
Definition: blockchain.cpp:1040
CAutoFile::fclose
void fclose()
Definition: streams.h:600
RPCArg::Type::RANGE
@ RANGE
Special type that is a NUM or [NUM,NUM].
base_blob::begin
uint8_t * begin()
Definition: uint256.h:83
CCoinsViewMemPool::GetCoin
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txmempool.cpp:1061
cs_blockchange
static Mutex cs_blockchange
Definition: blockchain.cpp:51
coins.h
ThresholdState::FAILED
@ FAILED
parkblock
RPCHelpMan parkblock()
Definition: blockchain.cpp:2203
CChain::Height
int Height() const
Return the maximal height in the chain.
Definition: chain.h:204
gettxoutsetinfo
static RPCHelpMan gettxoutsetinfo()
Definition: blockchain.cpp:1279
BlockHash
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
getrawmempool
static RPCHelpMan getrawmempool()
Definition: blockchain.cpp:650
ChainstateManager
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1132
CRPCTable
RPC command dispatcher.
Definition: server.h:184
CVerifyDB
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
Definition: validation.h:552
PruneBlockFilesManual
void PruneBlockFilesManual(CChainState &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
Definition: validation.cpp:4511
RPC_INVALID_ADDRESS_OR_KEY
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:42
name
const char * name
Definition: rest.cpp:45
getblockheader
static RPCHelpMan getblockheader()
Definition: blockchain.cpp:926
fs::path::u8string
std::string u8string() const
Definition: fs.h:77
coinstats.h
dumptxoutset
static RPCHelpMan dumptxoutset()
Serialize the UTXO set to a file for loading elsewhere.
Definition: blockchain.cpp:3157
BlockFilter::GetEncodedFilter
const std::vector< uint8_t > & GetEncodedFilter() const
Definition: blockfilter.h:134
CChainState::ParkBlock
bool ParkBlock(const Config &config, BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_chainstate)
Park a block.
Definition: validation.cpp:3323
BIP9Stats
Display status of an in-progress BIP9 softfork.
Definition: versionbits.h:44
system.h
CBlock
Definition: block.h:55
CVerifyDB::VerifyDB
bool VerifyDB(CChainState &chainstate, const Config &config, CCoinsView &coinsview, int nCheckLevel, int nCheckDepth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.cpp:4799
Currency::ticker
std::string ticker
Definition: amount.h:160
CLIENT_VERSION
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:44
VersionBitsDeploymentInfo
const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS]
Definition: versionbitsinfo.cpp:10
CChainState::IsInitialBlockDownload
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network)
Definition: validation.cpp:862
reconsiderblock
static RPCHelpMan reconsiderblock()
Definition: blockchain.cpp:2245
getmempooldescendants
static RPCHelpMan getmempooldescendants()
Definition: blockchain.cpp:791
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
BIP9Stats::elapsed
int elapsed
Number of blocks elapsed since the beginning of the current period.
Definition: versionbits.h:55
Join
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
Definition: string.h:44
MempoolToJSON
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
Definition: blockchain.cpp:606
TxToUniv
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
Definition: core_write.cpp:213
CRPCTable::appendCommand
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:322
g_scan_in_progress
static std::atomic< bool > g_scan_in_progress
Definition: blockchain.cpp:2804
RPCNotifyBlockChange
void RPCNotifyBlockChange(const CBlockIndex *pindex)
Callback for when block tip changed.
Definition: blockchain.cpp:263
CChain
An in-memory indexed chain of blocks.
Definition: chain.h:152
CBlock::vtx
std::vector< CTransactionRef > vtx
Definition: block.h:58
RPCResult::Type::BOOL
@ BOOL
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:105
CCoinsViewCache
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:233
CompareBlocksByHeight::operator()
bool operator()(const CBlockIndex *a, const CBlockIndex *b) const
Definition: blockchain.cpp:1877
translation.h
NodeContext::chainman
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:40
RPCTypeCheck
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:25
GetBlockFilterIndex
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
Definition: blockfilterindex.cpp:486
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
Config::GetChainParams
virtual const CChainParams & GetChainParams() const =0
JSONRPCError
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:52
CTxMemPoolEntry
Definition: txmempool.h:81
LOCK
#define LOCK(cs)
Definition: sync.h:241
gArgs
ArgsManager gArgs
Definition: system.cpp:76
CChainState::FinalizeBlock
bool FinalizeBlock(const Config &config, BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_chainstate)
Finalize a block.
Definition: validation.cpp:3332
fs::u8path
static path u8path(const std::string &string)
Definition: fs.h:82
blockstorage.h
CTxMemPool::GetUnbroadcastTxs
std::set< TxId > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
Definition: txmempool.h:822
RPCArg::Type::BOOL
@ BOOL
CCoinsViewCache::GetBestBlock
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:206
RPCSerializationFlags
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition: server.cpp:600
RPCArg::Optional::OMITTED
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:63
CBlockIndex::nNonce
uint32_t nNonce
Definition: blockindex.h:92
CCoinsViewMemPool
CCoinsView that brings transactions from a mempool into view.
Definition: txmempool.h:923
CTxMemPool::size
unsigned long size() const
Definition: txmempool.h:785
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
CChainState::m_blockman
BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all CChainState instances.
Definition: validation.h:808
BlockFilterIndex::LookupFilter
bool LookupFilter(const CBlockIndex *block_index, BlockFilter &filter_out) const
Get a single filter by block.
Definition: blockfilterindex.cpp:408
EnsureChainman
ChainstateManager & EnsureChainman(const NodeContext &node)
Definition: blockchain.cpp:75
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:515
CUpdatedBlock
Definition: blockchain.cpp:46
CCoinsViewCursor::GetKey
virtual bool GetKey(COutPoint &key) const =0
invalidateblock
static RPCHelpMan invalidateblock()
Definition: blockchain.cpp:2160
count_seconds
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
Definition: time.h:29
versionbitsinfo.h
CChain::Contains
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:184
SER_DISK
@ SER_DISK
Definition: serialize.h:167
Coin::GetHeight
uint32_t GetHeight() const
Definition: coins.h:44
scantxoutset
static RPCHelpMan scantxoutset()
Definition: blockchain.cpp:2829
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue_get.cpp:84
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:197
BlockFilterType
BlockFilterType
Definition: blockfilter.h:88
ThresholdState::LOCKED_IN
@ LOCKED_IN
MEMPOOL_HEIGHT
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coins to signify they are only in the memory pool(since 0....
Definition: txmempool.h:41
BIP9Stats::possible
bool possible
False if there are not enough blocks left in this period to pass activation threshold.
Definition: versionbits.h:65
CChainState::ResetBlockFailureFlags
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove invalidity status from a block and its descendants.
Definition: validation.cpp:3430
unparkblock
RPCHelpMan unparkblock()
Definition: blockchain.cpp:2287
CoinsViewScanReserver::CoinsViewScanReserver
CoinsViewScanReserver()
Definition: blockchain.cpp:2811
RPCResult::Type::OBJ_DYN
@ OBJ_DYN
Special dictionary with keys that are not literals.
UniValue::size
size_t size() const
Definition: univalue.h:80
IndexSummary
Definition: base.h:17
CTxMemPool::DynamicMemoryUsage
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:1077
ValidationState::GetRejectReason
std::string GetRejectReason() const
Definition: validation.h:122
JSONRPCRequest
Definition: request.h:30
util.h
RPCResult
Definition: util.h:244
COutPoint::GetN
uint32_t GetN() const
Definition: transaction.h:38
COutPoint
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
blockchain.h
VersionBitsStateSinceHeight
int VersionBitsStateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos, VersionBitsCache &cache)
Get the block height at which the BIP9 deployment switched into the state for the block building on t...
Definition: versionbits.cpp:234
getmempoolancestors
static RPCHelpMan getmempoolancestors()
Definition: blockchain.cpp:716
VersionBitsStatistics
BIP9Stats VersionBitsStatistics(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos)
Get the numerical statistics for the BIP9 state for a given deployment at the current tip.
Definition: versionbits.cpp:227
RPCResult::Type::STR_AMOUNT
@ STR_AMOUNT
Special string to represent a floating point amount.
CChainState::UnparkBlockAndChildren
void UnparkBlockAndChildren(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove parked status from a block and its descendants.
Definition: validation.cpp:3470
MAX_MONEY
static const Amount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:175
UniValue::get_array
const UniValue & get_array() const
Definition: univalue_get.cpp:142
UniValue::VARR
@ VARR
Definition: univalue.h:27
NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:36
CTxMemPool::GetTotalTxSize
uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:790
BIP9Stats::period
int period
Length of blocks of the BIP9 signalling period.
Definition: versionbits.h:46
server.h
InferDescriptor
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
Definition: descriptor.cpp:1301
ThresholdState
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
Definition: versionbits.h:26
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:23
savemempool
static RPCHelpMan savemempool()
Definition: blockchain.cpp:2735
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:667
CoinStatsHashType
CoinStatsHashType
Definition: coinstats.h:22
Coin::GetTxOut
CTxOut & GetTxOut()
Definition: coins.h:48
getblockchaininfo
RPCHelpMan getblockchaininfo()
Definition: blockchain.cpp:1703
BlockManager::LookupBlockIndex
CBlockIndex * LookupBlockIndex(const BlockHash &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.cpp:139
CTxMemPool::isSpent
bool isSpent(const COutPoint &outpoint) const
Definition: txmempool.cpp:409
UniValue::VSTR
@ VSTR
Definition: univalue.h:27
amount.h
CCoinsViewCursor::Next
virtual void Next()=0
GuessVerificationProgress
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
Definition: validation.cpp:5889
warnings.h
BlockValidity::TREE
@ TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
BlockFilterIndex::LookupFilterHeader
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out)
Get a single filter header by block.
Definition: blockfilterindex.cpp:418
CChainState::CoinsTip
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:856
CCoinsView::GetBestBlock
virtual BlockHash GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:15
txdb.h
MempoolEntryDescription
static std::vector< RPCResult > MempoolEntryDescription()
Definition: blockchain.cpp:488
SnapshotMetadata
Metadata describing a serialized version of a UTXO set from which an assumeutxo CChainState can be co...
Definition: utxo_snapshot.h:14
UNIX_EPOCH_TIME
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
Definition: util.cpp:21
CBlockUndo
Undo information for a CBlock.
Definition: undo.h:73
WAIT_LOCK
#define WAIT_LOCK(cs, name)
Definition: sync.h:249
CChainState::m_chain
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition: validation.h:837
DEFAULT_MAX_MEMPOOL_SIZE
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
Definition: policy.h:48
waitforblock
static RPCHelpMan waitforblock()
Definition: blockchain.cpp:329
FlatSigningProvider
Definition: signingprovider.h:58
descriptor.h
SetHasKeys
static bool SetHasKeys(const std::set< T > &set)
Definition: blockchain.cpp:2457
DEFAULT_CHECKBLOCKS
static const signed int DEFAULT_CHECKBLOCKS
Definition: validation.h:119
blockToJSON
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
Block description to JSON.
Definition: blockchain.cpp:184
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11
TIMESTAMP_WINDOW
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
Definition: chain.h:36
getblockcount
static RPCHelpMan getblockcount()
Definition: blockchain.cpp:204
CTxMemPool::CalculateDescendants
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
Definition: txmempool.cpp:515
CreateUTXOSnapshot
UniValue CreateUTXOSnapshot(NodeContext &node, CChainState &chainstate, CAutoFile &afile)
Helper to create UTXO snapshots given a chainstate and a file handle.
Definition: blockchain.cpp:3211
CChainState::InvalidateBlock
bool InvalidateBlock(const Config &config, BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_chainstate)
Mark a block as invalid.
Definition: validation.cpp:3313
Coin::IsCoinBase
bool IsCoinBase() const
Definition: coins.h:45
waitfornewblock
static RPCHelpMan waitfornewblock()
Definition: blockchain.cpp:272
CTxMemPoolEntry::GetTx
const CTransaction & GetTx() const
Definition: txmempool.h:140
BlockFilter
Complete block filter struct as defined in BIP 157.
Definition: blockfilter.h:111