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