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