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