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