Bitcoin Core  21.99.0
P2P Digital Currency
blockchain.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <rpc/blockchain.h>
7 
8 #include <amount.h>
9 #include <blockfilter.h>
10 #include <chain.h>
11 #include <chainparams.h>
12 #include <coins.h>
13 #include <consensus/validation.h>
14 #include <core_io.h>
15 #include <hash.h>
16 #include <index/blockfilterindex.h>
17 #include <node/blockstorage.h>
18 #include <node/coinstats.h>
19 #include <node/context.h>
20 #include <node/utxo_snapshot.h>
21 #include <policy/feerate.h>
22 #include <policy/fees.h>
23 #include <policy/policy.h>
24 #include <policy/rbf.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 <sync.h>
31 #include <txdb.h>
32 #include <txmempool.h>
33 #include <undo.h>
34 #include <util/strencodings.h>
35 #include <util/system.h>
36 #include <util/translation.h>
37 #include <validation.h>
38 #include <validationinterface.h>
39 #include <warnings.h>
40 
41 #include <stdint.h>
42 
43 #include <univalue.h>
44 
45 #include <condition_variable>
46 #include <memory>
47 #include <mutex>
48 
50 {
52  int height;
53 };
54 
56 static std::condition_variable cond_blockchange;
57 static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);
58 
59 NodeContext& EnsureAnyNodeContext(const std::any& context)
60 {
61  auto node_context = util::AnyPtr<NodeContext>(context);
62  if (!node_context) {
63  throw JSONRPCError(RPC_INTERNAL_ERROR, "Node context not found");
64  }
65  return *node_context;
66 }
67 
69 {
70  if (!node.mempool) {
71  throw JSONRPCError(RPC_CLIENT_MEMPOOL_DISABLED, "Mempool disabled or instance not found");
72  }
73  return *node.mempool;
74 }
75 
76 CTxMemPool& EnsureAnyMemPool(const std::any& context)
77 {
78  return EnsureMemPool(EnsureAnyNodeContext(context));
79 }
80 
82 {
83  if (!node.chainman) {
84  throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
85  }
86  WITH_LOCK(::cs_main, CHECK_NONFATAL(std::addressof(g_chainman) == std::addressof(*node.chainman)));
87  return *node.chainman;
88 }
89 
90 ChainstateManager& EnsureAnyChainman(const std::any& context)
91 {
92  return EnsureChainman(EnsureAnyNodeContext(context));
93 }
94 
96 {
97  if (!node.fee_estimator) {
98  throw JSONRPCError(RPC_INTERNAL_ERROR, "Fee estimation disabled");
99  }
100  return *node.fee_estimator;
101 }
102 
104 {
105  return EnsureFeeEstimator(EnsureAnyNodeContext(context));
106 }
107 
108 /* Calculate the difficulty for a given block index.
109  */
110 double GetDifficulty(const CBlockIndex* blockindex)
111 {
112  CHECK_NONFATAL(blockindex);
113 
114  int nShift = (blockindex->nBits >> 24) & 0xff;
115  double dDiff =
116  (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
117 
118  while (nShift < 29)
119  {
120  dDiff *= 256.0;
121  nShift++;
122  }
123  while (nShift > 29)
124  {
125  dDiff /= 256.0;
126  nShift--;
127  }
128 
129  return dDiff;
130 }
131 
132 static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
133 {
134  next = tip->GetAncestor(blockindex->nHeight + 1);
135  if (next && next->pprev == blockindex) {
136  return tip->nHeight - blockindex->nHeight + 1;
137  }
138  next = nullptr;
139  return blockindex == tip ? 1 : -1;
140 }
141 
142 UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
143 {
144  // Serialize passed information without accessing chain state of the active chain!
145  AssertLockNotHeld(cs_main); // For performance reasons
146 
147  UniValue result(UniValue::VOBJ);
148  result.pushKV("hash", blockindex->GetBlockHash().GetHex());
149  const CBlockIndex* pnext;
150  int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
151  result.pushKV("confirmations", confirmations);
152  result.pushKV("height", blockindex->nHeight);
153  result.pushKV("version", blockindex->nVersion);
154  result.pushKV("versionHex", strprintf("%08x", blockindex->nVersion));
155  result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex());
156  result.pushKV("time", (int64_t)blockindex->nTime);
157  result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast());
158  result.pushKV("nonce", (uint64_t)blockindex->nNonce);
159  result.pushKV("bits", strprintf("%08x", blockindex->nBits));
160  result.pushKV("difficulty", GetDifficulty(blockindex));
161  result.pushKV("chainwork", blockindex->nChainWork.GetHex());
162  result.pushKV("nTx", (uint64_t)blockindex->nTx);
163 
164  if (blockindex->pprev)
165  result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
166  if (pnext)
167  result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
168  return result;
169 }
170 
171 UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails)
172 {
173  UniValue result = blockheaderToJSON(tip, blockindex);
174 
175  result.pushKV("strippedsize", (int)::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS));
176  result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
177  result.pushKV("weight", (int)::GetBlockWeight(block));
179  if (txDetails) {
180  CBlockUndo blockUndo;
181  const bool have_undo = !IsBlockPruned(blockindex) && UndoReadFromDisk(blockUndo, blockindex);
182  for (size_t i = 0; i < block.vtx.size(); ++i) {
183  const CTransactionRef& tx = block.vtx.at(i);
184  // coinbase transaction (i == 0) doesn't have undo data
185  const CTxUndo* txundo = (have_undo && i) ? &blockUndo.vtxundo.at(i - 1) : nullptr;
186  UniValue objTx(UniValue::VOBJ);
187  TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags(), txundo);
188  txs.push_back(objTx);
189  }
190  } else {
191  for (const CTransactionRef& tx : block.vtx) {
192  txs.push_back(tx->GetHash().GetHex());
193  }
194  }
195  result.pushKV("tx", txs);
196 
197  return result;
198 }
199 
201 {
202  return RPCHelpMan{"getblockcount",
203  "\nReturns the height of the most-work fully-validated chain.\n"
204  "The genesis block has height 0.\n",
205  {},
206  RPCResult{
207  RPCResult::Type::NUM, "", "The current block count"},
208  RPCExamples{
209  HelpExampleCli("getblockcount", "")
210  + HelpExampleRpc("getblockcount", "")
211  },
212  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
213 {
214  ChainstateManager& chainman = EnsureAnyChainman(request.context);
215  LOCK(cs_main);
216  return chainman.ActiveChain().Height();
217 },
218  };
219 }
220 
222 {
223  return RPCHelpMan{"getbestblockhash",
224  "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n",
225  {},
226  RPCResult{
227  RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"},
228  RPCExamples{
229  HelpExampleCli("getbestblockhash", "")
230  + HelpExampleRpc("getbestblockhash", "")
231  },
232  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
233 {
234  ChainstateManager& chainman = EnsureAnyChainman(request.context);
235  LOCK(cs_main);
236  return chainman.ActiveChain().Tip()->GetBlockHash().GetHex();
237 },
238  };
239 }
240 
242 {
243  if(pindex) {
245  latestblock.hash = pindex->GetBlockHash();
246  latestblock.height = pindex->nHeight;
247  }
248  cond_blockchange.notify_all();
249 }
250 
252 {
253  return RPCHelpMan{"waitfornewblock",
254  "\nWaits for a specific new block and returns useful info about it.\n"
255  "\nReturns the current block on timeout or exit.\n",
256  {
257  {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},
258  },
259  RPCResult{
260  RPCResult::Type::OBJ, "", "",
261  {
262  {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
263  {RPCResult::Type::NUM, "height", "Block height"},
264  }},
265  RPCExamples{
266  HelpExampleCli("waitfornewblock", "1000")
267  + HelpExampleRpc("waitfornewblock", "1000")
268  },
269  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
270 {
271  int timeout = 0;
272  if (!request.params[0].isNull())
273  timeout = request.params[0].get_int();
274 
275  CUpdatedBlock block;
276  {
277  WAIT_LOCK(cs_blockchange, lock);
278  block = latestblock;
279  if(timeout)
280  cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
281  else
282  cond_blockchange.wait(lock, [&block]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
283  block = latestblock;
284  }
286  ret.pushKV("hash", block.hash.GetHex());
287  ret.pushKV("height", block.height);
288  return ret;
289 },
290  };
291 }
292 
294 {
295  return RPCHelpMan{"waitforblock",
296  "\nWaits for a specific new block and returns useful info about it.\n"
297  "\nReturns the current block on timeout or exit.\n",
298  {
299  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Block hash to wait for."},
300  {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},
301  },
302  RPCResult{
303  RPCResult::Type::OBJ, "", "",
304  {
305  {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
306  {RPCResult::Type::NUM, "height", "Block height"},
307  }},
308  RPCExamples{
309  HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000")
310  + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
311  },
312  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
313 {
314  int timeout = 0;
315 
316  uint256 hash(ParseHashV(request.params[0], "blockhash"));
317 
318  if (!request.params[1].isNull())
319  timeout = request.params[1].get_int();
320 
321  CUpdatedBlock block;
322  {
323  WAIT_LOCK(cs_blockchange, lock);
324  if(timeout)
325  cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning();});
326  else
327  cond_blockchange.wait(lock, [&hash]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning(); });
328  block = latestblock;
329  }
330 
332  ret.pushKV("hash", block.hash.GetHex());
333  ret.pushKV("height", block.height);
334  return ret;
335 },
336  };
337 }
338 
340 {
341  return RPCHelpMan{"waitforblockheight",
342  "\nWaits for (at least) block height and returns the height and hash\n"
343  "of the current tip.\n"
344  "\nReturns the current block on timeout or exit.\n",
345  {
346  {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "Block height to wait for."},
347  {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},
348  },
349  RPCResult{
350  RPCResult::Type::OBJ, "", "",
351  {
352  {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
353  {RPCResult::Type::NUM, "height", "Block height"},
354  }},
355  RPCExamples{
356  HelpExampleCli("waitforblockheight", "100 1000")
357  + HelpExampleRpc("waitforblockheight", "100, 1000")
358  },
359  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
360 {
361  int timeout = 0;
362 
363  int height = request.params[0].get_int();
364 
365  if (!request.params[1].isNull())
366  timeout = request.params[1].get_int();
367 
368  CUpdatedBlock block;
369  {
370  WAIT_LOCK(cs_blockchange, lock);
371  if(timeout)
372  cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height >= height || !IsRPCRunning();});
373  else
374  cond_blockchange.wait(lock, [&height]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height >= height || !IsRPCRunning(); });
375  block = latestblock;
376  }
378  ret.pushKV("hash", block.hash.GetHex());
379  ret.pushKV("height", block.height);
380  return ret;
381 },
382  };
383 }
384 
386 {
387  return RPCHelpMan{"syncwithvalidationinterfacequeue",
388  "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n",
389  {},
391  RPCExamples{
392  HelpExampleCli("syncwithvalidationinterfacequeue","")
393  + HelpExampleRpc("syncwithvalidationinterfacequeue","")
394  },
395  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
396 {
398  return NullUniValue;
399 },
400  };
401 }
402 
404 {
405  return RPCHelpMan{"getdifficulty",
406  "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n",
407  {},
408  RPCResult{
409  RPCResult::Type::NUM, "", "the proof-of-work difficulty as a multiple of the minimum difficulty."},
410  RPCExamples{
411  HelpExampleCli("getdifficulty", "")
412  + HelpExampleRpc("getdifficulty", "")
413  },
414  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
415 {
416  ChainstateManager& chainman = EnsureAnyChainman(request.context);
417  LOCK(cs_main);
418  return GetDifficulty(chainman.ActiveChain().Tip());
419 },
420  };
421 }
422 
423 static std::vector<RPCResult> MempoolEntryDescription() { return {
424  RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."},
425  RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
426  RPCResult{RPCResult::Type::STR_AMOUNT, "fee", "transaction fee in " + CURRENCY_UNIT + " (DEPRECATED)"},
427  RPCResult{RPCResult::Type::STR_AMOUNT, "modifiedfee", "transaction fee with fee deltas used for mining priority (DEPRECATED)"},
428  RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
429  RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"},
430  RPCResult{RPCResult::Type::NUM, "descendantcount", "number of in-mempool descendant transactions (including this one)"},
431  RPCResult{RPCResult::Type::NUM, "descendantsize", "virtual transaction size of in-mempool descendants (including this one)"},
432  RPCResult{RPCResult::Type::STR_AMOUNT, "descendantfees", "modified fees (see above) of in-mempool descendants (including this one) (DEPRECATED)"},
433  RPCResult{RPCResult::Type::NUM, "ancestorcount", "number of in-mempool ancestor transactions (including this one)"},
434  RPCResult{RPCResult::Type::NUM, "ancestorsize", "virtual transaction size of in-mempool ancestors (including this one)"},
435  RPCResult{RPCResult::Type::STR_AMOUNT, "ancestorfees", "modified fees (see above) of in-mempool ancestors (including this one) (DEPRECATED)"},
436  RPCResult{RPCResult::Type::STR_HEX, "wtxid", "hash of serialized transaction, including witness data"},
437  RPCResult{RPCResult::Type::OBJ, "fees", "",
438  {
439  RPCResult{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
440  RPCResult{RPCResult::Type::STR_AMOUNT, "modified", "transaction fee with fee deltas used for mining priority in " + CURRENCY_UNIT},
441  RPCResult{RPCResult::Type::STR_AMOUNT, "ancestor", "modified fees (see above) of in-mempool ancestors (including this one) in " + CURRENCY_UNIT},
442  RPCResult{RPCResult::Type::STR_AMOUNT, "descendant", "modified fees (see above) of in-mempool descendants (including this one) in " + CURRENCY_UNIT},
443  }},
444  RPCResult{RPCResult::Type::ARR, "depends", "unconfirmed transactions used as inputs for this transaction",
445  {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}},
446  RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction",
447  {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}},
448  RPCResult{RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction could be replaced due to BIP125 (replace-by-fee)"},
449  RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)"},
450 };}
451 
452 static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
453 {
454  AssertLockHeld(pool.cs);
455 
456  UniValue fees(UniValue::VOBJ);
457  fees.pushKV("base", ValueFromAmount(e.GetFee()));
458  fees.pushKV("modified", ValueFromAmount(e.GetModifiedFee()));
459  fees.pushKV("ancestor", ValueFromAmount(e.GetModFeesWithAncestors()));
460  fees.pushKV("descendant", ValueFromAmount(e.GetModFeesWithDescendants()));
461  info.pushKV("fees", fees);
462 
463  info.pushKV("vsize", (int)e.GetTxSize());
464  info.pushKV("weight", (int)e.GetTxWeight());
465  info.pushKV("fee", ValueFromAmount(e.GetFee()));
466  info.pushKV("modifiedfee", ValueFromAmount(e.GetModifiedFee()));
467  info.pushKV("time", count_seconds(e.GetTime()));
468  info.pushKV("height", (int)e.GetHeight());
469  info.pushKV("descendantcount", e.GetCountWithDescendants());
470  info.pushKV("descendantsize", e.GetSizeWithDescendants());
471  info.pushKV("descendantfees", e.GetModFeesWithDescendants());
472  info.pushKV("ancestorcount", e.GetCountWithAncestors());
473  info.pushKV("ancestorsize", e.GetSizeWithAncestors());
474  info.pushKV("ancestorfees", e.GetModFeesWithAncestors());
475  info.pushKV("wtxid", pool.vTxHashes[e.vTxHashesIdx].first.ToString());
476  const CTransaction& tx = e.GetTx();
477  std::set<std::string> setDepends;
478  for (const CTxIn& txin : tx.vin)
479  {
480  if (pool.exists(txin.prevout.hash))
481  setDepends.insert(txin.prevout.hash.ToString());
482  }
483 
484  UniValue depends(UniValue::VARR);
485  for (const std::string& dep : setDepends)
486  {
487  depends.push_back(dep);
488  }
489 
490  info.pushKV("depends", depends);
491 
492  UniValue spent(UniValue::VARR);
493  const CTxMemPool::txiter& it = pool.mapTx.find(tx.GetHash());
494  const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
495  for (const CTxMemPoolEntry& child : children) {
496  spent.push_back(child.GetTx().GetHash().ToString());
497  }
498 
499  info.pushKV("spentby", spent);
500 
501  // Add opt-in RBF status
502  bool rbfStatus = false;
503  RBFTransactionState rbfState = IsRBFOptIn(tx, pool);
504  if (rbfState == RBFTransactionState::UNKNOWN) {
505  throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not in mempool");
506  } else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125) {
507  rbfStatus = true;
508  }
509 
510  info.pushKV("bip125-replaceable", rbfStatus);
511  info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetHash()));
512 }
513 
514 UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempool_sequence)
515 {
516  if (verbose) {
517  if (include_mempool_sequence) {
518  throw JSONRPCError(RPC_INVALID_PARAMETER, "Verbose results cannot contain mempool sequence values.");
519  }
520  LOCK(pool.cs);
522  for (const CTxMemPoolEntry& e : pool.mapTx) {
523  const uint256& hash = e.GetTx().GetHash();
524  UniValue info(UniValue::VOBJ);
525  entryToJSON(pool, info, e);
526  // Mempool has unique entries so there is no advantage in using
527  // UniValue::pushKV, which checks if the key already exists in O(N).
528  // UniValue::__pushKV is used instead which currently is O(1).
529  o.__pushKV(hash.ToString(), info);
530  }
531  return o;
532  } else {
533  uint64_t mempool_sequence;
534  std::vector<uint256> vtxid;
535  {
536  LOCK(pool.cs);
537  pool.queryHashes(vtxid);
538  mempool_sequence = pool.GetSequence();
539  }
541  for (const uint256& hash : vtxid)
542  a.push_back(hash.ToString());
543 
544  if (!include_mempool_sequence) {
545  return a;
546  } else {
548  o.pushKV("txids", a);
549  o.pushKV("mempool_sequence", mempool_sequence);
550  return o;
551  }
552  }
553 }
554 
556 {
557  return RPCHelpMan{"getrawmempool",
558  "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
559  "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n",
560  {
561  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
562  {"mempool_sequence", RPCArg::Type::BOOL, RPCArg::Default{false}, "If verbose=false, returns a json object with transaction list and mempool sequence number attached."},
563  },
564  {
565  RPCResult{"for verbose = false",
566  RPCResult::Type::ARR, "", "",
567  {
568  {RPCResult::Type::STR_HEX, "", "The transaction id"},
569  }},
570  RPCResult{"for verbose = true",
571  RPCResult::Type::OBJ_DYN, "", "",
572  {
573  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
574  }},
575  RPCResult{"for verbose = false and mempool_sequence = true",
576  RPCResult::Type::OBJ, "", "",
577  {
578  {RPCResult::Type::ARR, "txids", "",
579  {
580  {RPCResult::Type::STR_HEX, "", "The transaction id"},
581  }},
582  {RPCResult::Type::NUM, "mempool_sequence", "The mempool sequence value."},
583  }},
584  },
585  RPCExamples{
586  HelpExampleCli("getrawmempool", "true")
587  + HelpExampleRpc("getrawmempool", "true")
588  },
589  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
590 {
591  bool fVerbose = false;
592  if (!request.params[0].isNull())
593  fVerbose = request.params[0].get_bool();
594 
595  bool include_mempool_sequence = false;
596  if (!request.params[1].isNull()) {
597  include_mempool_sequence = request.params[1].get_bool();
598  }
599 
600  return MempoolToJSON(EnsureAnyMemPool(request.context), fVerbose, include_mempool_sequence);
601 },
602  };
603 }
604 
606 {
607  return RPCHelpMan{"getmempoolancestors",
608  "\nIf txid is in the mempool, returns all in-mempool ancestors.\n",
609  {
610  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
611  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
612  },
613  {
614  RPCResult{"for verbose = false",
615  RPCResult::Type::ARR, "", "",
616  {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool ancestor transaction"}}},
617  RPCResult{"for verbose = true",
618  RPCResult::Type::OBJ_DYN, "", "",
619  {
620  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
621  }},
622  },
623  RPCExamples{
624  HelpExampleCli("getmempoolancestors", "\"mytxid\"")
625  + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
626  },
627  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
628 {
629  bool fVerbose = false;
630  if (!request.params[1].isNull())
631  fVerbose = request.params[1].get_bool();
632 
633  uint256 hash = ParseHashV(request.params[0], "parameter 1");
634 
635  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
636  LOCK(mempool.cs);
637 
638  CTxMemPool::txiter it = mempool.mapTx.find(hash);
639  if (it == mempool.mapTx.end()) {
640  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
641  }
642 
643  CTxMemPool::setEntries setAncestors;
644  uint64_t noLimit = std::numeric_limits<uint64_t>::max();
645  std::string dummy;
646  mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
647 
648  if (!fVerbose) {
650  for (CTxMemPool::txiter ancestorIt : setAncestors) {
651  o.push_back(ancestorIt->GetTx().GetHash().ToString());
652  }
653  return o;
654  } else {
656  for (CTxMemPool::txiter ancestorIt : setAncestors) {
657  const CTxMemPoolEntry &e = *ancestorIt;
658  const uint256& _hash = e.GetTx().GetHash();
659  UniValue info(UniValue::VOBJ);
660  entryToJSON(mempool, info, e);
661  o.pushKV(_hash.ToString(), info);
662  }
663  return o;
664  }
665 },
666  };
667 }
668 
670 {
671  return RPCHelpMan{"getmempooldescendants",
672  "\nIf txid is in the mempool, returns all in-mempool descendants.\n",
673  {
674  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
675  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
676  },
677  {
678  RPCResult{"for verbose = false",
679  RPCResult::Type::ARR, "", "",
680  {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool descendant transaction"}}},
681  RPCResult{"for verbose = true",
682  RPCResult::Type::OBJ_DYN, "", "",
683  {
684  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
685  }},
686  },
687  RPCExamples{
688  HelpExampleCli("getmempooldescendants", "\"mytxid\"")
689  + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
690  },
691  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
692 {
693  bool fVerbose = false;
694  if (!request.params[1].isNull())
695  fVerbose = request.params[1].get_bool();
696 
697  uint256 hash = ParseHashV(request.params[0], "parameter 1");
698 
699  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
700  LOCK(mempool.cs);
701 
702  CTxMemPool::txiter it = mempool.mapTx.find(hash);
703  if (it == mempool.mapTx.end()) {
704  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
705  }
706 
707  CTxMemPool::setEntries setDescendants;
708  mempool.CalculateDescendants(it, setDescendants);
709  // CTxMemPool::CalculateDescendants will include the given tx
710  setDescendants.erase(it);
711 
712  if (!fVerbose) {
714  for (CTxMemPool::txiter descendantIt : setDescendants) {
715  o.push_back(descendantIt->GetTx().GetHash().ToString());
716  }
717 
718  return o;
719  } else {
721  for (CTxMemPool::txiter descendantIt : setDescendants) {
722  const CTxMemPoolEntry &e = *descendantIt;
723  const uint256& _hash = e.GetTx().GetHash();
724  UniValue info(UniValue::VOBJ);
725  entryToJSON(mempool, info, e);
726  o.pushKV(_hash.ToString(), info);
727  }
728  return o;
729  }
730 },
731  };
732 }
733 
735 {
736  return RPCHelpMan{"getmempoolentry",
737  "\nReturns mempool data for given transaction\n",
738  {
739  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
740  },
741  RPCResult{
743  RPCExamples{
744  HelpExampleCli("getmempoolentry", "\"mytxid\"")
745  + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
746  },
747  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
748 {
749  uint256 hash = ParseHashV(request.params[0], "parameter 1");
750 
751  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
752  LOCK(mempool.cs);
753 
754  CTxMemPool::txiter it = mempool.mapTx.find(hash);
755  if (it == mempool.mapTx.end()) {
756  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
757  }
758 
759  const CTxMemPoolEntry &e = *it;
760  UniValue info(UniValue::VOBJ);
761  entryToJSON(mempool, info, e);
762  return info;
763 },
764  };
765 }
766 
768 {
769  return RPCHelpMan{"getblockhash",
770  "\nReturns hash of block in best-block-chain at height provided.\n",
771  {
772  {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"},
773  },
774  RPCResult{
775  RPCResult::Type::STR_HEX, "", "The block hash"},
776  RPCExamples{
777  HelpExampleCli("getblockhash", "1000")
778  + HelpExampleRpc("getblockhash", "1000")
779  },
780  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
781 {
782  ChainstateManager& chainman = EnsureAnyChainman(request.context);
783  LOCK(cs_main);
784  const CChain& active_chain = chainman.ActiveChain();
785 
786  int nHeight = request.params[0].get_int();
787  if (nHeight < 0 || nHeight > active_chain.Height())
788  throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
789 
790  CBlockIndex* pblockindex = active_chain[nHeight];
791  return pblockindex->GetBlockHash().GetHex();
792 },
793  };
794 }
795 
797 {
798  return RPCHelpMan{"getblockheader",
799  "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
800  "If verbose is true, returns an Object with information about blockheader <hash>.\n",
801  {
802  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
803  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{true}, "true for a json object, false for the hex-encoded data"},
804  },
805  {
806  RPCResult{"for verbose = true",
807  RPCResult::Type::OBJ, "", "",
808  {
809  {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"},
810  {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"},
811  {RPCResult::Type::NUM, "height", "The block height or index"},
812  {RPCResult::Type::NUM, "version", "The block version"},
813  {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"},
814  {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
815  {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
816  {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
817  {RPCResult::Type::NUM, "nonce", "The nonce"},
818  {RPCResult::Type::STR_HEX, "bits", "The bits"},
819  {RPCResult::Type::NUM, "difficulty", "The difficulty"},
820  {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"},
821  {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
822  {RPCResult::Type::STR_HEX, "previousblockhash", /* optional */ true, "The hash of the previous block (if available)"},
823  {RPCResult::Type::STR_HEX, "nextblockhash", /* optional */ true, "The hash of the next block (if available)"},
824  }},
825  RPCResult{"for verbose=false",
826  RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"},
827  },
828  RPCExamples{
829  HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
830  + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
831  },
832  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
833 {
834  uint256 hash(ParseHashV(request.params[0], "hash"));
835 
836  bool fVerbose = true;
837  if (!request.params[1].isNull())
838  fVerbose = request.params[1].get_bool();
839 
840  const CBlockIndex* pblockindex;
841  const CBlockIndex* tip;
842  {
843  ChainstateManager& chainman = EnsureAnyChainman(request.context);
844  LOCK(cs_main);
845  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
846  tip = chainman.ActiveChain().Tip();
847  }
848 
849  if (!pblockindex) {
850  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
851  }
852 
853  if (!fVerbose)
854  {
856  ssBlock << pblockindex->GetBlockHeader();
857  std::string strHex = HexStr(ssBlock);
858  return strHex;
859  }
860 
861  return blockheaderToJSON(tip, pblockindex);
862 },
863  };
864 }
865 
866 static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
867 {
868  CBlock block;
869  if (IsBlockPruned(pblockindex)) {
870  throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
871  }
872 
873  if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) {
874  // Block not found on disk. This could be because we have the block
875  // header in our index but not yet have the block or did not accept the
876  // block.
877  throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
878  }
879 
880  return block;
881 }
882 
883 static CBlockUndo GetUndoChecked(const CBlockIndex* pblockindex)
884 {
885  CBlockUndo blockUndo;
886  if (IsBlockPruned(pblockindex)) {
887  throw JSONRPCError(RPC_MISC_ERROR, "Undo data not available (pruned data)");
888  }
889 
890  if (!UndoReadFromDisk(blockUndo, pblockindex)) {
891  throw JSONRPCError(RPC_MISC_ERROR, "Can't read undo data from disk");
892  }
893 
894  return blockUndo;
895 }
896 
898 {
899  return RPCHelpMan{"getblock",
900  "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
901  "If verbosity is 1, returns an Object with information about block <hash>.\n"
902  "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n",
903  {
904  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
905  {"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{1}, "0 for hex-encoded data, 1 for a json object, and 2 for json object with transaction data"},
906  },
907  {
908  RPCResult{"for verbosity = 0",
909  RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"},
910  RPCResult{"for verbosity = 1",
911  RPCResult::Type::OBJ, "", "",
912  {
913  {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"},
914  {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"},
915  {RPCResult::Type::NUM, "size", "The block size"},
916  {RPCResult::Type::NUM, "strippedsize", "The block size excluding witness data"},
917  {RPCResult::Type::NUM, "weight", "The block weight as defined in BIP 141"},
918  {RPCResult::Type::NUM, "height", "The block height or index"},
919  {RPCResult::Type::NUM, "version", "The block version"},
920  {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"},
921  {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
922  {RPCResult::Type::ARR, "tx", "The transaction ids",
923  {{RPCResult::Type::STR_HEX, "", "The transaction id"}}},
924  {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
925  {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
926  {RPCResult::Type::NUM, "nonce", "The nonce"},
927  {RPCResult::Type::STR_HEX, "bits", "The bits"},
928  {RPCResult::Type::NUM, "difficulty", "The difficulty"},
929  {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the chain up to this block (in hex)"},
930  {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
931  {RPCResult::Type::STR_HEX, "previousblockhash", /* optional */ true, "The hash of the previous block (if available)"},
932  {RPCResult::Type::STR_HEX, "nextblockhash", /* optional */ true, "The hash of the next block (if available)"},
933  }},
934  RPCResult{"for verbosity = 2",
935  RPCResult::Type::OBJ, "", "",
936  {
937  {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
938  {RPCResult::Type::ARR, "tx", "",
939  {
940  {RPCResult::Type::OBJ, "", "",
941  {
942  {RPCResult::Type::ELISION, "", "The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result"},
943  {RPCResult::Type::NUM, "fee", "The transaction fee in " + CURRENCY_UNIT + ", omitted if block undo data is not available"},
944  }},
945  }},
946  }},
947  },
948  RPCExamples{
949  HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
950  + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
951  },
952  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
953 {
954  uint256 hash(ParseHashV(request.params[0], "blockhash"));
955 
956  int verbosity = 1;
957  if (!request.params[1].isNull()) {
958  if (request.params[1].isBool()) {
959  verbosity = request.params[1].get_bool() ? 1 : 0;
960  } else {
961  verbosity = request.params[1].get_int();
962  }
963  }
964 
965  CBlock block;
966  const CBlockIndex* pblockindex;
967  const CBlockIndex* tip;
968  {
969  ChainstateManager& chainman = EnsureAnyChainman(request.context);
970  LOCK(cs_main);
971  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
972  tip = chainman.ActiveChain().Tip();
973 
974  if (!pblockindex) {
975  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
976  }
977 
978  block = GetBlockChecked(pblockindex);
979  }
980 
981  if (verbosity <= 0)
982  {
984  ssBlock << block;
985  std::string strHex = HexStr(ssBlock);
986  return strHex;
987  }
988 
989  return blockToJSON(block, tip, pblockindex, verbosity >= 2);
990 },
991  };
992 }
993 
995 {
996  return RPCHelpMan{"pruneblockchain", "",
997  {
998  {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block height to prune up to. May be set to a discrete height, or to a " + UNIX_EPOCH_TIME + "\n"
999  " to prune blocks whose block time is at least 2 hours older than the provided timestamp."},
1000  },
1001  RPCResult{
1002  RPCResult::Type::NUM, "", "Height of the last block pruned"},
1003  RPCExamples{
1004  HelpExampleCli("pruneblockchain", "1000")
1005  + HelpExampleRpc("pruneblockchain", "1000")
1006  },
1007  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1008 {
1009  if (!fPruneMode)
1010  throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
1011 
1012  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1013  LOCK(cs_main);
1014  CChainState& active_chainstate = chainman.ActiveChainstate();
1015  CChain& active_chain = active_chainstate.m_chain;
1016 
1017  int heightParam = request.params[0].get_int();
1018  if (heightParam < 0)
1019  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
1020 
1021  // Height value more than a billion is too high to be a block height, and
1022  // too low to be a block time (corresponds to timestamp from Sep 2001).
1023  if (heightParam > 1000000000) {
1024  // Add a 2 hour buffer to include blocks which might have had old timestamps
1025  CBlockIndex* pindex = active_chain.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW, 0);
1026  if (!pindex) {
1027  throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
1028  }
1029  heightParam = pindex->nHeight;
1030  }
1031 
1032  unsigned int height = (unsigned int) heightParam;
1033  unsigned int chainHeight = (unsigned int) active_chain.Height();
1034  if (chainHeight < Params().PruneAfterHeight())
1035  throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
1036  else if (height > chainHeight)
1037  throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
1038  else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
1039  LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.\n");
1040  height = chainHeight - MIN_BLOCKS_TO_KEEP;
1041  }
1042 
1043  PruneBlockFilesManual(active_chainstate, height);
1044  const CBlockIndex* block = active_chain.Tip();
1045  CHECK_NONFATAL(block);
1046  while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
1047  block = block->pprev;
1048  }
1049  return uint64_t(block->nHeight);
1050 },
1051  };
1052 }
1053 
1054 CoinStatsHashType ParseHashType(const std::string& hash_type_input)
1055 {
1056  if (hash_type_input == "hash_serialized_2") {
1058  } else if (hash_type_input == "muhash") {
1060  } else if (hash_type_input == "none") {
1061  return CoinStatsHashType::NONE;
1062  } else {
1063  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s is not a valid hash_type", hash_type_input));
1064  }
1065 }
1066 
1068 {
1069  return RPCHelpMan{"gettxoutsetinfo",
1070  "\nReturns statistics about the unspent transaction output set.\n"
1071  "Note this call may take some time.\n",
1072  {
1073  {"hash_type", RPCArg::Type::STR, RPCArg::Default{"hash_serialized_2"}, "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'."},
1074  },
1075  RPCResult{
1076  RPCResult::Type::OBJ, "", "",
1077  {
1078  {RPCResult::Type::NUM, "height", "The block height (index) of the returned statistics"},
1079  {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at which these statistics are calculated"},
1080  {RPCResult::Type::NUM, "transactions", "The number of transactions with unspent outputs"},
1081  {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs"},
1082  {RPCResult::Type::NUM, "bogosize", "A meaningless metric for UTXO set size"},
1083  {RPCResult::Type::STR_HEX, "hash_serialized_2", /* optional */ true, "The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)"},
1084  {RPCResult::Type::STR_HEX, "muhash", /* optional */ true, "The serialized hash (only present if 'muhash' hash_type is chosen)"},
1085  {RPCResult::Type::NUM, "disk_size", "The estimated size of the chainstate on disk"},
1086  {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of coins in the UTXO set"},
1087  }},
1088  RPCExamples{
1089  HelpExampleCli("gettxoutsetinfo", "")
1090  + HelpExampleRpc("gettxoutsetinfo", "")
1091  },
1092  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1093 {
1094  UniValue ret(UniValue::VOBJ);
1095 
1096  CCoinsStats stats;
1097  NodeContext& node = EnsureAnyNodeContext(request.context);
1098  ChainstateManager& chainman = EnsureChainman(node);
1099  CChainState& active_chainstate = chainman.ActiveChainstate();
1100  active_chainstate.ForceFlushStateToDisk();
1101 
1102  const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())};
1103 
1104  CCoinsView* coins_view;
1105  BlockManager* blockman;
1106  {
1107  LOCK(::cs_main);
1108  coins_view = &active_chainstate.CoinsDB();
1109  blockman = &active_chainstate.m_blockman;
1110  }
1111  if (GetUTXOStats(coins_view, *blockman, stats, hash_type, node.rpc_interruption_point)) {
1112  ret.pushKV("height", (int64_t)stats.nHeight);
1113  ret.pushKV("bestblock", stats.hashBlock.GetHex());
1114  ret.pushKV("transactions", (int64_t)stats.nTransactions);
1115  ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs);
1116  ret.pushKV("bogosize", (int64_t)stats.nBogoSize);
1117  if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1118  ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex());
1119  }
1120  if (hash_type == CoinStatsHashType::MUHASH) {
1121  ret.pushKV("muhash", stats.hashSerialized.GetHex());
1122  }
1123  ret.pushKV("disk_size", stats.nDiskSize);
1124  ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount));
1125  } else {
1126  throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
1127  }
1128  return ret;
1129 },
1130  };
1131 }
1132 
1134 {
1135  return RPCHelpMan{"gettxout",
1136  "\nReturns details about an unspent transaction output.\n",
1137  {
1138  {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"},
1139  {"n", RPCArg::Type::NUM, RPCArg::Optional::NO, "vout number"},
1140  {"include_mempool", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."},
1141  },
1142  {
1143  RPCResult{"If the UTXO was not found", RPCResult::Type::NONE, "", ""},
1144  RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "", {
1145  {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
1146  {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
1147  {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT},
1148  {RPCResult::Type::OBJ, "scriptPubKey", "", {
1149  {RPCResult::Type::STR, "asm", ""},
1150  {RPCResult::Type::STR_HEX, "hex", ""},
1151  {RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
1152  {RPCResult::Type::STR, "type", "The type, eg pubkeyhash"},
1153  {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin address (only if a well-defined address exists)"},
1154  {RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of bitcoin addresses",
1155  {{RPCResult::Type::STR, "address", "bitcoin address"}}},
1156  }},
1157  {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
1158  }},
1159  },
1160  RPCExamples{
1161  "\nGet unspent transactions\n"
1162  + HelpExampleCli("listunspent", "") +
1163  "\nView the details\n"
1164  + HelpExampleCli("gettxout", "\"txid\" 1") +
1165  "\nAs a JSON-RPC call\n"
1166  + HelpExampleRpc("gettxout", "\"txid\", 1")
1167  },
1168  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1169 {
1170  NodeContext& node = EnsureAnyNodeContext(request.context);
1171  ChainstateManager& chainman = EnsureChainman(node);
1172  LOCK(cs_main);
1173 
1174  UniValue ret(UniValue::VOBJ);
1175 
1176  uint256 hash(ParseHashV(request.params[0], "txid"));
1177  int n = request.params[1].get_int();
1178  COutPoint out(hash, n);
1179  bool fMempool = true;
1180  if (!request.params[2].isNull())
1181  fMempool = request.params[2].get_bool();
1182 
1183  Coin coin;
1184  CChainState& active_chainstate = chainman.ActiveChainstate();
1185  CCoinsViewCache* coins_view = &active_chainstate.CoinsTip();
1186 
1187  if (fMempool) {
1188  const CTxMemPool& mempool = EnsureMemPool(node);
1189  LOCK(mempool.cs);
1190  CCoinsViewMemPool view(coins_view, mempool);
1191  if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
1192  return NullUniValue;
1193  }
1194  } else {
1195  if (!coins_view->GetCoin(out, coin)) {
1196  return NullUniValue;
1197  }
1198  }
1199 
1200  const CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(coins_view->GetBestBlock());
1201  ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
1202  if (coin.nHeight == MEMPOOL_HEIGHT) {
1203  ret.pushKV("confirmations", 0);
1204  } else {
1205  ret.pushKV("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1));
1206  }
1207  ret.pushKV("value", ValueFromAmount(coin.out.nValue));
1209  ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1210  ret.pushKV("scriptPubKey", o);
1211  ret.pushKV("coinbase", (bool)coin.fCoinBase);
1212 
1213  return ret;
1214 },
1215  };
1216 }
1217 
1219 {
1220  return RPCHelpMan{"verifychain",
1221  "\nVerifies blockchain database.\n",
1222  {
1223  {"checklevel", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL)},
1224  strprintf("How thorough the block verification is:\n - %s", Join(CHECKLEVEL_DOC, "\n- "))},
1225  {"nblocks", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, 0=all", DEFAULT_CHECKBLOCKS)}, "The number of blocks to check."},
1226  },
1227  RPCResult{
1228  RPCResult::Type::BOOL, "", "Verified or not"},
1229  RPCExamples{
1230  HelpExampleCli("verifychain", "")
1231  + HelpExampleRpc("verifychain", "")
1232  },
1233  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1234 {
1235  const int check_level(request.params[0].isNull() ? DEFAULT_CHECKLEVEL : request.params[0].get_int());
1236  const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()};
1237 
1238  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1239  LOCK(cs_main);
1240 
1241  CChainState& active_chainstate = chainman.ActiveChainstate();
1242  return CVerifyDB().VerifyDB(Params(), active_chainstate, &active_chainstate.CoinsTip(), check_level, check_depth);
1243 },
1244  };
1245 }
1246 
1247 static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int softfork_height, int tip_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
1248 {
1249  // For buried deployments.
1250  // A buried deployment is one where the height of the activation has been hardcoded into
1251  // the client implementation long after the consensus change has activated. See BIP 90.
1252  // Buried deployments with activation height value of
1253  // std::numeric_limits<int>::max() are disabled and thus hidden.
1254  if (softfork_height == std::numeric_limits<int>::max()) return;
1255 
1257  rv.pushKV("type", "buried");
1258  // getblockchaininfo reports the softfork as active from when the chain height is
1259  // one below the activation height
1260  rv.pushKV("active", tip_height + 1 >= softfork_height);
1261  rv.pushKV("height", softfork_height);
1262  softforks.pushKV(name, rv);
1263 }
1264 
1265 static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
1266 {
1267  // For BIP9 deployments.
1268  // Deployments that are never active are hidden.
1269  if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
1270 
1271  UniValue bip9(UniValue::VOBJ);
1272  const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, versionbitscache);
1273  switch (thresholdState) {
1274  case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); break;
1275  case ThresholdState::STARTED: bip9.pushKV("status", "started"); break;
1276  case ThresholdState::LOCKED_IN: bip9.pushKV("status", "locked_in"); break;
1277  case ThresholdState::ACTIVE: bip9.pushKV("status", "active"); break;
1278  case ThresholdState::FAILED: bip9.pushKV("status", "failed"); break;
1279  }
1280  if (ThresholdState::STARTED == thresholdState)
1281  {
1282  bip9.pushKV("bit", consensusParams.vDeployments[id].bit);
1283  }
1284  bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
1285  bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
1286  int64_t since_height = VersionBitsStateSinceHeight(active_chain_tip, consensusParams, id, versionbitscache);
1287  bip9.pushKV("since", since_height);
1288  if (ThresholdState::STARTED == thresholdState)
1289  {
1290  UniValue statsUV(UniValue::VOBJ);
1291  BIP9Stats statsStruct = VersionBitsStatistics(active_chain_tip, consensusParams, id);
1292  statsUV.pushKV("period", statsStruct.period);
1293  statsUV.pushKV("threshold", statsStruct.threshold);
1294  statsUV.pushKV("elapsed", statsStruct.elapsed);
1295  statsUV.pushKV("count", statsStruct.count);
1296  statsUV.pushKV("possible", statsStruct.possible);
1297  bip9.pushKV("statistics", statsUV);
1298  }
1299  bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
1300 
1302  rv.pushKV("type", "bip9");
1303  rv.pushKV("bip9", bip9);
1304  if (ThresholdState::ACTIVE == thresholdState) {
1305  rv.pushKV("height", since_height);
1306  }
1307  rv.pushKV("active", ThresholdState::ACTIVE == thresholdState);
1308 
1309  softforks.pushKV(name, rv);
1310 }
1311 
1313 {
1314  return RPCHelpMan{"getblockchaininfo",
1315  "Returns an object containing various state info regarding blockchain processing.\n",
1316  {},
1317  RPCResult{
1318  RPCResult::Type::OBJ, "", "",
1319  {
1320  {RPCResult::Type::STR, "chain", "current network name (main, test, signet, regtest)"},
1321  {RPCResult::Type::NUM, "blocks", "the height of the most-work fully-validated chain. The genesis block has height 0"},
1322  {RPCResult::Type::NUM, "headers", "the current number of headers we have validated"},
1323  {RPCResult::Type::STR, "bestblockhash", "the hash of the currently best block"},
1324  {RPCResult::Type::NUM, "difficulty", "the current difficulty"},
1325  {RPCResult::Type::NUM, "mediantime", "median time for the current best block"},
1326  {RPCResult::Type::NUM, "verificationprogress", "estimate of verification progress [0..1]"},
1327  {RPCResult::Type::BOOL, "initialblockdownload", "(debug information) estimate of whether this node is in Initial Block Download mode"},
1328  {RPCResult::Type::STR_HEX, "chainwork", "total amount of work in active chain, in hexadecimal"},
1329  {RPCResult::Type::NUM, "size_on_disk", "the estimated size of the block and undo files on disk"},
1330  {RPCResult::Type::BOOL, "pruned", "if the blocks are subject to pruning"},
1331  {RPCResult::Type::NUM, "pruneheight", "lowest-height complete block stored (only present if pruning is enabled)"},
1332  {RPCResult::Type::BOOL, "automatic_pruning", "whether automatic pruning is enabled (only present if pruning is enabled)"},
1333  {RPCResult::Type::NUM, "prune_target_size", "the target size used by pruning (only present if automatic pruning is enabled)"},
1334  {RPCResult::Type::OBJ_DYN, "softforks", "status of softforks",
1335  {
1336  {RPCResult::Type::OBJ, "xxxx", "name of the softfork",
1337  {
1338  {RPCResult::Type::STR, "type", "one of \"buried\", \"bip9\""},
1339  {RPCResult::Type::OBJ, "bip9", "status of bip9 softforks (only for \"bip9\" type)",
1340  {
1341  {RPCResult::Type::STR, "status", "one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\""},
1342  {RPCResult::Type::NUM, "bit", "the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)"},
1343  {RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
1344  {RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
1345  {RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
1346  {RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
1347  {RPCResult::Type::OBJ, "statistics", "numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)",
1348  {
1349  {RPCResult::Type::NUM, "period", "the length in blocks of the BIP9 signalling period"},
1350  {RPCResult::Type::NUM, "threshold", "the number of blocks with the version bit set required to activate the feature"},
1351  {RPCResult::Type::NUM, "elapsed", "the number of blocks elapsed since the beginning of the current period"},
1352  {RPCResult::Type::NUM, "count", "the number of blocks with the version bit set in the current period"},
1353  {RPCResult::Type::BOOL, "possible", "returns false if there are not enough blocks left in this period to pass activation threshold"},
1354  }},
1355  }},
1356  {RPCResult::Type::NUM, "height", "height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)"},
1357  {RPCResult::Type::BOOL, "active", "true if the rules are enforced for the mempool and the next block"},
1358  }},
1359  }},
1360  {RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
1361  }},
1362  RPCExamples{
1363  HelpExampleCli("getblockchaininfo", "")
1364  + HelpExampleRpc("getblockchaininfo", "")
1365  },
1366  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1367 {
1368  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1369  LOCK(cs_main);
1370  CChainState& active_chainstate = chainman.ActiveChainstate();
1371 
1372  const CBlockIndex* tip = active_chainstate.m_chain.Tip();
1373  CHECK_NONFATAL(tip);
1374  const int height = tip->nHeight;
1375  UniValue obj(UniValue::VOBJ);
1376  obj.pushKV("chain", Params().NetworkIDString());
1377  obj.pushKV("blocks", height);
1378  obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1);
1379  obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
1380  obj.pushKV("difficulty", (double)GetDifficulty(tip));
1381  obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast());
1382  obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
1383  obj.pushKV("initialblockdownload", active_chainstate.IsInitialBlockDownload());
1384  obj.pushKV("chainwork", tip->nChainWork.GetHex());
1385  obj.pushKV("size_on_disk", CalculateCurrentUsage());
1386  obj.pushKV("pruned", fPruneMode);
1387  if (fPruneMode) {
1388  const CBlockIndex* block = tip;
1389  CHECK_NONFATAL(block);
1390  while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
1391  block = block->pprev;
1392  }
1393 
1394  obj.pushKV("pruneheight", block->nHeight);
1395 
1396  // if 0, execution bypasses the whole if block.
1397  bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1);
1398  obj.pushKV("automatic_pruning", automatic_pruning);
1399  if (automatic_pruning) {
1400  obj.pushKV("prune_target_size", nPruneTarget);
1401  }
1402  }
1403 
1404  const Consensus::Params& consensusParams = Params().GetConsensus();
1405  UniValue softforks(UniValue::VOBJ);
1406  BuriedForkDescPushBack(softforks, "bip34", consensusParams.BIP34Height, height);
1407  BuriedForkDescPushBack(softforks, "bip66", consensusParams.BIP66Height, height);
1408  BuriedForkDescPushBack(softforks, "bip65", consensusParams.BIP65Height, height);
1409  BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight, height);
1410  BuriedForkDescPushBack(softforks, "segwit", consensusParams.SegwitHeight, height);
1411  BIP9SoftForkDescPushBack(tip, softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
1412  BIP9SoftForkDescPushBack(tip, softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
1413  obj.pushKV("softforks", softforks);
1414 
1415  obj.pushKV("warnings", GetWarnings(false).original);
1416  return obj;
1417 },
1418  };
1419 }
1420 
1423 {
1424  bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1425  {
1426  /* Make sure that unequal blocks with the same height do not compare
1427  equal. Use the pointers themselves to make a distinction. */
1428 
1429  if (a->nHeight != b->nHeight)
1430  return (a->nHeight > b->nHeight);
1431 
1432  return a < b;
1433  }
1434 };
1435 
1437 {
1438  return RPCHelpMan{"getchaintips",
1439  "Return information about all known tips in the block tree,"
1440  " including the main chain as well as orphaned branches.\n",
1441  {},
1442  RPCResult{
1443  RPCResult::Type::ARR, "", "",
1444  {{RPCResult::Type::OBJ, "", "",
1445  {
1446  {RPCResult::Type::NUM, "height", "height of the chain tip"},
1447  {RPCResult::Type::STR_HEX, "hash", "block hash of the tip"},
1448  {RPCResult::Type::NUM, "branchlen", "zero for main chain, otherwise length of branch connecting the tip to the main chain"},
1449  {RPCResult::Type::STR, "status", "status of the chain, \"active\" for the main chain\n"
1450  "Possible values for status:\n"
1451  "1. \"invalid\" This branch contains at least one invalid block\n"
1452  "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1453  "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1454  "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1455  "5. \"active\" This is the tip of the active main chain, which is certainly valid"},
1456  }}}},
1457  RPCExamples{
1458  HelpExampleCli("getchaintips", "")
1459  + HelpExampleRpc("getchaintips", "")
1460  },
1461  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1462 {
1463  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1464  LOCK(cs_main);
1465  CChain& active_chain = chainman.ActiveChain();
1466 
1467  /*
1468  * Idea: The set of chain tips is the active chain tip, plus orphan blocks which do not have another orphan building off of them.
1469  * Algorithm:
1470  * - Make one pass through BlockIndex(), picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1471  * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1472  * - Add the active chain tip
1473  */
1474  std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1475  std::set<const CBlockIndex*> setOrphans;
1476  std::set<const CBlockIndex*> setPrevs;
1477 
1478  for (const std::pair<const uint256, CBlockIndex*>& item : chainman.BlockIndex()) {
1479  if (!active_chain.Contains(item.second)) {
1480  setOrphans.insert(item.second);
1481  setPrevs.insert(item.second->pprev);
1482  }
1483  }
1484 
1485  for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) {
1486  if (setPrevs.erase(*it) == 0) {
1487  setTips.insert(*it);
1488  }
1489  }
1490 
1491  // Always report the currently active tip.
1492  setTips.insert(active_chain.Tip());
1493 
1494  /* Construct the output array. */
1495  UniValue res(UniValue::VARR);
1496  for (const CBlockIndex* block : setTips) {
1497  UniValue obj(UniValue::VOBJ);
1498  obj.pushKV("height", block->nHeight);
1499  obj.pushKV("hash", block->phashBlock->GetHex());
1500 
1501  const int branchLen = block->nHeight - active_chain.FindFork(block)->nHeight;
1502  obj.pushKV("branchlen", branchLen);
1503 
1504  std::string status;
1505  if (active_chain.Contains(block)) {
1506  // This block is part of the currently active chain.
1507  status = "active";
1508  } else if (block->nStatus & BLOCK_FAILED_MASK) {
1509  // This block or one of its ancestors is invalid.
1510  status = "invalid";
1511  } else if (!block->HaveTxsDownloaded()) {
1512  // This block cannot be connected because full block data for it or one of its parents is missing.
1513  status = "headers-only";
1514  } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1515  // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1516  status = "valid-fork";
1517  } else if (block->IsValid(BLOCK_VALID_TREE)) {
1518  // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1519  status = "valid-headers";
1520  } else {
1521  // No clue.
1522  status = "unknown";
1523  }
1524  obj.pushKV("status", status);
1525 
1526  res.push_back(obj);
1527  }
1528 
1529  return res;
1530 },
1531  };
1532 }
1533 
1535 {
1536  // Make sure this call is atomic in the pool.
1537  LOCK(pool.cs);
1538  UniValue ret(UniValue::VOBJ);
1539  ret.pushKV("loaded", pool.IsLoaded());
1540  ret.pushKV("size", (int64_t)pool.size());
1541  ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
1542  ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
1543  ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee()));
1544  size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1545  ret.pushKV("maxmempool", (int64_t) maxmempool);
1546  ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
1547  ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
1548  ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()});
1549  return ret;
1550 }
1551 
1553 {
1554  return RPCHelpMan{"getmempoolinfo",
1555  "\nReturns details on the active state of the TX memory pool.\n",
1556  {},
1557  RPCResult{
1558  RPCResult::Type::OBJ, "", "",
1559  {
1560  {RPCResult::Type::BOOL, "loaded", "True if the mempool is fully loaded"},
1561  {RPCResult::Type::NUM, "size", "Current tx count"},
1562  {RPCResult::Type::NUM, "bytes", "Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted"},
1563  {RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
1564  {RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritizetransaction"},
1565  {RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
1566  {RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
1567  {RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
1568  {RPCResult::Type::NUM, "unbroadcastcount", "Current number of transactions that haven't passed initial broadcast yet"}
1569  }},
1570  RPCExamples{
1571  HelpExampleCli("getmempoolinfo", "")
1572  + HelpExampleRpc("getmempoolinfo", "")
1573  },
1574  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1575 {
1576  return MempoolInfoToJSON(EnsureAnyMemPool(request.context));
1577 },
1578  };
1579 }
1580 
1582 {
1583  return RPCHelpMan{"preciousblock",
1584  "\nTreats a block as if it were received before others with the same work.\n"
1585  "\nA later preciousblock call can override the effect of an earlier one.\n"
1586  "\nThe effects of preciousblock are not retained across restarts.\n",
1587  {
1588  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to mark as precious"},
1589  },
1591  RPCExamples{
1592  HelpExampleCli("preciousblock", "\"blockhash\"")
1593  + HelpExampleRpc("preciousblock", "\"blockhash\"")
1594  },
1595  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1596 {
1597  uint256 hash(ParseHashV(request.params[0], "blockhash"));
1598  CBlockIndex* pblockindex;
1599 
1600  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1601  {
1602  LOCK(cs_main);
1603  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
1604  if (!pblockindex) {
1605  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1606  }
1607  }
1608 
1609  BlockValidationState state;
1610  chainman.ActiveChainstate().PreciousBlock(state, Params(), pblockindex);
1611 
1612  if (!state.IsValid()) {
1613  throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
1614  }
1615 
1616  return NullUniValue;
1617 },
1618  };
1619 }
1620 
1622 {
1623  return RPCHelpMan{"invalidateblock",
1624  "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n",
1625  {
1626  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to mark as invalid"},
1627  },
1629  RPCExamples{
1630  HelpExampleCli("invalidateblock", "\"blockhash\"")
1631  + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1632  },
1633  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1634 {
1635  uint256 hash(ParseHashV(request.params[0], "blockhash"));
1636  BlockValidationState state;
1637 
1638  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1639  CBlockIndex* pblockindex;
1640  {
1641  LOCK(cs_main);
1642  pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
1643  if (!pblockindex) {
1644  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1645  }
1646  }
1647  chainman.ActiveChainstate().InvalidateBlock(state, Params(), pblockindex);
1648 
1649  if (state.IsValid()) {
1650  chainman.ActiveChainstate().ActivateBestChain(state, Params());
1651  }
1652 
1653  if (!state.IsValid()) {
1654  throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
1655  }
1656 
1657  return NullUniValue;
1658 },
1659  };
1660 }
1661 
1663 {
1664  return RPCHelpMan{"reconsiderblock",
1665  "\nRemoves invalidity status of a block, its ancestors and its descendants, reconsider them for activation.\n"
1666  "This can be used to undo the effects of invalidateblock.\n",
1667  {
1668  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to reconsider"},
1669  },
1671  RPCExamples{
1672  HelpExampleCli("reconsiderblock", "\"blockhash\"")
1673  + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1674  },
1675  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1676 {
1677  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1678  uint256 hash(ParseHashV(request.params[0], "blockhash"));
1679 
1680  {
1681  LOCK(cs_main);
1682  CBlockIndex* pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
1683  if (!pblockindex) {
1684  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1685  }
1686 
1687  chainman.ActiveChainstate().ResetBlockFailureFlags(pblockindex);
1688  }
1689 
1690  BlockValidationState state;
1691  chainman.ActiveChainstate().ActivateBestChain(state, Params());
1692 
1693  if (!state.IsValid()) {
1694  throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
1695  }
1696 
1697  return NullUniValue;
1698 },
1699  };
1700 }
1701 
1703 {
1704  return RPCHelpMan{"getchaintxstats",
1705  "\nCompute statistics about the total number and rate of transactions in the chain.\n",
1706  {
1707  {"nblocks", RPCArg::Type::NUM, RPCArg::DefaultHint{"one month"}, "Size of the window in number of blocks"},
1708  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::DefaultHint{"chain tip"}, "The hash of the block that ends the window."},
1709  },
1710  RPCResult{
1711  RPCResult::Type::OBJ, "", "",
1712  {
1713  {RPCResult::Type::NUM_TIME, "time", "The timestamp for the final block in the window, expressed in " + UNIX_EPOCH_TIME},
1714  {RPCResult::Type::NUM, "txcount", "The total number of transactions in the chain up to that point"},
1715  {RPCResult::Type::STR_HEX, "window_final_block_hash", "The hash of the final block in the window"},
1716  {RPCResult::Type::NUM, "window_final_block_height", "The height of the final block in the window."},
1717  {RPCResult::Type::NUM, "window_block_count", "Size of the window in number of blocks"},
1718  {RPCResult::Type::NUM, "window_tx_count", /* optional */ true, "The number of transactions in the window. Only returned if \"window_block_count\" is > 0"},
1719  {RPCResult::Type::NUM, "window_interval", /* optional */ true, "The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0"},
1720  {RPCResult::Type::NUM, "txrate", /* optional */ true, "The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0"},
1721  }},
1722  RPCExamples{
1723  HelpExampleCli("getchaintxstats", "")
1724  + HelpExampleRpc("getchaintxstats", "2016")
1725  },
1726  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1727 {
1728  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1729  const CBlockIndex* pindex;
1730  int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1731 
1732  if (request.params[1].isNull()) {
1733  LOCK(cs_main);
1734  pindex = chainman.ActiveChain().Tip();
1735  } else {
1736  uint256 hash(ParseHashV(request.params[1], "blockhash"));
1737  LOCK(cs_main);
1738  pindex = chainman.m_blockman.LookupBlockIndex(hash);
1739  if (!pindex) {
1740  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1741  }
1742  if (!chainman.ActiveChain().Contains(pindex)) {
1743  throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1744  }
1745  }
1746 
1747  CHECK_NONFATAL(pindex != nullptr);
1748 
1749  if (request.params[0].isNull()) {
1750  blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1));
1751  } else {
1752  blockcount = request.params[0].get_int();
1753 
1754  if (blockcount < 0 || (blockcount > 0 && blockcount >= pindex->nHeight)) {
1755  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 0 and the block's height - 1");
1756  }
1757  }
1758 
1759  const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1760  int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1761  int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1762 
1763  UniValue ret(UniValue::VOBJ);
1764  ret.pushKV("time", (int64_t)pindex->nTime);
1765  ret.pushKV("txcount", (int64_t)pindex->nChainTx);
1766  ret.pushKV("window_final_block_hash", pindex->GetBlockHash().GetHex());
1767  ret.pushKV("window_final_block_height", pindex->nHeight);
1768  ret.pushKV("window_block_count", blockcount);
1769  if (blockcount > 0) {
1770  ret.pushKV("window_tx_count", nTxDiff);
1771  ret.pushKV("window_interval", nTimeDiff);
1772  if (nTimeDiff > 0) {
1773  ret.pushKV("txrate", ((double)nTxDiff) / nTimeDiff);
1774  }
1775  }
1776 
1777  return ret;
1778 },
1779  };
1780 }
1781 
1782 template<typename T>
1783 static T CalculateTruncatedMedian(std::vector<T>& scores)
1784 {
1785  size_t size = scores.size();
1786  if (size == 0) {
1787  return 0;
1788  }
1789 
1790  std::sort(scores.begin(), scores.end());
1791  if (size % 2 == 0) {
1792  return (scores[size / 2 - 1] + scores[size / 2]) / 2;
1793  } else {
1794  return scores[size / 2];
1795  }
1796 }
1797 
1798 void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight)
1799 {
1800  if (scores.empty()) {
1801  return;
1802  }
1803 
1804  std::sort(scores.begin(), scores.end());
1805 
1806  // 10th, 25th, 50th, 75th, and 90th percentile weight units.
1807  const double weights[NUM_GETBLOCKSTATS_PERCENTILES] = {
1808  total_weight / 10.0, total_weight / 4.0, total_weight / 2.0, (total_weight * 3.0) / 4.0, (total_weight * 9.0) / 10.0
1809  };
1810 
1811  int64_t next_percentile_index = 0;
1812  int64_t cumulative_weight = 0;
1813  for (const auto& element : scores) {
1814  cumulative_weight += element.second;
1815  while (next_percentile_index < NUM_GETBLOCKSTATS_PERCENTILES && cumulative_weight >= weights[next_percentile_index]) {
1816  result[next_percentile_index] = element.first;
1817  ++next_percentile_index;
1818  }
1819  }
1820 
1821  // Fill any remaining percentiles with the last value.
1822  for (int64_t i = next_percentile_index; i < NUM_GETBLOCKSTATS_PERCENTILES; i++) {
1823  result[i] = scores.back().first;
1824  }
1825 }
1826 
1827 void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
1828 {
1829  ScriptPubKeyToUniv(scriptPubKey, out, fIncludeHex, IsDeprecatedRPCEnabled("addresses"));
1830 }
1831 
1832 void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo)
1833 {
1834  TxToUniv(tx, hashBlock, IsDeprecatedRPCEnabled("addresses"), entry, include_hex, serialize_flags, txundo);
1835 }
1836 
1837 template<typename T>
1838 static inline bool SetHasKeys(const std::set<T>& set) {return false;}
1839 template<typename T, typename Tk, typename... Args>
1840 static inline bool SetHasKeys(const std::set<T>& set, const Tk& key, const Args&... args)
1841 {
1842  return (set.count(key) != 0) || SetHasKeys(set, args...);
1843 }
1844 
1845 // outpoint (needed for the utxo index) + nHeight + fCoinBase
1846 static constexpr size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool);
1847 
1849 {
1850  return RPCHelpMan{"getblockstats",
1851  "\nCompute per block statistics for a given window. All amounts are in satoshis.\n"
1852  "It won't work for some heights with pruning.\n",
1853  {
1854  {"hash_or_height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block hash or height of the target block", "", {"", "string or numeric"}},
1855  {"stats", RPCArg::Type::ARR, RPCArg::DefaultHint{"all values"}, "Values to plot (see result below)",
1856  {
1857  {"height", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Selected statistic"},
1858  {"time", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Selected statistic"},
1859  },
1860  "stats"},
1861  },
1862  RPCResult{
1863  RPCResult::Type::OBJ, "", "",
1864  {
1865  {RPCResult::Type::NUM, "avgfee", "Average fee in the block"},
1866  {RPCResult::Type::NUM, "avgfeerate", "Average feerate (in satoshis per virtual byte)"},
1867  {RPCResult::Type::NUM, "avgtxsize", "Average transaction size"},
1868  {RPCResult::Type::STR_HEX, "blockhash", "The block hash (to check for potential reorgs)"},
1869  {RPCResult::Type::ARR_FIXED, "feerate_percentiles", "Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)",
1870  {
1871  {RPCResult::Type::NUM, "10th_percentile_feerate", "The 10th percentile feerate"},
1872  {RPCResult::Type::NUM, "25th_percentile_feerate", "The 25th percentile feerate"},
1873  {RPCResult::Type::NUM, "50th_percentile_feerate", "The 50th percentile feerate"},
1874  {RPCResult::Type::NUM, "75th_percentile_feerate", "The 75th percentile feerate"},
1875  {RPCResult::Type::NUM, "90th_percentile_feerate", "The 90th percentile feerate"},
1876  }},
1877  {RPCResult::Type::NUM, "height", "The height of the block"},
1878  {RPCResult::Type::NUM, "ins", "The number of inputs (excluding coinbase)"},
1879  {RPCResult::Type::NUM, "maxfee", "Maximum fee in the block"},
1880  {RPCResult::Type::NUM, "maxfeerate", "Maximum feerate (in satoshis per virtual byte)"},
1881  {RPCResult::Type::NUM, "maxtxsize", "Maximum transaction size"},
1882  {RPCResult::Type::NUM, "medianfee", "Truncated median fee in the block"},
1883  {RPCResult::Type::NUM, "mediantime", "The block median time past"},
1884  {RPCResult::Type::NUM, "mediantxsize", "Truncated median transaction size"},
1885  {RPCResult::Type::NUM, "minfee", "Minimum fee in the block"},
1886  {RPCResult::Type::NUM, "minfeerate", "Minimum feerate (in satoshis per virtual byte)"},
1887  {RPCResult::Type::NUM, "mintxsize", "Minimum transaction size"},
1888  {RPCResult::Type::NUM, "outs", "The number of outputs"},
1889  {RPCResult::Type::NUM, "subsidy", "The block subsidy"},
1890  {RPCResult::Type::NUM, "swtotal_size", "Total size of all segwit transactions"},
1891  {RPCResult::Type::NUM, "swtotal_weight", "Total weight of all segwit transactions"},
1892  {RPCResult::Type::NUM, "swtxs", "The number of segwit transactions"},
1893  {RPCResult::Type::NUM, "time", "The block time"},
1894  {RPCResult::Type::NUM, "total_out", "Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])"},
1895  {RPCResult::Type::NUM, "total_size", "Total size of all non-coinbase transactions"},
1896  {RPCResult::Type::NUM, "total_weight", "Total weight of all non-coinbase transactions"},
1897  {RPCResult::Type::NUM, "totalfee", "The fee total"},
1898  {RPCResult::Type::NUM, "txs", "The number of transactions (including coinbase)"},
1899  {RPCResult::Type::NUM, "utxo_increase", "The increase/decrease in the number of unspent outputs"},
1900  {RPCResult::Type::NUM, "utxo_size_inc", "The increase/decrease in size for the utxo index (not discounting op_return and similar)"},
1901  }},
1902  RPCExamples{
1903  HelpExampleCli("getblockstats", R"('"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"' '["minfeerate","avgfeerate"]')") +
1904  HelpExampleCli("getblockstats", R"(1000 '["minfeerate","avgfeerate"]')") +
1905  HelpExampleRpc("getblockstats", R"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") +
1906  HelpExampleRpc("getblockstats", R"(1000, ["minfeerate","avgfeerate"])")
1907  },
1908  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1909 {
1910  ChainstateManager& chainman = EnsureAnyChainman(request.context);
1911  LOCK(cs_main);
1912  CChain& active_chain = chainman.ActiveChain();
1913 
1914  CBlockIndex* pindex;
1915  if (request.params[0].isNum()) {
1916  const int height = request.params[0].get_int();
1917  const int current_tip = active_chain.Height();
1918  if (height < 0) {
1919  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d is negative", height));
1920  }
1921  if (height > current_tip) {
1922  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d after current tip %d", height, current_tip));
1923  }
1924 
1925  pindex = active_chain[height];
1926  } else {
1927  const uint256 hash(ParseHashV(request.params[0], "hash_or_height"));
1928  pindex = chainman.m_blockman.LookupBlockIndex(hash);
1929  if (!pindex) {
1930  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1931  }
1932  if (!active_chain.Contains(pindex)) {
1933  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Block is not in chain %s", Params().NetworkIDString()));
1934  }
1935  }
1936 
1937  CHECK_NONFATAL(pindex != nullptr);
1938 
1939  std::set<std::string> stats;
1940  if (!request.params[1].isNull()) {
1941  const UniValue stats_univalue = request.params[1].get_array();
1942  for (unsigned int i = 0; i < stats_univalue.size(); i++) {
1943  const std::string stat = stats_univalue[i].get_str();
1944  stats.insert(stat);
1945  }
1946  }
1947 
1948  const CBlock block = GetBlockChecked(pindex);
1949  const CBlockUndo blockUndo = GetUndoChecked(pindex);
1950 
1951  const bool do_all = stats.size() == 0; // Calculate everything if nothing selected (default)
1952  const bool do_mediantxsize = do_all || stats.count("mediantxsize") != 0;
1953  const bool do_medianfee = do_all || stats.count("medianfee") != 0;
1954  const bool do_feerate_percentiles = do_all || stats.count("feerate_percentiles") != 0;
1955  const bool loop_inputs = do_all || do_medianfee || do_feerate_percentiles ||
1956  SetHasKeys(stats, "utxo_size_inc", "totalfee", "avgfee", "avgfeerate", "minfee", "maxfee", "minfeerate", "maxfeerate");
1957  const bool loop_outputs = do_all || loop_inputs || stats.count("total_out");
1958  const bool do_calculate_size = do_mediantxsize ||
1959  SetHasKeys(stats, "total_size", "avgtxsize", "mintxsize", "maxtxsize", "swtotal_size");
1960  const bool do_calculate_weight = do_all || SetHasKeys(stats, "total_weight", "avgfeerate", "swtotal_weight", "avgfeerate", "feerate_percentiles", "minfeerate", "maxfeerate");
1961  const bool do_calculate_sw = do_all || SetHasKeys(stats, "swtxs", "swtotal_size", "swtotal_weight");
1962 
1963  CAmount maxfee = 0;
1964  CAmount maxfeerate = 0;
1965  CAmount minfee = MAX_MONEY;
1966  CAmount minfeerate = MAX_MONEY;
1967  CAmount total_out = 0;
1968  CAmount totalfee = 0;
1969  int64_t inputs = 0;
1970  int64_t maxtxsize = 0;
1971  int64_t mintxsize = MAX_BLOCK_SERIALIZED_SIZE;
1972  int64_t outputs = 0;
1973  int64_t swtotal_size = 0;
1974  int64_t swtotal_weight = 0;
1975  int64_t swtxs = 0;
1976  int64_t total_size = 0;
1977  int64_t total_weight = 0;
1978  int64_t utxo_size_inc = 0;
1979  std::vector<CAmount> fee_array;
1980  std::vector<std::pair<CAmount, int64_t>> feerate_array;
1981  std::vector<int64_t> txsize_array;
1982 
1983  for (size_t i = 0; i < block.vtx.size(); ++i) {
1984  const auto& tx = block.vtx.at(i);
1985  outputs += tx->vout.size();
1986 
1987  CAmount tx_total_out = 0;
1988  if (loop_outputs) {
1989  for (const CTxOut& out : tx->vout) {
1990  tx_total_out += out.nValue;
1991  utxo_size_inc += GetSerializeSize(out, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD;
1992  }
1993  }
1994 
1995  if (tx->IsCoinBase()) {
1996  continue;
1997  }
1998 
1999  inputs += tx->vin.size(); // Don't count coinbase's fake input
2000  total_out += tx_total_out; // Don't count coinbase reward
2001 
2002  int64_t tx_size = 0;
2003  if (do_calculate_size) {
2004 
2005  tx_size = tx->GetTotalSize();
2006  if (do_mediantxsize) {
2007  txsize_array.push_back(tx_size);
2008  }
2009  maxtxsize = std::max(maxtxsize, tx_size);
2010  mintxsize = std::min(mintxsize, tx_size);
2011  total_size += tx_size;
2012  }
2013 
2014  int64_t weight = 0;
2015  if (do_calculate_weight) {
2016  weight = GetTransactionWeight(*tx);
2017  total_weight += weight;
2018  }
2019 
2020  if (do_calculate_sw && tx->HasWitness()) {
2021  ++swtxs;
2022  swtotal_size += tx_size;
2023  swtotal_weight += weight;
2024  }
2025 
2026  if (loop_inputs) {
2027  CAmount tx_total_in = 0;
2028  const auto& txundo = blockUndo.vtxundo.at(i - 1);
2029  for (const Coin& coin: txundo.vprevout) {
2030  const CTxOut& prevoutput = coin.out;
2031 
2032  tx_total_in += prevoutput.nValue;
2033  utxo_size_inc -= GetSerializeSize(prevoutput, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD;
2034  }
2035 
2036  CAmount txfee = tx_total_in - tx_total_out;
2037  CHECK_NONFATAL(MoneyRange(txfee));
2038  if (do_medianfee) {
2039  fee_array.push_back(txfee);
2040  }
2041  maxfee = std::max(maxfee, txfee);
2042  minfee = std::min(minfee, txfee);
2043  totalfee += txfee;
2044 
2045  // New feerate uses satoshis per virtual byte instead of per serialized byte
2046  CAmount feerate = weight ? (txfee * WITNESS_SCALE_FACTOR) / weight : 0;
2047  if (do_feerate_percentiles) {
2048  feerate_array.emplace_back(std::make_pair(feerate, weight));
2049  }
2050  maxfeerate = std::max(maxfeerate, feerate);
2051  minfeerate = std::min(minfeerate, feerate);
2052  }
2053  }
2054 
2055  CAmount feerate_percentiles[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 };
2056  CalculatePercentilesByWeight(feerate_percentiles, feerate_array, total_weight);
2057 
2058  UniValue feerates_res(UniValue::VARR);
2059  for (int64_t i = 0; i < NUM_GETBLOCKSTATS_PERCENTILES; i++) {
2060  feerates_res.push_back(feerate_percentiles[i]);
2061  }
2062 
2063  UniValue ret_all(UniValue::VOBJ);
2064  ret_all.pushKV("avgfee", (block.vtx.size() > 1) ? totalfee / (block.vtx.size() - 1) : 0);
2065  ret_all.pushKV("avgfeerate", total_weight ? (totalfee * WITNESS_SCALE_FACTOR) / total_weight : 0); // Unit: sat/vbyte
2066  ret_all.pushKV("avgtxsize", (block.vtx.size() > 1) ? total_size / (block.vtx.size() - 1) : 0);
2067  ret_all.pushKV("blockhash", pindex->GetBlockHash().GetHex());
2068  ret_all.pushKV("feerate_percentiles", feerates_res);
2069  ret_all.pushKV("height", (int64_t)pindex->nHeight);
2070  ret_all.pushKV("ins", inputs);
2071  ret_all.pushKV("maxfee", maxfee);
2072  ret_all.pushKV("maxfeerate", maxfeerate);
2073  ret_all.pushKV("maxtxsize", maxtxsize);
2074  ret_all.pushKV("medianfee", CalculateTruncatedMedian(fee_array));
2075  ret_all.pushKV("mediantime", pindex->GetMedianTimePast());
2076  ret_all.pushKV("mediantxsize", CalculateTruncatedMedian(txsize_array));
2077  ret_all.pushKV("minfee", (minfee == MAX_MONEY) ? 0 : minfee);
2078  ret_all.pushKV("minfeerate", (minfeerate == MAX_MONEY) ? 0 : minfeerate);
2079  ret_all.pushKV("mintxsize", mintxsize == MAX_BLOCK_SERIALIZED_SIZE ? 0 : mintxsize);
2080  ret_all.pushKV("outs", outputs);
2081  ret_all.pushKV("subsidy", GetBlockSubsidy(pindex->nHeight, Params().GetConsensus()));
2082  ret_all.pushKV("swtotal_size", swtotal_size);
2083  ret_all.pushKV("swtotal_weight", swtotal_weight);
2084  ret_all.pushKV("swtxs", swtxs);
2085  ret_all.pushKV("time", pindex->GetBlockTime());
2086  ret_all.pushKV("total_out", total_out);
2087  ret_all.pushKV("total_size", total_size);
2088  ret_all.pushKV("total_weight", total_weight);
2089  ret_all.pushKV("totalfee", totalfee);
2090  ret_all.pushKV("txs", (int64_t)block.vtx.size());
2091  ret_all.pushKV("utxo_increase", outputs - inputs);
2092  ret_all.pushKV("utxo_size_inc", utxo_size_inc);
2093 
2094  if (do_all) {
2095  return ret_all;
2096  }
2097 
2098  UniValue ret(UniValue::VOBJ);
2099  for (const std::string& stat : stats) {
2100  const UniValue& value = ret_all[stat];
2101  if (value.isNull()) {
2102  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid selected statistic %s", stat));
2103  }
2104  ret.pushKV(stat, value);
2105  }
2106  return ret;
2107 },
2108  };
2109 }
2110 
2112 {
2113  return RPCHelpMan{"savemempool",
2114  "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n",
2115  {},
2117  RPCExamples{
2118  HelpExampleCli("savemempool", "")
2119  + HelpExampleRpc("savemempool", "")
2120  },
2121  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
2122 {
2123  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
2124 
2125  if (!mempool.IsLoaded()) {
2126  throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet");
2127  }
2128 
2129  if (!DumpMempool(mempool)) {
2130  throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
2131  }
2132 
2133  return NullUniValue;
2134 },
2135  };
2136 }
2137 
2138 namespace {
2140 bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>& should_abort, int64_t& count, CCoinsViewCursor* cursor, const std::set<CScript>& needles, std::map<COutPoint, Coin>& out_results, std::function<void()>& interruption_point)
2141 {
2142  scan_progress = 0;
2143  count = 0;
2144  while (cursor->Valid()) {
2145  COutPoint key;
2146  Coin coin;
2147  if (!cursor->GetKey(key) || !cursor->GetValue(coin)) return false;
2148  if (++count % 8192 == 0) {
2149  interruption_point();
2150  if (should_abort) {
2151  // allow to abort the scan via the abort reference
2152  return false;
2153  }
2154  }
2155  if (count % 256 == 0) {
2156  // update progress reference every 256 item
2157  uint32_t high = 0x100 * *key.hash.begin() + *(key.hash.begin() + 1);
2158  scan_progress = (int)(high * 100.0 / 65536.0 + 0.5);
2159  }
2160  if (needles.count(coin.out.scriptPubKey)) {
2161  out_results.emplace(key, coin);
2162  }
2163  cursor->Next();
2164  }
2165  scan_progress = 100;
2166  return true;
2167 }
2168 } // namespace
2169 
2171 static std::atomic<int> g_scan_progress;
2172 static std::atomic<bool> g_scan_in_progress;
2173 static std::atomic<bool> g_should_abort_scan;
2175 {
2176 private:
2178 public:
2180 
2181  bool reserve() {
2183  if (g_scan_in_progress.exchange(true)) {
2184  return false;
2185  }
2186  m_could_reserve = true;
2187  return true;
2188  }
2189 
2191  if (m_could_reserve) {
2192  g_scan_in_progress = false;
2193  }
2194  }
2195 };
2196 
2198 {
2199  return RPCHelpMan{"scantxoutset",
2200  "\nScans the unspent transaction output set for entries that match certain output descriptors.\n"
2201  "Examples of output descriptors are:\n"
2202  " addr(<address>) Outputs whose scriptPubKey corresponds to the specified address (does not include P2PK)\n"
2203  " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n"
2204  " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n"
2205  " pkh(<pubkey>) P2PKH outputs for the given pubkey\n"
2206  " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"
2207  "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
2208  "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
2209  "unhardened or hardened child keys.\n"
2210  "In the latter case, a range needs to be specified by below if different from 1000.\n"
2211  "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n",
2212  {
2213  {"action", RPCArg::Type::STR, RPCArg::Optional::NO, "The action to execute\n"
2214  "\"start\" for starting a scan\n"
2215  "\"abort\" for aborting the current scan (returns true when abort was successful)\n"
2216  "\"status\" for progress report (in %) of the current scan"},
2217  {"scanobjects", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Array of scan objects. Required for \"start\" action\n"
2218  "Every scan object is either a string descriptor or an object:",
2219  {
2220  {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
2221  {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with output descriptor and metadata",
2222  {
2223  {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
2224  {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "The range of HD chain indexes to explore (either end or [begin,end])"},
2225  }},
2226  },
2227  "[scanobjects,...]"},
2228  },
2229  {
2230  RPCResult{"When action=='abort'", RPCResult::Type::BOOL, "", ""},
2231  RPCResult{"When action=='status' and no scan is in progress", RPCResult::Type::NONE, "", ""},
2232  RPCResult{"When action=='status' and scan is in progress", RPCResult::Type::OBJ, "", "",
2233  {
2234  {RPCResult::Type::NUM, "progress", "The scan progress"},
2235  }},
2236  RPCResult{"When action=='start'", RPCResult::Type::OBJ, "", "", {
2237  {RPCResult::Type::BOOL, "success", "Whether the scan was completed"},
2238  {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs scanned"},
2239  {RPCResult::Type::NUM, "height", "The current block height (index)"},
2240  {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
2241  {RPCResult::Type::ARR, "unspents", "",
2242  {
2243  {RPCResult::Type::OBJ, "", "",
2244  {
2245  {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
2246  {RPCResult::Type::NUM, "vout", "The vout value"},
2247  {RPCResult::Type::STR_HEX, "scriptPubKey", "The script key"},
2248  {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched scriptPubKey"},
2249  {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"},
2250  {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"},
2251  }},
2252  }},
2253  {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT},
2254  }},
2255  },
2256  RPCExamples{""},
2257  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
2258 {
2259  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
2260 
2261  UniValue result(UniValue::VOBJ);
2262  if (request.params[0].get_str() == "status") {
2263  CoinsViewScanReserver reserver;
2264  if (reserver.reserve()) {
2265  // no scan in progress
2266  return NullUniValue;
2267  }
2268  result.pushKV("progress", g_scan_progress);
2269  return result;
2270  } else if (request.params[0].get_str() == "abort") {
2271  CoinsViewScanReserver reserver;
2272  if (reserver.reserve()) {
2273  // reserve was possible which means no scan was running
2274  return false;
2275  }
2276  // set the abort flag
2277  g_should_abort_scan = true;
2278  return true;
2279  } else if (request.params[0].get_str() == "start") {
2280  CoinsViewScanReserver reserver;
2281  if (!reserver.reserve()) {
2282  throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\"");
2283  }
2284 
2285  if (request.params.size() < 2) {
2286  throw JSONRPCError(RPC_MISC_ERROR, "scanobjects argument is required for the start action");
2287  }
2288 
2289  std::set<CScript> needles;
2290  std::map<CScript, std::string> descriptors;
2291  CAmount total_in = 0;
2292 
2293  // loop through the scan objects
2294  for (const UniValue& scanobject : request.params[1].get_array().getValues()) {
2295  FlatSigningProvider provider;
2296  auto scripts = EvalDescriptorStringOrObject(scanobject, provider);
2297  for (const auto& script : scripts) {
2298  std::string inferred = InferDescriptor(script, provider)->ToString();
2299  needles.emplace(script);
2300  descriptors.emplace(std::move(script), std::move(inferred));
2301  }
2302  }
2303 
2304  // Scan the unspent transaction output set for inputs
2305  UniValue unspents(UniValue::VARR);
2306  std::vector<CTxOut> input_txos;
2307  std::map<COutPoint, Coin> coins;
2308  g_should_abort_scan = false;
2309  g_scan_progress = 0;
2310  int64_t count = 0;
2311  std::unique_ptr<CCoinsViewCursor> pcursor;
2312  CBlockIndex* tip;
2313  NodeContext& node = EnsureAnyNodeContext(request.context);
2314  {
2315  ChainstateManager& chainman = EnsureChainman(node);
2316  LOCK(cs_main);
2317  CChainState& active_chainstate = chainman.ActiveChainstate();
2318  active_chainstate.ForceFlushStateToDisk();
2319  pcursor = std::unique_ptr<CCoinsViewCursor>(active_chainstate.CoinsDB().Cursor());
2320  CHECK_NONFATAL(pcursor);
2321  tip = active_chainstate.m_chain.Tip();
2322  CHECK_NONFATAL(tip);
2323  }
2324  bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins, node.rpc_interruption_point);
2325  result.pushKV("success", res);
2326  result.pushKV("txouts", count);
2327  result.pushKV("height", tip->nHeight);
2328  result.pushKV("bestblock", tip->GetBlockHash().GetHex());
2329 
2330  for (const auto& it : coins) {
2331  const COutPoint& outpoint = it.first;
2332  const Coin& coin = it.second;
2333  const CTxOut& txo = coin.out;
2334  input_txos.push_back(txo);
2335  total_in += txo.nValue;
2336 
2337  UniValue unspent(UniValue::VOBJ);
2338  unspent.pushKV("txid", outpoint.hash.GetHex());
2339  unspent.pushKV("vout", (int32_t)outpoint.n);
2340  unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey));
2341  unspent.pushKV("desc", descriptors[txo.scriptPubKey]);
2342  unspent.pushKV("amount", ValueFromAmount(txo.nValue));
2343  unspent.pushKV("height", (int32_t)coin.nHeight);
2344 
2345  unspents.push_back(unspent);
2346  }
2347  result.pushKV("unspents", unspents);
2348  result.pushKV("total_amount", ValueFromAmount(total_in));
2349  } else {
2350  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command");
2351  }
2352  return result;
2353 },
2354  };
2355 }
2356 
2358 {
2359  return RPCHelpMan{"getblockfilter",
2360  "\nRetrieve a BIP 157 content filter for a particular block.\n",
2361  {
2362  {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hash of the block"},
2363  {"filtertype", RPCArg::Type::STR, RPCArg::Default{"basic"}, "The type name of the filter"},
2364  },
2365  RPCResult{
2366  RPCResult::Type::OBJ, "", "",
2367  {
2368  {RPCResult::Type::STR_HEX, "filter", "the hex-encoded filter data"},
2369  {RPCResult::Type::STR_HEX, "header", "the hex-encoded filter header"},
2370  }},
2371  RPCExamples{
2372  HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") +
2373  HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"")
2374  },
2375  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
2376 {
2377  uint256 block_hash = ParseHashV(request.params[0], "blockhash");
2378  std::string filtertype_name = "basic";
2379  if (!request.params[1].isNull()) {
2380  filtertype_name = request.params[1].get_str();
2381  }
2382 
2383  BlockFilterType filtertype;
2384  if (!BlockFilterTypeByName(filtertype_name, filtertype)) {
2385  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown filtertype");
2386  }
2387 
2388  BlockFilterIndex* index = GetBlockFilterIndex(filtertype);
2389  if (!index) {
2390  throw JSONRPCError(RPC_MISC_ERROR, "Index is not enabled for filtertype " + filtertype_name);
2391  }
2392 
2393  const CBlockIndex* block_index;
2394  bool block_was_connected;
2395  {
2396  ChainstateManager& chainman = EnsureAnyChainman(request.context);
2397  LOCK(cs_main);
2398  block_index = chainman.m_blockman.LookupBlockIndex(block_hash);
2399  if (!block_index) {
2400  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
2401  }
2402  block_was_connected = block_index->IsValid(BLOCK_VALID_SCRIPTS);
2403  }
2404 
2405  bool index_ready = index->BlockUntilSyncedToCurrentChain();
2406 
2407  BlockFilter filter;
2408  uint256 filter_header;
2409  if (!index->LookupFilter(block_index, filter) ||
2410  !index->LookupFilterHeader(block_index, filter_header)) {
2411  int err_code;
2412  std::string errmsg = "Filter not found.";
2413 
2414  if (!block_was_connected) {
2415  err_code = RPC_INVALID_ADDRESS_OR_KEY;
2416  errmsg += " Block was not connected to active chain.";
2417  } else if (!index_ready) {
2418  err_code = RPC_MISC_ERROR;
2419  errmsg += " Block filters are still in the process of being indexed.";
2420  } else {
2421  err_code = RPC_INTERNAL_ERROR;
2422  errmsg += " This error is unexpected and indicates index corruption.";
2423  }
2424 
2425  throw JSONRPCError(err_code, errmsg);
2426  }
2427 
2428  UniValue ret(UniValue::VOBJ);
2429  ret.pushKV("filter", HexStr(filter.GetEncodedFilter()));
2430  ret.pushKV("header", filter_header.GetHex());
2431  return ret;
2432 },
2433  };
2434 }
2435 
2442 {
2443  return RPCHelpMan{
2444  "dumptxoutset",
2445  "\nWrite the serialized UTXO set to disk.\n",
2446  {
2447  {"path",
2450  /* default_val */ "",
2451  "path to the output file. If relative, will be prefixed by datadir."},
2452  },
2453  RPCResult{
2454  RPCResult::Type::OBJ, "", "",
2455  {
2456  {RPCResult::Type::NUM, "coins_written", "the number of coins written in the snapshot"},
2457  {RPCResult::Type::STR_HEX, "base_hash", "the hash of the base of the snapshot"},
2458  {RPCResult::Type::NUM, "base_height", "the height of the base of the snapshot"},
2459  {RPCResult::Type::STR, "path", "the absolute path that the snapshot was written to"},
2460  }
2461  },
2462  RPCExamples{
2463  HelpExampleCli("dumptxoutset", "utxo.dat")
2464  },
2465  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
2466 {
2467  const fs::path path = fsbridge::AbsPathJoin(GetDataDir(), request.params[0].get_str());
2468  // Write to a temporary path and then move into `path` on completion
2469  // to avoid confusion due to an interruption.
2470  const fs::path temppath = fsbridge::AbsPathJoin(GetDataDir(), request.params[0].get_str() + ".incomplete");
2471 
2472  if (fs::exists(path)) {
2473  throw JSONRPCError(
2475  path.string() + " already exists. If you are sure this is what you want, "
2476  "move it out of the way first");
2477  }
2478 
2479  FILE* file{fsbridge::fopen(temppath, "wb")};
2480  CAutoFile afile{file, SER_DISK, CLIENT_VERSION};
2481  NodeContext& node = EnsureAnyNodeContext(request.context);
2482  UniValue result = CreateUTXOSnapshot(node, node.chainman->ActiveChainstate(), afile);
2483  fs::rename(temppath, path);
2484 
2485  result.pushKV("path", path.string());
2486  return result;
2487 },
2488  };
2489 }
2490 
2492 {
2493  std::unique_ptr<CCoinsViewCursor> pcursor;
2494  CCoinsStats stats;
2495  CBlockIndex* tip;
2496 
2497  {
2498  // We need to lock cs_main to ensure that the coinsdb isn't written to
2499  // between (i) flushing coins cache to disk (coinsdb), (ii) getting stats
2500  // based upon the coinsdb, and (iii) constructing a cursor to the
2501  // coinsdb for use below this block.
2502  //
2503  // Cursors returned by leveldb iterate over snapshots, so the contents
2504  // of the pcursor will not be affected by simultaneous writes during
2505  // use below this block.
2506  //
2507  // See discussion here:
2508  // https://github.com/bitcoin/bitcoin/pull/15606#discussion_r274479369
2509  //
2510  LOCK(::cs_main);
2511 
2512  chainstate.ForceFlushStateToDisk();
2513 
2514  if (!GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) {
2515  throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
2516  }
2517 
2518  pcursor = std::unique_ptr<CCoinsViewCursor>(chainstate.CoinsDB().Cursor());
2519  tip = chainstate.m_blockman.LookupBlockIndex(stats.hashBlock);
2520  CHECK_NONFATAL(tip);
2521  }
2522 
2523  SnapshotMetadata metadata{tip->GetBlockHash(), stats.coins_count, tip->nChainTx};
2524 
2525  afile << metadata;
2526 
2527  COutPoint key;
2528  Coin coin;
2529  unsigned int iter{0};
2530 
2531  while (pcursor->Valid()) {
2532  if (iter % 5000 == 0) node.rpc_interruption_point();
2533  ++iter;
2534  if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
2535  afile << key;
2536  afile << coin;
2537  }
2538 
2539  pcursor->Next();
2540  }
2541 
2542  afile.fclose();
2543 
2544  UniValue result(UniValue::VOBJ);
2545  result.pushKV("coins_written", stats.coins_count);
2546  result.pushKV("base_hash", tip->GetBlockHash().ToString());
2547  result.pushKV("base_height", tip->nHeight);
2548 
2549  return result;
2550 }
2551 
2553 {
2554 // clang-format off
2555 static const CRPCCommand commands[] =
2556 { // category actor (function)
2557  // --------------------- ------------------------
2558  { "blockchain", &getblockchaininfo, },
2559  { "blockchain", &getchaintxstats, },
2560  { "blockchain", &getblockstats, },
2561  { "blockchain", &getbestblockhash, },
2562  { "blockchain", &getblockcount, },
2563  { "blockchain", &getblock, },
2564  { "blockchain", &getblockhash, },
2565  { "blockchain", &getblockheader, },
2566  { "blockchain", &getchaintips, },
2567  { "blockchain", &getdifficulty, },
2568  { "blockchain", &getmempoolancestors, },
2569  { "blockchain", &getmempooldescendants, },
2570  { "blockchain", &getmempoolentry, },
2571  { "blockchain", &getmempoolinfo, },
2572  { "blockchain", &getrawmempool, },
2573  { "blockchain", &gettxout, },
2574  { "blockchain", &gettxoutsetinfo, },
2575  { "blockchain", &pruneblockchain, },
2576  { "blockchain", &savemempool, },
2577  { "blockchain", &verifychain, },
2578 
2579  { "blockchain", &preciousblock, },
2580  { "blockchain", &scantxoutset, },
2581  { "blockchain", &getblockfilter, },
2582 
2583  /* Not shown in help */
2584  { "hidden", &invalidateblock, },
2585  { "hidden", &reconsiderblock, },
2586  { "hidden", &waitfornewblock, },
2587  { "hidden", &waitforblock, },
2588  { "hidden", &waitforblockheight, },
2589  { "hidden", &syncwithvalidationinterfacequeue, },
2590  { "hidden", &dumptxoutset, },
2591 };
2592 // clang-format on
2593  for (const auto& c : commands) {
2594  t.appendCommand(c.name, &c);
2595  }
2596 }
ThresholdState::STARTED
@ STARTED
CCoinsViewDB::Cursor
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: txdb.cpp:171
CBlockIndex::GetBlockTime
int64_t GetBlockTime() const
Definition: chain.h:260
GetSerializeSize
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1116
CTxIn
An input of a transaction.
Definition: transaction.h:65
RPC_MISC_ERROR
@ RPC_MISC_ERROR
General application defined errors.
Definition: protocol.h:39
CTxMemPool::setEntries
std::set< txiter, CompareIteratorByHash > setEntries
Definition: txmempool.h:571
policy.h
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:20
CalculateTruncatedMedian
static T CalculateTruncatedMedian(std::vector< T > &scores)
Definition: blockchain.cpp:1783
CTransaction::vin
const std::vector< CTxIn > vin
Definition: transaction.h:270
GetBlockSubsidy
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
Definition: validation.cpp:1152
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:1008
feerate.h
BLOCK_FAILED_MASK
@ BLOCK_FAILED_MASK
Definition: chain.h:127
ParseHashV
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:89
g_should_abort_scan
static std::atomic< bool > g_should_abort_scan
Definition: blockchain.cpp:2173
preciousblock
static RPCHelpMan preciousblock()
Definition: blockchain.cpp:1581
PER_UTXO_OVERHEAD
static constexpr size_t PER_UTXO_OVERHEAD
Definition: blockchain.cpp:1846
ChainstateManager::BlockIndex
BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
Definition: validation.h:912
getblockfilter
static RPCHelpMan getblockfilter()
Definition: blockchain.cpp:2357
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:805
DEFAULT_CHECKLEVEL
static const unsigned int DEFAULT_CHECKLEVEL
Definition: validation.h:92
ThresholdState::ACTIVE
@ ACTIVE
CBlockIndex::GetAncestor
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:111
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:21
count
static int count
Definition: tests.c:35
CTxMemPool::GetUnbroadcastTxs
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
Definition: txmempool.h:771
CalculateCurrentUsage
uint64_t CalculateCurrentUsage()
BLOCK PRUNING CODE.
Definition: validation.cpp:3741
CHECKLEVEL_DOC
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
Definition: validation.cpp:79
UniValue::get_bool
bool get_bool() const
Definition: univalue_get.cpp:90
CChainState::ForceFlushStateToDisk
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
Definition: validation.cpp:2275
CoinStatsHashType::HASH_SERIALIZED
@ HASH_SERIALIZED
SER_DISK
@ SER_DISK
Definition: serialize.h:167
verifychain
static RPCHelpMan verifychain()
Definition: blockchain.cpp:1218
CTxMemPoolEntry::Children
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Children
Definition: txmempool.h:87
CUpdatedBlock::height
int height
Definition: blockchain.cpp:52
RPC_INTERNAL_ERROR
@ RPC_INTERNAL_ERROR
Definition: protocol.h:35
CBlockIndex::nTime
uint32_t nTime
Definition: chain.h:192
CHECK_NONFATAL
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:32
RegisterBlockchainRPCCommands
void RegisterBlockchainRPCCommands(CRPCTable &t)
Register block chain RPC commands.
Definition: blockchain.cpp:2552
nHeight
unsigned int nHeight
Definition: mempool_eviction.cpp:14
BlockValidationState
Definition: validation.h:140
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:193
CTxUndo
Undo information for a CTransaction.
Definition: undo.h:53
streams.h
base_uint::GetHex
std::string GetHex() const
Definition: arith_uint256.cpp:147
CBlockIndex::nTx
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:169
nPruneTarget
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
Definition: validation.cpp:145
BLOCK_VALID_TREE
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
Definition: chain.h:101
GetWarnings
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:31
cond_blockchange
static std::condition_variable cond_blockchange
Definition: blockchain.cpp:56
RPCHelpMan
Definition: util.h:338
g_scan_progress
static std::atomic< int > g_scan_progress
RAII object to prevent concurrency issue when scanning the txout set.
Definition: blockchain.cpp:2171
sync.h
blockfilterindex.h
transaction.h
BlockFilter::GetEncodedFilter
const std::vector< unsigned char > & GetEncodedFilter() const
Definition: blockfilter.h:134
CTxMemPool::txiter
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:568
waitforblockheight
static RPCHelpMan waitforblockheight()
Definition: blockchain.cpp:339
CTxMemPool::IsLoaded
bool IsLoaded() const
Definition: txmempool.cpp:1115
COutPoint::hash
uint256 hash
Definition: transaction.h:29
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
CCoinsStats::nDiskSize
uint64_t nDiskSize
Definition: coinstats.h:32
RBFTransactionState
RBFTransactionState
The rbf state of unconfirmed transactions.
Definition: rbf.h:11
NUM_GETBLOCKSTATS_PERCENTILES
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES
Definition: blockchain.h:28
Consensus::DeploymentPos
DeploymentPos
Definition: params.h:14
getmempoolinfo
static RPCHelpMan getmempoolinfo()
Definition: blockchain.cpp:1552
CBlockIndex::nBits
uint32_t nBits
Definition: chain.h:193
CTxMemPool
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:477
RPC_INVALID_PARAMETER
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
CCoinsStats::nTransactions
uint64_t nTransactions
Definition: coinstats.h:28
getblockstats
static RPCHelpMan getblockstats()
Definition: blockchain.cpp:1848
CBlockIndex::pprev
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:144
CoinsViewScanReserver::m_could_reserve
bool m_could_reserve
Definition: blockchain.cpp:2177
MempoolInfoToJSON
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
Definition: blockchain.cpp:1534
BlockFilterTypeByName
bool BlockFilterTypeByName(const std::string &name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
Definition: blockfilter.cpp:185
ComputeNextBlockAndDepth
static int ComputeNextBlockAndDepth(const CBlockIndex *tip, const CBlockIndex *blockindex, const CBlockIndex *&next)
Definition: blockchain.cpp:132
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:150
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:24
RPC_CLIENT_MEMPOOL_DISABLED
@ RPC_CLIENT_MEMPOOL_DISABLED
Chain errors.
Definition: protocol.h:68
RPCArg::Type::ARR
@ ARR
CUpdatedBlock::hash
uint256 hash
Definition: blockchain.cpp:51
CompareBlocksByHeight
Comparison function for sorting the getchaintips heads.
Definition: blockchain.cpp:1422
CCoinsStats
Definition: coinstats.h:24
CoinsViewScanReserver
Definition: blockchain.cpp:2174
Consensus::DEPLOYMENT_TESTDUMMY
@ DEPLOYMENT_TESTDUMMY
Definition: params.h:16
minRelayTxFee
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
Definition: validation.cpp:151
getchaintxstats
static RPCHelpMan getchaintxstats()
Definition: blockchain.cpp:1702
CBlockIndex::nChainWork
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: chain.h:162
MoneyRange
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:26
WITH_LOCK
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:276
ScriptPubKeyToUniv
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: blockchain.cpp:1827
CChainParams::GetConsensus
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:77
fsbridge::AbsPathJoin
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:34
AnnotatedMixin< std::mutex >
RPCResult::Type::NUM
@ NUM
EnsureAnyChainman
ChainstateManager & EnsureAnyChainman(const std::any &context)
Definition: blockchain.cpp:90
CBlockIndex::nChainTx
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
Definition: chain.h:179
UniValue::isNull
bool isNull() const
Definition: univalue.h:77
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:153
versionbitscache
VersionBitsCache versionbitscache
pruneblockchain
static RPCHelpMan pruneblockchain()
Definition: blockchain.cpp:994
Coin::fCoinBase
unsigned int fCoinBase
whether containing transaction was a coinbase
Definition: coins.h:39
MIN_BLOCKS_TO_KEEP
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ChainActive().Tip() will not be pr...
Definition: validation.h:90
BlockManager
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
Definition: validation.h:364
chainparams.h
ChainstateManager::ActiveChainstate
CChainState & ActiveChainstate() const
The most-work chain.
Definition: validation.cpp:5357
CTransactionRef
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
EnsureAnyNodeContext
NodeContext & EnsureAnyNodeContext(const std::any &context)
Definition: blockchain.cpp:59
syncwithvalidationinterfacequeue
static RPCHelpMan syncwithvalidationinterfacequeue()
Definition: blockchain.cpp:385
CChain::Tip
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:403
cs_main
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: validation.cpp:131
context.h
CoinStatsHashType::NONE
@ NONE
CBlockUndo::vtxundo
std::vector< CTxUndo > vtxundo
Definition: undo.h:66
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:141
ValueFromAmount
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:20
IsRPCRunning
bool IsRPCRunning()
Query whether RPC is running.
Definition: server.cpp:321
getblockhash
static RPCHelpMan getblockhash()
Definition: blockchain.cpp:767
getblock
static RPCHelpMan getblock()
Definition: blockchain.cpp:897
CTxMemPool::queryHashes
void queryHashes(std::vector< uint256 > &vtxid) const
Definition: txmempool.cpp:791
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:51
UniValue
Definition: univalue.h:19
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:259
MAX_BLOCK_SERIALIZED_SIZE
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
Definition: consensus.h:13
GUARDED_BY
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange)
EnsureFeeEstimator
CBlockPolicyEstimator & EnsureFeeEstimator(const NodeContext &node)
Definition: blockchain.cpp:95
ValidationState::ToString
std::string ToString() const
Definition: validation.h:125
ChainstateManager::ActiveChain
CChain & ActiveChain() const
Definition: validation.h:908
txmempool.h
Consensus::Params::nPowTargetSpacing
int64_t nPowTargetSpacing
Definition: params.h:89
CChainParams::PruneAfterHeight
uint64_t PruneAfterHeight() const
Definition: chainparams.h:90
CCoinsView
Abstract view on the open txout dataset.
Definition: coins.h:159
RPCResult::Type::ARR_FIXED
@ ARR_FIXED
Special array that has a fixed number of entries.
CoinsViewScanReserver::reserve
bool reserve()
Definition: blockchain.cpp:2181
RPCArg::Type::NUM
@ NUM
ValidationState::IsValid
bool IsValid() const
Definition: validation.h:119
Coin::out
CTxOut out
unspent transaction output
Definition: coins.h:36
CTxOut::nValue
CAmount nValue
Definition: transaction.h:131
getmempoolentry
static RPCHelpMan getmempoolentry()
Definition: blockchain.cpp:734
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:564
BCLog::RPC
@ RPC
Definition: logging.h:45
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:97
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:62
CCoinsViewCursor
Cursor for iterating over CoinsView state.
Definition: coins.h:139
CBlockIndex::GetBlockHeader
CBlockHeader GetBlockHeader() const
Definition: chain.h:233
strencodings.h
Consensus::Params
Parameters that influence chain consensus.
Definition: params.h:56
SyncWithValidationInterfaceQueue
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
Definition: validationinterface.cpp:160
CCoinsViewCache::GetCoin
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:57
blockheaderToJSON
UniValue blockheaderToJSON(const CBlockIndex *tip, const CBlockIndex *blockindex)
Block header to JSON.
Definition: blockchain.cpp:142
EnsureAnyMemPool
CTxMemPool & EnsureAnyMemPool(const std::any &context)
Definition: blockchain.cpp:76
Consensus::Params::SegwitHeight
int SegwitHeight
Block height at which Segwit (BIP141, BIP143 and BIP147) becomes active.
Definition: params.h:73
CURRENCY_UNIT
const std::string CURRENCY_UNIT
Definition: feerate.h:14
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:565
CCoinsViewCursor::GetValue
virtual bool GetValue(Coin &coin) const =0
blockfilter.h
AssertLockNotHeld
#define AssertLockNotHeld(cs)
Definition: sync.h:82
RPCArg::DefaultHint
std::string DefaultHint
Definition: util.h:148
CBlockIndex::nStatus
uint32_t nStatus
Verification status of this block.
Definition: chain.h:187
CTxOut
An output of a transaction.
Definition: transaction.h:128
RPCArg::Type::STR_HEX
@ STR_HEX
Special type that is a STR with only hex chars.
RPCResult::Type::OBJ
@ OBJ
CRPCCommand
Definition: server.h:90
Coin
A UTXO entry.
Definition: coins.h:32
RPCResult::Type::NONE
@ NONE
CCoinsStats::hashBlock
uint256 hashBlock
Definition: coinstats.h:27
GetDifficulty
double GetDifficulty(const CBlockIndex *blockindex)
Get the difficulty of the net wrt to the given block index.
Definition: blockchain.cpp:110
CBlockIndex::GetMedianTimePast
int64_t GetMedianTimePast() const
Definition: chain.h:272
Coin::nHeight
uint32_t nHeight
at which height this containing transaction was included in the active block chain
Definition: coins.h:42
getdifficulty
static RPCHelpMan getdifficulty()
Definition: blockchain.cpp:403
BLOCK_VALID_SCRIPTS
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Definition: chain.h:115
CTxOut::scriptPubKey
CScript scriptPubKey
Definition: transaction.h:132
CTxMemPool::GetTotalFee
CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:730
CBlockIndex::nVersion
int32_t nVersion
block header
Definition: chain.h:190
UndoReadFromDisk
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
Definition: validation.cpp:1492
undo.h
ThresholdState::DEFINED
@ DEFINED
CBlockIndex::hashMerkleRoot
uint256 hashMerkleRoot
Definition: chain.h:191
BIP9Stats::count
int count
Number of blocks with the version bit set since the beginning of the current period.
Definition: versionbits.h:47
CBlockIndex::IsValid
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
Definition: chain.h:295
getchaintips
static RPCHelpMan getchaintips()
Definition: blockchain.cpp:1436
gettxout
static RPCHelpMan gettxout()
Definition: blockchain.cpp:1133
BIP9SoftForkDescPushBack
static void BIP9SoftForkDescPushBack(const CBlockIndex *active_chain_tip, UniValue &softforks, const std::string &name, const Consensus::Params &consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: blockchain.cpp:1265
univalue.h
RPC_DATABASE_ERROR
@ RPC_DATABASE_ERROR
Database error.
Definition: protocol.h:44
CalculatePercentilesByWeight
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector< std::pair< CAmount, int64_t >> &scores, int64_t total_weight)
Used by getblockstats to get feerates at different percentiles by weight
Definition: blockchain.cpp:1798
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:133
CBlockPolicyEstimator
Definition: fees.h:131
Consensus::DEPLOYMENT_TAPROOT
@ DEPLOYMENT_TAPROOT
Definition: params.h:17
g_chainman
ChainstateManager g_chainman
Definition: validation.cpp:106
entryToJSON
static void entryToJSON(const CTxMemPool &pool, UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
Definition: blockchain.cpp:452
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:582
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
base_blob::GetHex
std::string GetHex() const
Definition: uint256.cpp:20
CTxMemPool::GetSequence
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:789
RPCExamples
Definition: util.h:328
SERIALIZE_TRANSACTION_NO_WITNESS
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
Definition: transaction.h:23
Consensus::BIP9Deployment::NEVER_ACTIVE
static constexpr int64_t NEVER_ACTIVE
Special value for nStartTime indicating that the deployment is never active.
Definition: params.h:50
ReadBlockFromDisk
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
Definition: blockstorage.cpp:44
UniValue::__pushKV
void __pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:127
BIP9Stats::threshold
int threshold
Number of blocks with the version bit set required to activate the softfork.
Definition: versionbits.h:43
CoinsViewScanReserver::~CoinsViewScanReserver
~CoinsViewScanReserver()
Definition: blockchain.cpp:2190
AssertLockHeld
#define AssertLockHeld(cs)
Definition: sync.h:81
RPCResult::Type::STR
@ STR
CoinStatsHashType::MUHASH
@ MUHASH
utxo_snapshot.h
CChainState::ActivateBestChain
bool ActivateBestChain(BlockValidationState &state, const CChainParams &chainparams, 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:2720
getbestblockhash
static RPCHelpMan getbestblockhash()
Definition: blockchain.cpp:221
base_blob::ToString
std::string ToString() const
Definition: uint256.cpp:64
uint256
256-bit opaque blob.
Definition: uint256.h:124
CCoinsViewCursor::Valid
virtual bool Valid() const =0
RPCResult::Type::NUM_TIME
@ NUM_TIME
Special numeric to denote unix epoch time.
RPCResult::Type::ARR
@ ARR
CChainState
CChainState stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:530
CChainState::CoinsDB
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:620
LogPrint
#define LogPrint(category,...)
Definition: logging.h:187
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
EnsureMemPool
CTxMemPool & EnsureMemPool(const NodeContext &node)
Definition: blockchain.cpp:68
GetBlockChecked
static CBlock GetBlockChecked(const CBlockIndex *pblockindex)
Definition: blockchain.cpp:866
TxToUniv
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex, int serialize_flags, const CTxUndo *txundo)
Definition: blockchain.cpp:1832
GetBlockWeight
static int64_t GetBlockWeight(const CBlock &block)
Definition: validation.h:150
GetUndoChecked
static CBlockUndo GetUndoChecked(const CBlockIndex *pblockindex)
Definition: blockchain.cpp:883
CAutoFile::fclose
void fclose()
Definition: streams.h:587
RPCArg::Type::RANGE
@ RANGE
Special type that is a NUM or [NUM,NUM].
CCoinsViewMemPool::GetCoin
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txmempool.cpp:921
CCoinsStats::coins_count
uint64_t coins_count
The number of coins contained.
Definition: coinstats.h:36
cs_blockchange
static Mutex cs_blockchange
Definition: blockchain.cpp:55
CBlockIndex::GetBlockHash
uint256 GetBlockHash() const
Definition: chain.h:246
coins.h
ThresholdState::FAILED
@ FAILED
CChain::Height
int Height() const
Return the maximal height in the chain.
Definition: chain.h:428
gettxoutsetinfo
static RPCHelpMan gettxoutsetinfo()
Definition: blockchain.cpp:1067
getrawmempool
static RPCHelpMan getrawmempool()
Definition: blockchain.cpp:555
ChainstateManager
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:807
CRPCTable
RPC command dispatcher.
Definition: server.h:126
CVerifyDB
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
Definition: validation.h:328
PruneBlockFilesManual
void PruneBlockFilesManual(CChainState &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
Definition: validation.cpp:3821
RPC_INVALID_ADDRESS_OR_KEY
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:41
name
const char * name
Definition: rest.cpp:43
getblockheader
static RPCHelpMan getblockheader()
Definition: blockchain.cpp:796
coinstats.h
dumptxoutset
static RPCHelpMan dumptxoutset()
Serialize the UTXO set to a file for loading elsewhere.
Definition: blockchain.cpp:2441
BIP9Stats
Display status of an in-progress BIP9 softfork.
Definition: versionbits.h:39
system.h
CBlock
Definition: block.h:62
BlockManager::LookupBlockIndex
CBlockIndex * LookupBlockIndex(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.cpp:173
CChainState::IsInitialBlockDownload
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network)
Definition: validation.cpp:1209
Consensus::Params::BIP34Height
int BIP34Height
Block height and hash at which BIP34 becomes active.
Definition: params.h:62
reconsiderblock
static RPCHelpMan reconsiderblock()
Definition: blockchain.cpp:1662
getmempooldescendants
static RPCHelpMan getmempooldescendants()
Definition: blockchain.cpp:669
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
HelpExampleRpc
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:173
BIP9Stats::elapsed
int elapsed
Number of blocks elapsed since the beginning of the current period.
Definition: versionbits.h:45
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:514
CCoinsStats::nHeight
int nHeight
Definition: coinstats.h:26
Consensus::Params::BIP66Height
int BIP66Height
Block height at which BIP66 becomes active.
Definition: params.h:67
CRPCTable::appendCommand
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:270
g_scan_in_progress
static std::atomic< bool > g_scan_in_progress
Definition: blockchain.cpp:2172
RPCNotifyBlockChange
void RPCNotifyBlockChange(const CBlockIndex *pindex)
Callback for when block tip changed.
Definition: blockchain.cpp:241
CChain
An in-memory indexed chain of blocks.
Definition: chain.h:392
GetTransactionWeight
static int64_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:146
CBlock::vtx
std::vector< CTransactionRef > vtx
Definition: block.h:66
RPCResult::Type::BOOL
@ BOOL
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:104
fees.h
CCoinsViewCache
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:215
CCoinsStats::nTransactionOutputs
uint64_t nTransactionOutputs
Definition: coinstats.h:29
CCoinsViewCache::GetBestBlock
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:156
CompareBlocksByHeight::operator()
bool operator()(const CBlockIndex *a, const CBlockIndex *b) const
Definition: blockchain.cpp:1424
translation.h
ParseHashType
CoinStatsHashType ParseHashType(const std::string &hash_type_input)
Definition: blockchain.cpp:1054
GetBlockFilterIndex
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
Definition: blockfilterindex.cpp:452
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
COutPoint::n
uint32_t n
Definition: transaction.h:30
JSONRPCError
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:51
CTxMemPoolEntry
Definition: txmempool.h:81
LOCK
#define LOCK(cs)
Definition: sync.h:232
gArgs
ArgsManager gArgs
Definition: system.cpp:79
blockstorage.h
EnsureAnyFeeEstimator
CBlockPolicyEstimator & EnsureAnyFeeEstimator(const std::any &context)
Definition: blockchain.cpp:103
RPCArg::Type::BOOL
@ BOOL
RPCSerializationFlags
int RPCSerializationFlags()
Definition: server.cpp:540
RPCArg::Optional::OMITTED
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
CLIENT_VERSION
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:68
CCoinsStats::nBogoSize
uint64_t nBogoSize
Definition: coinstats.h:30
MAX_MONEY
static const CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:25
CBlockIndex::nNonce
uint32_t nNonce
Definition: chain.h:194
CCoinsStats::nTotalAmount
CAmount nTotalAmount
Definition: coinstats.h:33
CCoinsViewMemPool
CCoinsView that brings transactions from a mempool into view.
Definition: txmempool.h:863
CTxMemPool::size
unsigned long size() const
Definition: txmempool.h:718
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:568
BlockFilterIndex::LookupFilter
bool LookupFilter(const CBlockIndex *block_index, BlockFilter &filter_out) const
Get a single filter by block.
Definition: blockfilterindex.cpp:375
EnsureChainman
ChainstateManager & EnsureChainman(const NodeContext &node)
Definition: blockchain.cpp:81
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:538
CUpdatedBlock
Definition: blockchain.cpp:49
CCoinsViewCursor::GetKey
virtual bool GetKey(COutPoint &key) const =0
DumpMempool
bool DumpMempool(const CTxMemPool &pool, FopenFn mockable_fopen_function, bool skip_file_commit)
Dump the mempool to disk.
Definition: validation.cpp:4956
invalidateblock
static RPCHelpMan invalidateblock()
Definition: blockchain.cpp:1621
count_seconds
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
Definition: time.h:29
CChain::Contains
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:415
Consensus::Params::BIP65Height
int BIP65Height
Block height at which BIP65 becomes active.
Definition: params.h:65
scantxoutset
static RPCHelpMan scantxoutset()
Definition: blockchain.cpp:2197
node
Definition: interfaces.cpp:66
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue_get.cpp:83
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:204
BlockFilterType
BlockFilterType
Definition: blockfilter.h:88
CCoinsStats::hashSerialized
uint256 hashSerialized
Definition: coinstats.h:31
BuriedForkDescPushBack
static void BuriedForkDescPushBack(UniValue &softforks, const std::string &name, int softfork_height, int tip_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: blockchain.cpp:1247
RBFTransactionState::UNKNOWN
@ UNKNOWN
Unconfirmed tx that does not signal rbf and is not in the mempool.
ThresholdState::LOCKED_IN
@ LOCKED_IN
MEMPOOL_HEIGHT
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0....
Definition: txmempool.h:37
BIP9Stats::possible
bool possible
False if there are not enough blocks left in this period to pass activation threshold.
Definition: versionbits.h:49
CChainState::ResetBlockFailureFlags
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove invalidity status from a block and its descendants.
Definition: validation.cpp:2988
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:166
CoinsViewScanReserver::CoinsViewScanReserver
CoinsViewScanReserver()
Definition: blockchain.cpp:2179
RPCResult::Type::OBJ_DYN
@ OBJ_DYN
Special dictionary with keys that are not literals.
UniValue::size
size_t size() const
Definition: univalue.h:68
CTxMemPool::DynamicMemoryUsage
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:937
JSONRPCRequest
Definition: request.h:28
CChainState::InvalidateBlock
bool InvalidateBlock(BlockValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as invalid.
Definition: validation.cpp:2847
CTransaction::GetHash
const uint256 & GetHash() const
Definition: transaction.h:302
util.h
RPCResult
Definition: util.h:224
COutPoint
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
blockchain.h
Consensus::Params::CSVHeight
int CSVHeight
Block height at which CSV (BIP68, BIP112 and BIP113) becomes active.
Definition: params.h:69
IsDeprecatedRPCEnabled
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:352
IsRBFOptIn
RBFTransactionState IsRBFOptIn(const CTransaction &tx, const CTxMemPool &pool)
Determine whether an unconfirmed transaction is signaling opt-in to RBF according to BIP 125 This inv...
Definition: rbf.cpp:8
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:203
getmempoolancestors
static RPCHelpMan getmempoolancestors()
Definition: blockchain.cpp:605
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:198
CVerifyDB::VerifyDB
bool VerifyDB(const CChainParams &chainparams, CChainState &active_chainstate, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.cpp:4104
RPCResult::Type::STR_AMOUNT
@ STR_AMOUNT
Special string to represent a floating point amount.
BLOCK_HAVE_DATA
@ BLOCK_HAVE_DATA
full block available in blk*.dat
Definition: chain.h:121
UniValue::get_array
const UniValue & get_array() const
Definition: univalue_get.cpp:141
UniValue::VARR
@ VARR
Definition: univalue.h:21
NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:38
CTxMemPool::GetTotalTxSize
uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:724
BIP9Stats::period
int period
Length of blocks of the BIP9 signalling period.
Definition: versionbits.h:41
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:1216
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:981
ThresholdState
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
Definition: versionbits.h:25
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:23
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:137
savemempool
static RPCHelpMan savemempool()
Definition: blockchain.cpp:2111
CFeeRate::GetFeePerK
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:59
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:594
CoinStatsHashType
CoinStatsHashType
Definition: coinstats.h:18
getblockchaininfo
RPCHelpMan getblockchaininfo()
Definition: blockchain.cpp:1312
CTxMemPool::isSpent
bool isSpent(const COutPoint &outpoint) const
Definition: txmempool.cpp:341
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:5019
RBFTransactionState::REPLACEABLE_BIP125
@ REPLACEABLE_BIP125
Either this tx or a mempool ancestor signals rbf.
warnings.h
IsBlockPruned
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
Definition: validation.h:1017
CChainState::PreciousBlock
bool PreciousBlock(BlockValidationState &state, const CChainParams &params, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as precious and reorganize.
Definition: validation.cpp:2818
GetUTXOStats
static bool GetUTXOStats(CCoinsView *view, BlockManager &blockman, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point)
Calculate statistics about the unspent transaction output set.
Definition: coinstats.cpp:87
BlockFilterIndex::LookupFilterHeader
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out)
Get a single filter header by block.
Definition: blockfilterindex.cpp:385
CChainState::CoinsTip
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:613
WITNESS_SCALE_FACTOR
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
txdb.h
base_blob::begin
unsigned char * begin()
Definition: uint256.h:58
MempoolEntryDescription
static std::vector< RPCResult > MempoolEntryDescription()
Definition: blockchain.cpp:423
SnapshotMetadata
Metadata describing a serialized version of a UTXO set from which an assumeutxo CChainState can be co...
Definition: utxo_snapshot.h:14
CBlockUndo
Undo information for a CBlock.
Definition: undo.h:63
WAIT_LOCK
#define WAIT_LOCK(cs, name)
Definition: sync.h:237
CChainState::m_chain
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition: validation.h:596
DEFAULT_MAX_MEMPOOL_SIZE
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
Definition: policy.h:32
waitforblock
static RPCHelpMan waitforblock()
Definition: blockchain.cpp:293
FlatSigningProvider
Definition: signingprovider.h:47
descriptor.h
SetHasKeys
static bool SetHasKeys(const std::set< T > &set)
Definition: blockchain.cpp:1838
it
auto it
Definition: validation.cpp:399
DEFAULT_CHECKBLOCKS
static const signed int DEFAULT_CHECKBLOCKS
Definition: validation.h:91
rbf.h
blockToJSON
UniValue blockToJSON(const CBlock &block, const CBlockIndex *tip, const CBlockIndex *blockindex, bool txDetails)
Block description to JSON.
Definition: blockchain.cpp:171
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
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:30
HelpExampleCli
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:155
getblockcount
static RPCHelpMan getblockcount()
Definition: blockchain.cpp:200
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:453
CreateUTXOSnapshot
UniValue CreateUTXOSnapshot(NodeContext &node, CChainState &chainstate, CAutoFile &afile)
Helper to create UTXO snapshots given a chainstate and a file handle.
Definition: blockchain.cpp:2491
waitfornewblock
static RPCHelpMan waitfornewblock()
Definition: blockchain.cpp:251
CTxMemPoolEntry::GetTx
const CTransaction & GetTx() const
Definition: txmempool.h:122
BlockFilter
Complete block filter struct as defined in BIP 157.
Definition: blockfilter.h:110