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