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