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