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