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