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