8#include <blockfilter.h>
10#include <chainparams.h>
57#include <condition_variable>
77 const std::function<
void()>& interruption_point = {})
87 const fs::path& temppath,
88 const std::function<
void()>& interruption_point = {});
94 int nShift = (blockindex.
nBits >> 24) & 0xff;
96 (double)0x0000ffff / (
double)(blockindex.
nBits & 0x00ffffff);
115 if (next && next->
pprev == &blockindex) {
119 return &blockindex == &tip ? 1 : -1;
128 const int height{param.
getInt<
int>()};
132 const int current_tip{active_chain.
Height()};
133 if (height > current_tip) {
137 return active_chain[height];
159 result.
pushKV(
"confirmations", confirmations);
173 if (blockindex.
pprev)
199 const bool is_not_pruned{
WITH_LOCK(
::cs_main,
return !blockman.IsBlockPruned(blockindex))};
201 if (have_undo && !blockman.
ReadBlockUndo(blockUndo, blockindex)) {
202 throw JSONRPCError(
RPC_INTERNAL_ERROR,
"Undo data expected but can't be read. This could be due to disk corruption or a conflict with a pruning event.");
204 for (
size_t i = 0; i < block.
vtx.size(); ++i) {
207 const CTxUndo* txundo = (have_undo && i > 0) ? &blockUndo.
vtxundo.at(i - 1) :
nullptr;
215 result.
pushKV(
"tx", std::move(txs));
224 "Returns the height of the most-work fully-validated chain.\n"
225 "The genesis block has height 0.\n",
246 "Returns the hash of the best (tip) block in the most-work fully-validated chain.\n",
267 "Waits for any new block and returns useful info about it.\n"
268 "\nReturns the current block on timeout or exit.\n"
269 "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
286 if (!request.params[0].isNull())
287 timeout = request.params[0].
getInt<
int>();
295 std::optional<BlockRef> block = timeout ? miner.
waitTipChanged(current_block.hash, std::chrono::milliseconds(timeout)) :
299 if (block) current_block = *block;
302 ret.pushKV(
"hash", current_block.hash.GetHex());
303 ret.pushKV(
"height", current_block.height);
313 "Waits for a specific new block and returns useful info about it.\n"
314 "\nReturns the current block on timeout or exit.\n"
315 "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
327 HelpExampleCli(
"waitforblock",
"\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000")
328 +
HelpExampleRpc(
"waitforblock",
"\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
336 if (!request.params[1].isNull())
337 timeout = request.params[1].getInt<
int>();
346 const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
347 while (current_block.hash != hash) {
348 std::optional<BlockRef> block;
350 auto now{std::chrono::steady_clock::now()};
351 if (now >= deadline)
break;
359 current_block = *block;
363 ret.pushKV(
"hash", current_block.hash.GetHex());
364 ret.pushKV(
"height", current_block.height);
373 "waitforblockheight",
374 "Waits for (at least) block height and returns the height and hash\n"
375 "of the current tip.\n"
376 "\nReturns the current block on timeout or exit.\n"
377 "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
396 int height = request.params[0].
getInt<
int>();
398 if (!request.params[1].isNull())
399 timeout = request.params[1].getInt<
int>();
408 const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
410 while (current_block.height < height) {
411 std::optional<BlockRef> block;
413 auto now{std::chrono::steady_clock::now()};
414 if (now >= deadline)
break;
422 current_block = *block;
426 ret.pushKV(
"hash", current_block.hash.GetHex());
427 ret.pushKV(
"height", current_block.height);
436 "syncwithvalidationinterfacequeue",
437 "Waits for the validation interface queue to catch up on everything that was there when we entered this function.\n",
457 "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.\n",
460 RPCResult::Type::NUM,
"",
"the proof-of-work difficulty as a multiple of the minimum difficulty."},
478 "Attempt to fetch block from a given peer.\n\n"
479 "We must have the header for this block, e.g. using submitheader.\n"
480 "The block will not have any undo data which can limit the usage of the block data in a context where the undo data is needed.\n"
481 "Subsequent calls for the same block may cause the response from the previous peer to be ignored.\n"
482 "Peers generally ignore requests for a stale block that they never fully verified, or one that is more than a month old.\n"
483 "When a peer does not respond with a block, we will disconnect.\n"
484 "Note: The block could be re-pruned as soon as it is received.\n\n"
485 "Returns an empty JSON object if the request was successfully scheduled.",
492 HelpExampleCli(
"getblockfrompeer",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
493 +
HelpExampleRpc(
"getblockfrompeer",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
502 const NodeId peer_id{request.params[1].getInt<int64_t>()};
513 throw JSONRPCError(
RPC_MISC_ERROR,
"In prune mode, only blocks that the node has already synced previously can be fetched from a peer");
517 if (block_has_data) {
521 if (
const auto err{peerman.
FetchBlock(peer_id, *index)}) {
533 "Returns hash of block in best-block-chain at height provided.\n",
549 int nHeight = request.params[0].getInt<
int>();
550 if (nHeight < 0 || nHeight > active_chain.
Height())
563 "If verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
564 "If verbose is true, returns an Object with information about blockheader <hash>.\n",
574 {
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations, or -1 if the block is not on the main chain"},
594 HelpExampleCli(
"getblockheader",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
595 +
HelpExampleRpc(
"getblockheader",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
601 bool fVerbose =
true;
602 if (!request.params[1].isNull())
603 fVerbose = request.params[1].get_bool();
622 std::string strHex =
HexStr(ssBlock);
635 if (!(blockindex.nStatus & flag)) {
636 if (blockman.IsBlockPruned(blockindex)) {
639 if (check_for_undo) {
654 if (!blockman.
ReadBlock(block, blockindex)) {
665 std::vector<std::byte>
data{};
687 if (blockindex.
nHeight == 0)
return blockUndo;
717 {
RPCResult::Type::STR,
"address",
true,
"The Bitcoin address (only if a well-defined address exists)"},
729 "If verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
730 "If verbosity is 1, returns an Object with information about block <hash>.\n"
731 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.\n"
732 "If verbosity is 3, returns an Object with information about block <hash> and information about each transaction, including prevout information for inputs (only for unpruned blocks in the current best chain).\n",
735 {
"verbosity|verbose",
RPCArg::Type::NUM,
RPCArg::Default{1},
"0 for hex-encoded data, 1 for a JSON object, 2 for JSON object with transaction data, and 3 for JSON object with transaction data including prevout information for inputs",
745 {
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations, or -1 if the block is not on the main chain"},
761 {
RPCResult::Type::STR_HEX,
"chainwork",
"Expected number of hashes required to produce the chain up to this block (in hex)"},
774 {
RPCResult::Type::ELISION,
"",
"The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result"},
793 HelpExampleCli(
"getblock",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
794 +
HelpExampleRpc(
"getblock",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
817 if (verbosity <= 0) {
818 return HexStr(block_data);
826 if (verbosity == 1) {
828 }
else if (verbosity == 2) {
850 if (!first_block || !chain_tip)
return std::nullopt;
856 if (&first_unpruned == first_block) {
868 "Attempts to delete block and undo data up to a specified height or timestamp, if eligible for pruning.\n"
869 "Requires `-prune` to be enabled at startup. While pruned data may be re-fetched in some cases (e.g., via `getblockfrompeer`), local deletion is irreversible.\n",
872 " to prune blocks whose block time is at least 2 hours older than the provided timestamp."},
891 int heightParam = request.params[0].getInt<
int>();
892 if (heightParam < 0) {
898 if (heightParam > 1000000000) {
907 unsigned int height = (
unsigned int) heightParam;
908 unsigned int chainHeight = (
unsigned int) active_chain.
Height();
911 }
else if (height > chainHeight) {
914 LogDebug(
BCLog::RPC,
"Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.\n");
926 if (hash_type_input ==
"hash_serialized_3") {
927 return CoinStatsHashType::HASH_SERIALIZED;
928 }
else if (hash_type_input ==
"muhash") {
929 return CoinStatsHashType::MUHASH;
930 }
else if (hash_type_input ==
"none") {
944 const std::function<
void()>& interruption_point = {},
946 bool index_requested =
true)
971 "Returns statistics about the unspent transaction output set.\n"
972 "Note this call may take some time if you are not using coinstatsindex.\n",
974 {
"hash_type",
RPCArg::Type::STR,
RPCArg::Default{
"hash_serialized_3"},
"Which UTXO set hash should be calculated. Options: 'hash_serialized_3' (the legacy algorithm), 'muhash', 'none'."},
978 .type_str = {
"",
"string or numeric"},
988 {
RPCResult::Type::NUM,
"bogosize",
"Database-independent, meaningless metric indicating the UTXO set size"},
989 {
RPCResult::Type::STR_HEX,
"hash_serialized_3",
true,
"The serialized hash (only present if 'hash_serialized_3' hash_type is chosen)"},
991 {
RPCResult::Type::NUM,
"transactions",
true,
"The number of transactions with unspent outputs (not available when coinstatsindex is used)"},
992 {
RPCResult::Type::NUM,
"disk_size",
true,
"The estimated size of the chainstate on disk (not available when coinstatsindex is used)"},
994 {
RPCResult::Type::STR_AMOUNT,
"total_unspendable_amount",
true,
"The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)"},
995 {
RPCResult::Type::OBJ,
"block_info",
true,
"Info on amounts in the block at this block height (only available if coinstatsindex is used)",
1014 HelpExampleCli("gettxoutsetinfo", R
"("none" '"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"')") +
1015 HelpExampleCli("-named gettxoutsetinfo", R
"(hash_type='muhash' use_index='false')") +
1019 HelpExampleRpc("gettxoutsetinfo", R
"("none", "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09")")
1027 bool index_requested = request.params[2].isNull() || request.params[2].get_bool();
1038 coins_view = &active_chainstate.
CoinsDB();
1043 if (!request.params[1].isNull()) {
1048 if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1052 if (!index_requested) {
1064 if (pindex->
nHeight > summary.best_block_height) {
1070 const std::optional<CCoinsStats> maybe_stats =
GetUTXOStats(coins_view, *blockman, hash_type,
node.rpc_interruption_point, pindex, index_requested);
1071 if (maybe_stats.has_value()) {
1073 ret.pushKV(
"height", (int64_t)stats.
nHeight);
1077 if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1080 if (hash_type == CoinStatsHashType::MUHASH) {
1093 const std::optional<CCoinsStats> maybe_prev_stats =
GetUTXOStats(coins_view, *blockman, hash_type,
node.rpc_interruption_point, pindex->
pprev, index_requested);
1094 if (!maybe_prev_stats) {
1097 prev_stats = maybe_prev_stats.value();
1111 block_info.
pushKV(
"unspendables", std::move(unspendables));
1113 ret.pushKV(
"block_info", std::move(block_info));
1127 "Returns details about an unspent transaction output.\n",
1131 {
"include_mempool",
RPCArg::Type::BOOL,
RPCArg::Default{
true},
"Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."},
1144 {
RPCResult::Type::STR,
"address",
true,
"The Bitcoin address (only if a well-defined address exists)"},
1150 "\nGet unspent transactions\n"
1152 "\nView the details\n"
1154 "\nAs a JSON-RPC call\n"
1166 COutPoint out{hash, request.params[1].getInt<uint32_t>()};
1167 bool fMempool =
true;
1168 if (!request.params[2].isNull())
1169 fMempool = request.params[2].get_bool();
1174 std::optional<Coin> coin;
1188 ret.pushKV(
"confirmations", 0);
1190 ret.pushKV(
"confirmations", (int64_t)(pindex->
nHeight - coin->nHeight + 1));
1195 ret.pushKV(
"scriptPubKey", std::move(o));
1196 ret.pushKV(
"coinbase", (
bool)coin->fCoinBase);
1207 "Verifies blockchain database.\n",
1214 RPCResult::Type::BOOL,
"",
"Verification finished successfully. If false, check debug.log for reason."},
1222 const int check_depth{request.params[1].isNull() ?
DEFAULT_CHECKBLOCKS : request.params[1].getInt<
int>()};
1241 rv.
pushKV(
"type",
"buried");
1253 if (blockindex ==
nullptr)
return;
1260 if (info.stats.has_value()) {
1261 bip9.
pushKV(
"bit", depparams.bit);
1263 bip9.
pushKV(
"start_time", depparams.nStartTime);
1264 bip9.
pushKV(
"timeout", depparams.nTimeout);
1265 bip9.
pushKV(
"min_activation_height", depparams.min_activation_height);
1268 bip9.
pushKV(
"status", info.current_state);
1269 bip9.
pushKV(
"since", info.since);
1270 bip9.
pushKV(
"status_next", info.next_state);
1273 if (info.stats.has_value()) {
1275 statsUV.
pushKV(
"period", info.stats->period);
1276 statsUV.
pushKV(
"elapsed", info.stats->elapsed);
1277 statsUV.
pushKV(
"count", info.stats->count);
1278 if (info.stats->threshold > 0 || info.stats->possible) {
1279 statsUV.
pushKV(
"threshold", info.stats->threshold);
1280 statsUV.
pushKV(
"possible", info.stats->possible);
1282 bip9.
pushKV(
"statistics", std::move(statsUV));
1285 sig.reserve(info.signalling_blocks.size());
1286 for (
const bool s : info.signalling_blocks) {
1287 sig.push_back(
s ?
'#' :
'-');
1289 bip9.
pushKV(
"signalling", sig);
1293 rv.
pushKV(
"type",
"bip9");
1294 bool is_active =
false;
1295 if (info.active_since.has_value()) {
1296 rv.
pushKV(
"height", *info.active_since);
1297 is_active = (*info.active_since <= blockindex->
nHeight + 1);
1299 rv.
pushKV(
"active", is_active);
1308 "Returns an object containing various state info regarding blockchain processing.\n",
1314 {
RPCResult::Type::NUM,
"blocks",
"the height of the most-work fully-validated chain. The genesis block has height 0"},
1323 {
RPCResult::Type::BOOL,
"initialblockdownload",
"(debug information) estimate of whether this node is in Initial Block Download mode"},
1325 {
RPCResult::Type::NUM,
"size_on_disk",
"the estimated size of the block and undo files on disk"},
1327 {
RPCResult::Type::NUM,
"pruneheight",
true,
"height of the last block pruned, plus one (only present if pruning is enabled)"},
1328 {
RPCResult::Type::BOOL,
"automatic_pruning",
true,
"whether automatic pruning is enabled (only present if pruning is enabled)"},
1329 {
RPCResult::Type::NUM,
"prune_target_size",
true,
"the target size used by pruning (only present if automatic pruning is enabled)"},
1330 {
RPCResult::Type::STR_HEX,
"signet_challenge",
true,
"the block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
1333 RPCResult{
RPCResult::Type::ARR,
"warnings",
"any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
1351 const int height{tip.
nHeight};
1354 obj.
pushKV(
"blocks", height);
1355 obj.
pushKV(
"headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
1369 obj.
pushKV(
"pruneheight", prune_height ? prune_height.value() + 1 : 0);
1372 obj.
pushKV(
"automatic_pruning", automatic_pruning);
1373 if (automatic_pruning) {
1378 const std::vector<uint8_t>& signet_challenge =
1380 obj.
pushKV(
"signet_challenge",
HexStr(signet_challenge));
1391const std::vector<RPCResult> RPCHelpForDeployment{
1393 {
RPCResult::Type::NUM,
"height",
true,
"height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)"},
1394 {
RPCResult::Type::BOOL,
"active",
"true if the rules are enforced for the mempool and the next block"},
1397 {
RPCResult::Type::NUM,
"bit",
true,
"the bit (0-28) in the block version field used to signal this softfork (only for \"started\" and \"locked_in\" status)"},
1398 {
RPCResult::Type::NUM_TIME,
"start_time",
"the minimum median time past of a block at which the bit gains its meaning"},
1399 {
RPCResult::Type::NUM_TIME,
"timeout",
"the median time past of a block at which the deployment is considered failed if not yet locked in"},
1400 {
RPCResult::Type::NUM,
"min_activation_height",
"minimum height of blocks for which the rules may be enforced"},
1401 {
RPCResult::Type::STR,
"status",
"status of deployment at specified block (one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\")"},
1404 {
RPCResult::Type::OBJ,
"statistics",
true,
"numeric statistics about signalling for a softfork (only for \"started\" and \"locked_in\" status)",
1407 {
RPCResult::Type::NUM,
"threshold",
true,
"the number of blocks with the version bit set required to activate the feature (only for \"started\" status)"},
1408 {
RPCResult::Type::NUM,
"elapsed",
"the number of blocks elapsed since the beginning of the current period"},
1409 {
RPCResult::Type::NUM,
"count",
"the number of blocks with the version bit set in the current period"},
1410 {
RPCResult::Type::BOOL,
"possible",
true,
"returns false if there are not enough blocks left in this period to pass activation threshold (only for \"started\" status)"},
1412 {
RPCResult::Type::STR,
"signalling",
true,
"indicates blocks that signalled with a # and blocks that did not with a -"},
1433 "Returns an object containing various state info regarding deployments of consensus changes.",
1454 if (request.params[0].isNull()) {
1467 deploymentinfo.
pushKV(
"deployments", DeploymentInfo(blockindex, chainman));
1468 return deploymentinfo;
1491 "Return information about all known tips in the block tree,"
1492 " including the main chain as well as orphaned branches.\n",
1500 {
RPCResult::Type::NUM,
"branchlen",
"zero for main chain, otherwise length of branch connecting the tip to the main chain"},
1502 "Possible values for status:\n"
1503 "1. \"invalid\" This branch contains at least one invalid block\n"
1504 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1505 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1506 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1507 "5. \"active\" This is the tip of the active main chain, which is certainly valid"},
1526 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1527 std::set<const CBlockIndex*> setOrphans;
1528 std::set<const CBlockIndex*> setPrevs;
1530 for (
const auto& [
_, block_index] : chainman.
BlockIndex()) {
1531 if (!active_chain.
Contains(&block_index)) {
1532 setOrphans.insert(&block_index);
1533 setPrevs.insert(block_index.pprev);
1537 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) {
1538 if (setPrevs.erase(*it) == 0) {
1539 setTips.insert(*it);
1544 setTips.insert(active_chain.
Tip());
1550 obj.
pushKV(
"height", block->nHeight);
1551 obj.
pushKV(
"hash", block->phashBlock->GetHex());
1553 const int branchLen = block->nHeight - active_chain.
FindFork(block)->
nHeight;
1554 obj.
pushKV(
"branchlen", branchLen);
1557 if (active_chain.
Contains(block)) {
1563 }
else if (!block->HaveNumChainTxs()) {
1565 status =
"headers-only";
1568 status =
"valid-fork";
1571 status =
"valid-headers";
1576 obj.
pushKV(
"status", status);
1590 "Treats a block as if it were received before others with the same work.\n"
1591 "\nA later preciousblock call can override the effect of an earlier one.\n"
1592 "\nThe effects of preciousblock are not retained across restarts.\n",
1652 "Permanently marks a block as invalid, as if it violated a consensus rule.\n",
1682 chainman.RecalculateBestHeader();
1697 "Removes invalidity status of a block, its ancestors and its descendants, reconsider them for activation.\n"
1698 "This can be used to undo the effects of invalidateblock.\n",
1723 "Compute statistics about the total number and rate of transactions in the chain.\n",
1733 "The total number of transactions in the chain up to that point, if known. "
1734 "It may be unknown when using assumeutxo."},
1736 {
RPCResult::Type::NUM,
"window_final_block_height",
"The height of the final block in the window."},
1738 {
RPCResult::Type::NUM,
"window_interval",
true,
"The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0"},
1740 "The number of transactions in the window. "
1741 "Only returned if \"window_block_count\" is > 0 and if txcount exists for the start and end of the window."},
1743 "The average rate of transactions per second in the window. "
1744 "Only returned if \"window_interval\" is > 0 and if window_tx_count exists."},
1756 if (request.params[1].isNull()) {
1773 if (request.params[0].isNull()) {
1774 blockcount = std::max(0, std::min(blockcount, pindex->
nHeight - 1));
1776 blockcount = request.params[0].getInt<
int>();
1778 if (blockcount < 0 || (blockcount > 0 && blockcount >= pindex->
nHeight)) {
1784 const int64_t nTimeDiff{pindex->
GetMedianTimePast() - past_block.GetMedianTimePast()};
1787 ret.pushKV(
"time", (int64_t)pindex->
nTime);
1792 ret.pushKV(
"window_final_block_height", pindex->
nHeight);
1793 ret.pushKV(
"window_block_count", blockcount);
1794 if (blockcount > 0) {
1795 ret.pushKV(
"window_interval", nTimeDiff);
1797 const auto window_tx_count = pindex->
m_chain_tx_count - past_block.m_chain_tx_count;
1798 ret.pushKV(
"window_tx_count", window_tx_count);
1799 if (nTimeDiff > 0) {
1800 ret.pushKV(
"txrate",
double(window_tx_count) / nTimeDiff);
1813 size_t size = scores.size();
1818 std::sort(scores.begin(), scores.end());
1819 if (size % 2 == 0) {
1820 return (scores[size / 2 - 1] + scores[size / 2]) / 2;
1822 return scores[size / 2];
1828 if (scores.empty()) {
1832 std::sort(scores.begin(), scores.end());
1836 total_weight / 10.0, total_weight / 4.0, total_weight / 2.0, (total_weight * 3.0) / 4.0, (total_weight * 9.0) / 10.0
1839 int64_t next_percentile_index = 0;
1840 int64_t cumulative_weight = 0;
1841 for (
const auto& element : scores) {
1842 cumulative_weight += element.second;
1843 while (next_percentile_index < NUM_GETBLOCKSTATS_PERCENTILES && cumulative_weight >= weights[next_percentile_index]) {
1844 result[next_percentile_index] = element.first;
1845 ++next_percentile_index;
1851 result[i] = scores.back().first;
1856static inline bool SetHasKeys(
const std::set<T>& set) {
return false;}
1857template<
typename T,
typename Tk,
typename... Args>
1858static inline bool SetHasKeys(
const std::set<T>& set,
const Tk& key,
const Args&...
args)
1870 "Compute per block statistics for a given window. All amounts are in satoshis.\n"
1871 "It won't work for some heights with pruning.\n",
1876 .type_str = {
"",
"string or numeric"},
1892 {
RPCResult::Type::ARR_FIXED,
"feerate_percentiles",
true,
"Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)",
1917 {
RPCResult::Type::NUM,
"total_out",
true,
"Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])"},
1922 {
RPCResult::Type::NUM,
"utxo_increase",
true,
"The increase/decrease in the number of unspent outputs (not discounting op_return and similar)"},
1923 {
RPCResult::Type::NUM,
"utxo_size_inc",
true,
"The increase/decrease in size for the utxo index (not discounting op_return and similar)"},
1924 {
RPCResult::Type::NUM,
"utxo_increase_actual",
true,
"The increase/decrease in the number of unspent outputs, not counting unspendables"},
1925 {
RPCResult::Type::NUM,
"utxo_size_inc_actual",
true,
"The increase/decrease in size for the utxo index, not counting unspendables"},
1928 HelpExampleCli(
"getblockstats", R
"('"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"' '["minfeerate","avgfeerate"]')") +
1929 HelpExampleCli("getblockstats", R
"(1000 '["minfeerate","avgfeerate"]')") +
1930 HelpExampleRpc("getblockstats", R
"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") +
1931 HelpExampleRpc("getblockstats", R
"(1000, ["minfeerate","avgfeerate"])")
1938 std::set<std::string> stats;
1939 if (!request.params[1].isNull()) {
1941 for (
unsigned int i = 0; i < stats_univalue.
size(); i++) {
1942 const std::string stat = stats_univalue[i].
get_str();
1950 const bool do_all = stats.size() == 0;
1951 const bool do_mediantxsize = do_all || stats.count(
"mediantxsize") != 0;
1952 const bool do_medianfee = do_all || stats.count(
"medianfee") != 0;
1953 const bool do_feerate_percentiles = do_all || stats.count(
"feerate_percentiles") != 0;
1954 const bool loop_inputs = do_all || do_medianfee || do_feerate_percentiles ||
1955 SetHasKeys(stats,
"utxo_increase",
"utxo_increase_actual",
"utxo_size_inc",
"utxo_size_inc_actual",
"totalfee",
"avgfee",
"avgfeerate",
"minfee",
"maxfee",
"minfeerate",
"maxfeerate");
1956 const bool loop_outputs = do_all || loop_inputs || stats.count(
"total_out");
1957 const bool do_calculate_size = do_mediantxsize ||
1958 SetHasKeys(stats,
"total_size",
"avgtxsize",
"mintxsize",
"maxtxsize",
"swtotal_size");
1959 const bool do_calculate_weight = do_all ||
SetHasKeys(stats,
"total_weight",
"avgfeerate",
"swtotal_weight",
"avgfeerate",
"feerate_percentiles",
"minfeerate",
"maxfeerate");
1960 const bool do_calculate_sw = do_all ||
SetHasKeys(stats,
"swtxs",
"swtotal_size",
"swtotal_weight");
1969 int64_t maxtxsize = 0;
1971 int64_t outputs = 0;
1972 int64_t swtotal_size = 0;
1973 int64_t swtotal_weight = 0;
1975 int64_t total_size = 0;
1976 int64_t total_weight = 0;
1978 int64_t utxo_size_inc = 0;
1979 int64_t utxo_size_inc_actual = 0;
1980 std::vector<CAmount> fee_array;
1981 std::vector<std::pair<CAmount, int64_t>> feerate_array;
1982 std::vector<int64_t> txsize_array;
1984 for (
size_t i = 0; i < block.
vtx.size(); ++i) {
1985 const auto& tx = block.
vtx.at(i);
1986 outputs += tx->vout.size();
1991 tx_total_out +=
out.nValue;
1994 utxo_size_inc += out_size;
2000 if (
out.scriptPubKey.IsUnspendable())
continue;
2003 utxo_size_inc_actual += out_size;
2007 if (tx->IsCoinBase()) {
2011 inputs += tx->vin.size();
2012 total_out += tx_total_out;
2014 int64_t tx_size = 0;
2015 if (do_calculate_size) {
2017 tx_size = tx->GetTotalSize();
2018 if (do_mediantxsize) {
2019 txsize_array.push_back(tx_size);
2021 maxtxsize = std::max(maxtxsize, tx_size);
2022 mintxsize = std::min(mintxsize, tx_size);
2023 total_size += tx_size;
2027 if (do_calculate_weight) {
2029 total_weight += weight;
2032 if (do_calculate_sw && tx->HasWitness()) {
2034 swtotal_size += tx_size;
2035 swtotal_weight += weight;
2040 const auto& txundo = blockUndo.
vtxundo.at(i - 1);
2041 for (
const Coin& coin: txundo.vprevout) {
2044 tx_total_in += prevoutput.
nValue;
2046 utxo_size_inc -= prevout_size;
2047 utxo_size_inc_actual -= prevout_size;
2050 CAmount txfee = tx_total_in - tx_total_out;
2053 fee_array.push_back(txfee);
2055 maxfee = std::max(maxfee, txfee);
2056 minfee = std::min(minfee, txfee);
2061 if (do_feerate_percentiles) {
2062 feerate_array.emplace_back(feerate, weight);
2064 maxfeerate = std::max(maxfeerate, feerate);
2065 minfeerate = std::min(minfeerate, feerate);
2074 feerates_res.
push_back(feerate_percentiles[i]);
2078 ret_all.
pushKV(
"avgfee", (block.
vtx.size() > 1) ? totalfee / (block.
vtx.size() - 1) : 0);
2080 ret_all.
pushKV(
"avgtxsize", (block.
vtx.size() > 1) ? total_size / (block.
vtx.size() - 1) : 0);
2082 ret_all.
pushKV(
"feerate_percentiles", std::move(feerates_res));
2084 ret_all.
pushKV(
"ins", inputs);
2085 ret_all.
pushKV(
"maxfee", maxfee);
2086 ret_all.
pushKV(
"maxfeerate", maxfeerate);
2087 ret_all.
pushKV(
"maxtxsize", maxtxsize);
2092 ret_all.
pushKV(
"minfeerate", (minfeerate ==
MAX_MONEY) ? 0 : minfeerate);
2094 ret_all.
pushKV(
"outs", outputs);
2096 ret_all.
pushKV(
"swtotal_size", swtotal_size);
2097 ret_all.
pushKV(
"swtotal_weight", swtotal_weight);
2098 ret_all.
pushKV(
"swtxs", swtxs);
2100 ret_all.
pushKV(
"total_out", total_out);
2101 ret_all.
pushKV(
"total_size", total_size);
2102 ret_all.
pushKV(
"total_weight", total_weight);
2103 ret_all.
pushKV(
"totalfee", totalfee);
2104 ret_all.
pushKV(
"txs", (int64_t)block.
vtx.size());
2105 ret_all.
pushKV(
"utxo_increase", outputs - inputs);
2106 ret_all.
pushKV(
"utxo_size_inc", utxo_size_inc);
2107 ret_all.
pushKV(
"utxo_increase_actual", utxos - inputs);
2108 ret_all.
pushKV(
"utxo_size_inc_actual", utxo_size_inc_actual);
2115 for (
const std::string& stat : stats) {
2116 const UniValue& value = ret_all[stat];
2120 ret.pushKV(stat, value);
2129bool FindScriptPubKey(std::atomic<int>& scan_progress,
const std::atomic<bool>& should_abort, int64_t&
count,
CCoinsViewCursor* cursor,
const std::set<CScript>& needles, std::map<COutPoint, Coin>& out_results, std::function<
void()>& interruption_point)
2133 while (cursor->
Valid()) {
2136 if (!cursor->
GetKey(key) || !cursor->
GetValue(coin))
return false;
2137 if (++
count % 8192 == 0) {
2138 interruption_point();
2144 if (
count % 256 == 0) {
2147 scan_progress = (int)(high * 100.0 / 65536.0 + 0.5);
2150 out_results.emplace(key, coin);
2154 scan_progress = 100;
2190 "\"start\" for starting a scan\n"
2191 "\"abort\" for aborting the current scan (returns true when abort was successful)\n"
2192 "\"status\" for progress report (in %) of the current scan"
2197 "Every scan object is either a string descriptor or an object:",
2211 "True if scan will be aborted (not necessarily before this RPC returns), or false if there is no scan to abort"
2214 "when action=='status' and no scan is in progress - possibly already completed",
RPCResult::Type::NONE,
"",
""
2225 const std::string EXAMPLE_DESCRIPTOR_RAW =
"raw(76a91411b366edfc0a8b66feebae5c2e25a7b6a5d1cf3188ac)#fm24fxxy";
2229 "Scans the unspent transaction output set for entries that match certain output descriptors.\n"
2230 "Examples of output descriptors are:\n"
2231 " addr(<address>) Outputs whose output script corresponds to the specified address (does not include P2PK)\n"
2232 " raw(<hex script>) Outputs whose output script equals the specified hex-encoded bytes\n"
2233 " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n"
2234 " pkh(<pubkey>) P2PKH outputs for the given pubkey\n"
2235 " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"
2236 " tr(<pubkey>) P2TR\n"
2237 " tr(<pubkey>,{pk(<pubkey>)}) P2TR with single fallback pubkey in tapscript\n"
2238 " rawtr(<pubkey>) P2TR with the specified key as output key rather than inner\n"
2239 " wsh(and_v(v:pk(<pubkey>),after(2))) P2WSH miniscript with mandatory pubkey and a timelock\n"
2240 "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
2241 "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
2242 "unhardened or hardened child keys.\n"
2243 "In the latter case, a range needs to be specified by below if different from 1000.\n"
2244 "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n",
2267 {
RPCResult::Type::NUM,
"confirmations",
"Number of confirmations of the unspent transaction output when the scan was done"},
2277 HelpExampleCli(
"scantxoutset",
"start \'[\"" + EXAMPLE_DESCRIPTOR_RAW +
"\"]\'") +
2280 HelpExampleRpc(
"scantxoutset",
"\"start\", [\"" + EXAMPLE_DESCRIPTOR_RAW +
"\"]") +
2287 const auto action{self.
Arg<std::string>(
"action")};
2288 if (action ==
"status") {
2296 }
else if (action ==
"abort") {
2305 }
else if (action ==
"start") {
2311 if (request.params.size() < 2) {
2315 std::set<CScript> needles;
2316 std::map<CScript, std::string> descriptors;
2326 descriptors.emplace(std::move(
script), std::move(inferred));
2332 std::vector<CTxOut> input_txos;
2333 std::map<COutPoint, Coin> coins;
2336 std::unique_ptr<CCoinsViewCursor> pcursor;
2348 result.
pushKV(
"success", res);
2353 for (
const auto& it : coins) {
2355 const Coin& coin = it.second;
2358 input_txos.push_back(txo);
2363 unspent.
pushKV(
"vout", outpoint.
n);
2369 unspent.
pushKV(
"blockhash", coinb_block.GetBlockHash().GetHex());
2374 result.
pushKV(
"unspents", std::move(unspents));
2418 for (
const auto& tx : block.vtx) {
2419 if (std::any_of(tx->vout.cbegin(), tx->vout.cend(), [&](
const auto& txout) {
2420 return needles.count(std::vector<unsigned char>(txout.scriptPubKey.begin(), txout.scriptPubKey.end())) != 0;
2426 for (
const auto& txundo : block_undo.vtxundo) {
2427 if (std::any_of(txundo.vprevout.cbegin(), txundo.vprevout.cend(), [&](
const auto& coin) {
2428 return needles.count(std::vector<unsigned char>(coin.out.scriptPubKey.begin(), coin.out.scriptPubKey.end())) != 0;
2441 "Return relevant blockhashes for given descriptors (requires blockfilterindex).\n"
2442 "This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
2451 {
"filter_false_positives",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Filter false positives (slower and may fail on pruned nodes). Otherwise they may occur at a rate of 1/M"},
2473 HelpExampleCli(
"scanblocks",
"start '[\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"]' 300000") +
2474 HelpExampleCli(
"scanblocks",
"start '[\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"]' 100 150 basic") +
2476 HelpExampleRpc(
"scanblocks",
"\"start\", [\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"], 300000") +
2477 HelpExampleRpc(
"scanblocks",
"\"start\", [\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"], 100, 150, \"basic\"") +
2483 if (request.params[0].get_str() ==
"status") {
2492 }
else if (request.params[0].get_str() ==
"abort") {
2501 }
else if (request.params[0].get_str() ==
"start") {
2506 const std::string filtertype_name{request.params[4].isNull() ?
"basic" : request.params[4].get_str()};
2514 bool filter_false_positives{options.exists(
"filter_false_positives") ? options[
"filter_false_positives"].get_bool() :
false};
2530 start_index = active_chain.
Genesis();
2531 stop_block = active_chain.
Tip();
2532 if (!request.params[2].isNull()) {
2533 start_index = active_chain[request.params[2].getInt<
int>()];
2538 if (!request.params[3].isNull()) {
2539 stop_block = active_chain[request.params[3].getInt<
int>()];
2558 const int amount_per_chunk = 10000;
2559 std::vector<BlockFilter> filters;
2560 int start_block_height = start_index->
nHeight;
2561 const int total_blocks_to_process = stop_block->
nHeight - start_block_height;
2566 bool completed =
true;
2570 node.rpc_interruption_point();
2577 int start_block = !end_range ? start_index->
nHeight : start_index->
nHeight + 1;
2578 end_range = (start_block + amount_per_chunk < stop_block->
nHeight) ?
2585 if (filter.GetFilter().MatchAny(needle_set)) {
2586 if (filter_false_positives) {
2595 blocks.
push_back(filter.GetBlockHash().GetHex());
2599 start_index = end_range;
2602 int blocks_processed = end_range->
nHeight - start_block_height;
2603 if (total_blocks_to_process > 0) {
2611 }
while (start_index != stop_block);
2613 ret.pushKV(
"from_height", start_block_height);
2614 ret.pushKV(
"to_height", start_index->
nHeight);
2615 ret.pushKV(
"relevant_blocks", std::move(blocks));
2616 ret.pushKV(
"completed", completed);
2629 "getdescriptoractivity",
2630 "Get spend and receive activity associated with a set of descriptors for a set of blocks. "
2631 "This command pairs well with the `relevant_blocks` output of `scanblocks()`.\n"
2632 "This call may take several minutes. If you encounter timeouts, try specifying no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
2668 HelpExampleCli(
"getdescriptoractivity",
"'[\"000000000000000000001347062c12fded7c528943c8ce133987e2e2f5a840ee\"]' '[\"addr(bc1qzl6nsgqzu89a66l50cvwapnkw5shh23zarqkw9)\"]'")
2677 struct CompareByHeightAscending {
2683 std::set<const CBlockIndex*, CompareByHeightAscending> blockindexes_sorted;
2697 blockindexes_sorted.insert(pindex);
2701 std::set<CScript> scripts_to_watch;
2709 scripts_to_watch.insert(
script);
2713 const auto AddSpend = [&](
2725 event.pushKV(
"type",
"spend");
2728 event.pushKV(
"blockhash", index->GetBlockHash().ToString());
2729 event.pushKV(
"height", index->nHeight);
2731 event.pushKV(
"spend_txid", tx->GetHash().ToString());
2732 event.pushKV(
"spend_vin", vin);
2733 event.pushKV(
"prevout_txid", txin.prevout.hash.ToString());
2734 event.pushKV(
"prevout_vout", txin.prevout.n);
2735 event.pushKV(
"prevout_spk", spkUv);
2745 event.pushKV(
"type",
"receive");
2748 event.pushKV(
"blockhash", index->GetBlockHash().ToString());
2749 event.pushKV(
"height", index->nHeight);
2751 event.pushKV(
"txid", tx->GetHash().ToString());
2752 event.pushKV(
"vout", vout);
2753 event.pushKV(
"output_spk", spkUv);
2765 for (
const CBlockIndex* blockindex : blockindexes_sorted) {
2769 for (
size_t i = 0; i < block.vtx.size(); ++i) {
2770 const auto& tx = block.vtx.at(i);
2772 if (!tx->IsCoinBase()) {
2774 const auto& txundo = block_undo.
vtxundo.at(i - 1);
2776 for (
size_t vin_idx = 0; vin_idx < tx->vin.size(); ++vin_idx) {
2777 const auto& coin = txundo.vprevout.at(vin_idx);
2778 const auto& txin = tx->vin.at(vin_idx);
2786 for (
size_t vout_idx = 0; vout_idx < tx->vout.size(); ++vout_idx) {
2787 const auto& vout = tx->vout.at(vout_idx);
2788 if (scripts_to_watch.contains(vout.scriptPubKey)) {
2789 activity.
push_back(AddReceive(vout, blockindex, vout_idx, tx));
2795 bool search_mempool =
true;
2796 if (!request.params[2].isNull()) {
2797 search_mempool = request.params[2].get_bool();
2800 if (search_mempool) {
2807 const auto& tx = e.GetSharedTx();
2809 for (
size_t vin_idx = 0; vin_idx < tx->vin.size(); ++vin_idx) {
2812 const auto& txin = tx->vin.at(vin_idx);
2813 std::optional<Coin> coin = coins_view.
GetCoin(txin.prevout);
2821 if (txin.prevout.n >= prev_tx->vout.size()) {
2822 throw std::runtime_error(
"Invalid output index");
2824 const CTxOut&
out = prev_tx->vout[txin.prevout.n];
2825 scriptPubKey =
out.scriptPubKey;
2830 scriptPubKey =
out.scriptPubKey;
2834 if (scripts_to_watch.contains(scriptPubKey)) {
2837 scriptPubKey, value, tx, vin_idx, txin,
nullptr));
2841 for (
size_t vout_idx = 0; vout_idx < tx->vout.size(); ++vout_idx) {
2842 const auto& vout = tx->vout.at(vout_idx);
2843 if (scripts_to_watch.contains(vout.scriptPubKey)) {
2844 activity.
push_back(AddReceive(vout,
nullptr, vout_idx, tx));
2850 ret.pushKV(
"activity", activity);
2860 "Retrieve a BIP 157 content filter for a particular block.\n",
2872 HelpExampleCli(
"getblockfilter",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") +
2873 HelpExampleRpc(
"getblockfilter",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"")
2879 if (!request.params[1].isNull()) {
2880 filtertype_name = request.params[1].get_str();
2894 bool block_was_connected;
2905 bool index_ready = index->BlockUntilSyncedToCurrentChain();
2912 std::string errmsg =
"Filter not found.";
2914 if (!block_was_connected) {
2916 errmsg +=
" Block was not connected to active chain.";
2917 }
else if (!index_ready) {
2919 errmsg +=
" Block filters are still in the process of being indexed.";
2922 errmsg +=
" This error is unexpected and indicates index corruption.";
2930 ret.pushKV(
"header", filter_header.
GetHex());
2981 "Write the serialized UTXO set to a file. This can be used in loadtxoutset afterwards if this snapshot height is supported in the chainparams as well.\n\n"
2982 "Unless the \"latest\" type is requested, the node will roll back to the requested height and network activity will be suspended during this process. "
2983 "Because of this it is discouraged to interact with the node in any other way during the execution of this call to avoid inconsistent results and race conditions, particularly RPCs that interact with blockstorage.\n\n"
2984 "This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
2987 {
"type",
RPCArg::Type::STR,
RPCArg::Default(
""),
"The type of snapshot to create. Can be \"latest\" to create a snapshot of the current UTXO set or \"rollback\" to temporarily roll back the state of the node to a historical block before creating the snapshot of a historical UTXO set. This parameter can be omitted if a separate \"rollback\" named parameter is specified indicating the height or hash of a specific historical block. If \"rollback\" is specified and separate \"rollback\" named parameter is not specified, this will roll back to the latest valid snapshot block that can currently be loaded with loadtxoutset."},
2991 "Height or hash of the block to roll back to before creating the snapshot. Note: The further this number is from the tip, the longer this process will take. Consider setting a higher -rpcclienttimeout value in this case.",
3004 {
RPCResult::Type::NUM,
"nchaintx",
"the number of transactions in the chain up to and including the base block"},
3008 HelpExampleCli(
"-rpcclienttimeout=0 dumptxoutset",
"utxo.dat latest") +
3009 HelpExampleCli(
"-rpcclienttimeout=0 dumptxoutset",
"utxo.dat rollback") +
3010 HelpExampleCli(
"-rpcclienttimeout=0 -named dumptxoutset", R
"(utxo.dat rollback=853456)")
3017 const std::string snapshot_type{self.
Arg<std::string>(
"type")};
3019 if (options.exists(
"rollback")) {
3020 if (!snapshot_type.empty() && snapshot_type !=
"rollback") {
3024 }
else if (snapshot_type ==
"rollback") {
3025 auto snapshot_heights =
node.chainman->GetParams().GetAvailableSnapshotHeights();
3027 auto max_height = std::max_element(snapshot_heights.begin(), snapshot_heights.end());
3029 }
else if (snapshot_type ==
"latest") {
3044 path.utf8string() +
" already exists. If you are sure this is what you want, "
3045 "move it out of the way first");
3053 "Couldn't open file " + temppath.utf8string() +
" for writing.");
3058 std::optional<NetworkDisable> disable_network;
3059 std::optional<TemporaryRollback> temporary_rollback;
3063 if (target_index != tip) {
3066 if (
node.chainman->m_blockman.IsPruneMode()) {
3070 if (first_block->nHeight > target_index->nHeight) {
3084 disable_network.emplace(connman);
3088 temporary_rollback.emplace(*
node.chainman, *invalidate_index);
3092 std::unique_ptr<CCoinsViewCursor> cursor;
3102 chainstate = &
node.chainman->ActiveChainstate();
3109 if (target_index != chainstate->
m_chain.
Tip()) {
3110 LogWarning(
"dumptxoutset failed to roll back to requested height, reverting to tip.\n");
3118 fs::rename(temppath, path);
3120 result.
pushKV(
"path", path.utf8string());
3129 const std::function<
void()>& interruption_point)
3131 std::unique_ptr<CCoinsViewCursor> pcursor;
3132 std::optional<CCoinsStats> maybe_stats;
3170 const fs::path& path,
3171 const fs::path& temppath,
3172 const std::function<
void()>& interruption_point)
3185 unsigned int iter{0};
3186 size_t written_coins_count{0};
3187 std::vector<std::pair<uint32_t, Coin>> coins;
3196 auto write_coins_to_file = [&](
AutoFile& afile,
const Txid& last_hash,
const std::vector<std::pair<uint32_t, Coin>>& coins,
size_t& written_coins_count) {
3199 for (
const auto& [n, coin] : coins) {
3202 ++written_coins_count;
3207 last_hash = key.
hash;
3208 while (pcursor->
Valid()) {
3209 if (iter % 5000 == 0) interruption_point();
3212 if (key.
hash != last_hash) {
3213 write_coins_to_file(afile, last_hash, coins, written_coins_count);
3214 last_hash = key.
hash;
3217 coins.emplace_back(key.
n, coin);
3222 if (!coins.empty()) {
3223 write_coins_to_file(afile, last_hash, coins, written_coins_count);
3231 result.
pushKV(
"coins_written", written_coins_count);
3234 result.
pushKV(
"path", path.utf8string());
3244 const fs::path& path,
3245 const fs::path& tmppath)
3248 return WriteUTXOSnapshot(chainstate, cursor.get(), &stats, tip, afile, path, tmppath,
node.rpc_interruption_point);
3255 "Load the serialized UTXO set from a file.\n"
3256 "Once this snapshot is loaded, its contents will be "
3257 "deserialized into a second chainstate data structure, which is then used to sync to "
3258 "the network's tip. "
3259 "Meanwhile, the original chainstate will complete the initial block download process in "
3260 "the background, eventually validating up to the block that the snapshot is based upon.\n\n"
3262 "The result is a usable bitcoind instance that is current with the network tip in a "
3263 "matter of minutes rather than hours. UTXO snapshot are typically obtained from "
3264 "third-party sources (HTTP, torrent, etc.) which is reasonable since their "
3265 "contents are always checked by hash.\n\n"
3267 "You can find more information on this process in the `assumeutxo` design "
3268 "document (<https://github.com/bitcoin/bitcoin/blob/master/doc/design/assumeutxo.md>).",
3273 "path to the snapshot file. If relative, will be prefixed by datadir."},
3298 "Couldn't open file " + path.utf8string() +
" for reading.");
3304 }
catch (
const std::ios_base::failure& e) {
3309 if (!activation_result) {
3323 result.
pushKV(
"coins_loaded", metadata.m_coins_count);
3324 result.
pushKV(
"tip_hash", snapshot_index.GetBlockHash().ToString());
3325 result.
pushKV(
"base_height", snapshot_index.nHeight);
3339 {
RPCResult::Type::STR_HEX,
"snapshot_blockhash",
true,
"the base block of the snapshot this chainstate is based on, if any"},
3342 {
RPCResult::Type::BOOL,
"validated",
"whether the chainstate is fully validated. True if all blocks in the chainstate were validated, false if the chain is based on a snapshot and the snapshot has not yet been validated."},
3349 "Return information about chainstates.\n",
3371 if (!
cs.m_chain.Tip()) {
3383 data.pushKV(
"coins_db_cache_bytes",
cs.m_coinsdb_cache_size_bytes);
3384 data.pushKV(
"coins_tip_cache_bytes",
cs.m_coinstip_cache_size_bytes);
3385 if (
cs.m_from_snapshot_blockhash) {
3386 data.pushKV(
"snapshot_blockhash",
cs.m_from_snapshot_blockhash->ToString());
3388 data.pushKV(
"validated", validated);
3392 obj.
pushKV(
"headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
3394 const auto& chainstates = chainman.
GetAll();
3397 obj_chainstates.push_back(make_chain_data(*
cs, !
cs->m_from_snapshot_blockhash || chainstates.size() == 1));
3399 obj.
pushKV(
"chainstates", std::move(obj_chainstates));
3440 for (
const auto& c : commands) {
3441 t.appendCommand(c.name, &c);
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
fs::path AbsPathForConfigVal(const ArgsManager &args, const fs::path &path, bool net_specific=true)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
static RPCHelpMan getblock()
static RPCHelpMan getdifficulty()
static const auto scan_result_abort
static std::atomic< bool > g_scan_in_progress
static bool SetHasKeys(const std::set< T > &set)
static RPCHelpMan reconsiderblock()
static T CalculateTruncatedMedian(std::vector< T > &scores)
static RPCHelpMan invalidateblock()
static int ComputeNextBlockAndDepth(const CBlockIndex &tip, const CBlockIndex &blockindex, const CBlockIndex *&next)
const RPCResult getblock_vin
static RPCHelpMan syncwithvalidationinterfacequeue()
static CBlockUndo GetUndoChecked(BlockManager &blockman, const CBlockIndex &blockindex)
static std::vector< std::byte > GetRawBlockChecked(BlockManager &blockman, const CBlockIndex &blockindex)
static RPCHelpMan getchaintips()
static RPCHelpMan loadtxoutset()
static RPCHelpMan gettxoutsetinfo()
static RPCHelpMan getchainstates()
std::tuple< std::unique_ptr< CCoinsViewCursor >, CCoinsStats, const CBlockIndex * > PrepareUTXOSnapshot(Chainstate &chainstate, const std::function< void()> &interruption_point)
static std::atomic< int > g_scanfilter_progress_height
static RPCHelpMan getblockstats()
void CheckBlockDataAvailability(BlockManager &blockman, const CBlockIndex &blockindex, bool check_for_undo)
static std::atomic< bool > g_scanfilter_should_abort_scan
static std::atomic< int > g_scanfilter_progress
RAII object to prevent concurrency issue when scanning blockfilters.
static void SoftForkDescPushBack(const CBlockIndex *blockindex, UniValue &softforks, const ChainstateManager &chainman, Consensus::BuriedDeployment dep)
static RPCHelpMan preciousblock()
static constexpr size_t PER_UTXO_OVERHEAD
static RPCHelpMan getdescriptoractivity()
double GetDifficulty(const CBlockIndex &blockindex)
Get the difficulty of the net wrt to the given block index.
static const auto scan_objects_arg_desc
static RPCHelpMan scantxoutset()
CoinStatsHashType ParseHashType(const std::string &hash_type_input)
static bool CheckBlockFilterMatches(BlockManager &blockman, const CBlockIndex &blockindex, const GCSFilter::ElementSet &needles)
void InvalidateBlock(ChainstateManager &chainman, const uint256 block_hash)
static std::atomic< int > g_scan_progress
RAII object to prevent concurrency issue when scanning the txout set.
static CBlock GetBlockChecked(BlockManager &blockman, const CBlockIndex &blockindex)
std::optional< int > GetPruneHeight(const BlockManager &blockman, const CChain &chain)
Return height of highest block that has been pruned, or std::nullopt if no blocks have been pruned.
UniValue blockToJSON(BlockManager &blockman, const CBlock &block, const CBlockIndex &tip, const CBlockIndex &blockindex, TxVerbosity verbosity, const uint256 pow_limit)
Block description to JSON.
RPCHelpMan getdeploymentinfo()
static RPCHelpMan getblockfilter()
static RPCHelpMan getbestblockhash()
RPCHelpMan getblockchaininfo()
void ReconsiderBlock(ChainstateManager &chainman, uint256 block_hash)
static RPCHelpMan getchaintxstats()
UniValue CreateUTXOSnapshot(node::NodeContext &node, Chainstate &chainstate, AutoFile &afile, const fs::path &path, const fs::path &tmppath)
Test-only helper to create UTXO snapshots given a chainstate and a file handle.
static RPCHelpMan waitforblock()
std::tuple< std::unique_ptr< CCoinsViewCursor >, CCoinsStats, const CBlockIndex * > PrepareUTXOSnapshot(Chainstate &chainstate, const std::function< void()> &interruption_point={}) EXCLUSIVE_LOCKS_REQUIRED(UniValue WriteUTXOSnapshot(Chainstate &chainstate, CCoinsViewCursor *pcursor, CCoinsStats *maybe_stats, const CBlockIndex *tip, AutoFile &afile, const fs::path &path, const fs::path &temppath, const std::function< void()> &interruption_point={})
UniValue blockheaderToJSON(const CBlockIndex &tip, const CBlockIndex &blockindex, const uint256 pow_limit)
Block header to JSON.
static RPCHelpMan getblockfrompeer()
static const auto scan_result_status_some
static RPCHelpMan getblockhash()
void RegisterBlockchainRPCCommands(CRPCTable &t)
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector< std::pair< CAmount, int64_t > > &scores, int64_t total_weight)
Used by getblockstats to get feerates at different percentiles by weight
static std::optional< kernel::CCoinsStats > GetUTXOStats(CCoinsView *view, node::BlockManager &blockman, kernel::CoinStatsHashType hash_type, const std::function< void()> &interruption_point={}, const CBlockIndex *pindex=nullptr, bool index_requested=true)
Calculate statistics about the unspent transaction output set.
static RPCHelpMan gettxout()
static RPCHelpMan verifychain()
static std::atomic< bool > g_should_abort_scan
const std::vector< RPCResult > RPCHelpForChainstate
static const auto scan_action_arg_desc
static RPCHelpMan waitforblockheight()
static const CBlockIndex * ParseHashOrHeight(const UniValue ¶m, ChainstateManager &chainman)
static RPCHelpMan pruneblockchain()
static RPCHelpMan getblockheader()
static RPCHelpMan scanblocks()
static std::atomic< bool > g_scanfilter_in_progress
static RPCHelpMan dumptxoutset()
Serialize the UTXO set to a file for loading elsewhere.
static RPCHelpMan getblockcount()
static RPCHelpMan waitfornewblock()
static const auto scan_result_status_none
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.
bool BlockFilterTypeByName(const std::string &name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous.
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
@ BLOCK_HAVE_DATA
full block available in blk*.dat
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
#define LIST_CHAIN_NAMES
List of possible chain / network names
#define CHECK_NONFATAL(condition)
Identity function.
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
Non-refcounted RAII wrapper for FILE*.
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Complete block filter struct as defined in BIP 157.
const std::vector< unsigned char > & GetEncodedFilter() const LIFETIMEBOUND
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
bool LookupFilterRange(int start_height, const CBlockIndex *stop_index, std::vector< BlockFilter > &filters_out) const
Get a range of filters between two heights on a chain.
bool LookupFilter(const CBlockIndex *block_index, BlockFilter &filter_out) const
Get a single filter by block.
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache)
Get a single filter header by block.
BlockFiltersScanReserver()=default
~BlockFiltersScanReserver()
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
uint64_t m_chain_tx_count
(memory only) Number of transactions in the chain up to and including this block.
CBlockHeader GetBlockHeader() const
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
uint256 GetBlockHash() const
int64_t GetBlockTime() const
int64_t GetMedianTimePast() const
unsigned int nTx
Number of transactions in this block.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
int32_t nVersion
block header
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
Undo information for a CBlock.
std::vector< CTxUndo > vtxundo
An in-memory indexed chain of blocks.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
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...
int Height() const
Return the maximal height in the chain.
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
std::string GetChainTypeString() const
Return the chain type string.
const MessageStartChars & MessageStart() const
const Consensus::Params & GetConsensus() const
uint64_t PruneAfterHeight() const
ChainType GetChainType() const
Return the chain type.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Cursor for iterating over CoinsView state.
virtual bool Valid() const =0
virtual bool GetKey(COutPoint &key) const =0
virtual bool GetValue(Coin &coin) const =0
std::unique_ptr< CCoinsViewCursor > Cursor() const override
Get a cursor to iterate over the whole state.
Abstract view on the open txout dataset.
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
CCoinsView that brings transactions from a mempool into view.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
GetCoin, returning whether it exists and is not spent.
bool GetNetworkActive() const
void SetNetworkActive(bool active)
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
An input of a transaction.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
CTransactionRef get(const uint256 &hash) const
std::vector< CTxMemPoolEntryRef > entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs)
bool isSpent(const COutPoint &outpoint) const
An output of a transaction.
Undo information for a CTransaction.
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
VerifyDBResult VerifyDB(Chainstate &chainstate, const Consensus::Params &consensus_params, CCoinsView &coinsview, int nCheckLevel, int nCheckDepth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CChain m_chain
The current chain of blockheaders we consult and build on.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
node::BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
double GuessVerificationProgress(const CBlockIndex *pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip).
kernel::Notifications & GetNotifications() const
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network)
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
VersionBitsCache m_versionbitscache
Track versionbit status.
const CChainParams & GetParams() const
const Consensus::Params & GetConsensus() const
util::Result< CBlockIndex * > ActivateSnapshot(AutoFile &coins_file, const node::SnapshotMetadata &metadata, bool in_memory)
Construct and activate a Chainstate on the basis of UTXO snapshot data.
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Chainstate &InitializeChainstate(CTxMemPool *mempool) EXCLUSIVE_LOCKS_REQUIRED(std::vector< Chainstate * GetAll)()
Instantiate a new chainstate.
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
CTxOut out
unspent transaction output
uint32_t nHeight
at which height this containing transaction was included in the active block chain
CoinsViewScanReserver()=default
Double ended buffer combining vector and stream-like interfaces.
std::unordered_set< Element, ByteVectorHash > ElementSet
RAII class that disables the network in its constructor and enables it in its destructor.
NetworkDisable(CConnman &connman)
virtual std::optional< std::string > FetchBlock(NodeId peer_id, const CBlockIndex &block_index)=0
Attempt to manually fetch block from a given peer.
auto Arg(std::string_view key) const
Helper to get a required or default-valued request argument.
RAII class that temporarily rolls back the local chain in it's constructor and rolls it forward again...
TemporaryRollback(ChainstateManager &chainman, const CBlockIndex &index)
const CBlockIndex & m_invalidate_index
ChainstateManager & m_chainman
void push_back(UniValue val)
const std::string & get_str() const
const std::vector< UniValue > & getValues() const
const UniValue & get_array() const
void pushKV(std::string key, UniValue val)
std::string ToString() const
BIP9Info Info(const CBlockIndex &block_index, const Consensus::Params ¶ms, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
std::string ToString() const
std::string GetHex() const
std::string GetHex() const
Hex encoding of the number (with the most significant digits first).
Interface giving clients (RPC, Stratum v2 Template Provider in the future) ability to create block te...
virtual std::optional< BlockRef > waitTipChanged(uint256 current_tip, MillisecondsDouble timeout=MillisecondsDouble::max())=0
Waits for the connected tip to change.
virtual std::optional< BlockRef > getTip()=0
Returns the hash and height for the tip of this chain.
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
bool ReadBlock(CBlock &block, const FlatFilePos &pos, const std::optional< uint256 > &expected_hash={}) const
Functions for disk access for blocks.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool ReadBlockUndo(CBlockUndo &blockundo, const CBlockIndex &index) const
uint64_t GetPruneTarget() const
Attempt to stay below this number of bytes of block files.
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
bool ReadRawBlock(std::vector< std::byte > &block, const FlatFilePos &pos) const
bool IsPruneMode() const
Whether running in -prune mode.
constexpr const std::byte * begin() const
std::string GetHex() const
static transaction_identifier FromUint256(const uint256 &id)
std::unique_ptr< CoinStatsIndex > g_coin_stats_index
The global UTXO set hash object.
static int64_t GetBlockWeight(const CBlock &block)
static int32_t GetTransactionWeight(const CTransaction &tx)
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
static const int WITNESS_SCALE_FACTOR
void TxToUniv(const CTransaction &tx, const uint256 &block_hash, UniValue &entry, bool include_hex=true, const CTxUndo *txundo=nullptr, TxVerbosity verbosity=TxVerbosity::SHOW_DETAILS)
TxVerbosity
Verbose level for block's transaction.
@ SHOW_DETAILS_AND_PREVOUT
The same as previous option with information about prevouts if available.
@ SHOW_TXID
Only TXID for each block's transaction.
@ SHOW_DETAILS
Include TXID, inputs, outputs, and other common block's transaction information.
void ScriptToUniv(const CScript &script, UniValue &out, bool include_hex=true, bool include_address=false, const SigningProvider *provider=nullptr)
UniValue ValueFromAmount(const CAmount amount)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
std::string DeploymentName(Consensus::BuriedDeployment dep)
bool DeploymentActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep, VersionBitsCache &versionbitscache)
Determine if a deployment is active for the next block.
bool DeploymentEnabled(const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is enabled (can ever be active)
const std::string CURRENCY_UNIT
static path u8path(const std::string &utf8_str)
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to a byte string.
#define T(expected, seed, data)
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
#define LogDebug(category,...)
BuriedDeployment
A buried deployment is one where the height of the activation has been hardcoded into the client impl...
FILE * fopen(const fs::path &p, const char *mode)
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
static bool ComputeUTXOStats(CCoinsView *view, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point)
Calculate statistics about the unspent transaction output set.
UniValue GetWarningsForRpc(const Warnings &warnings, bool use_deprecated)
RPC helper function that wraps warnings.GetMessages().
bilingual_str ErrorString(const Result< T > &result)
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
static constexpr TransactionSerParams TX_NO_WITNESS
static constexpr TransactionSerParams TX_WITH_WITNESS
std::shared_ptr< const CTransaction > CTransactionRef
UniValue JSONRPCError(int code, const std::string &message)
@ RPC_MISC_ERROR
General application defined errors.
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
@ RPC_DATABASE_ERROR
Database error.
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
std::vector< CScript > EvalDescriptorStringOrObject(const UniValue &scanobject, FlatSigningProvider &provider, const bool expand_priv)
Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range ...
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
uint256 GetTarget(const CBlockIndex &blockindex, const uint256 pow_limit)
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
std::string GetAllOutputTypes()
Gets all existing output types formatted for RPC help sections.
int ParseVerbosity(const UniValue &arg, int default_verbosity, bool allow_bool)
Parses verbosity from provided UniValue.
uint256 ParseHashV(const UniValue &v, std::string_view name)
Utilities: convert hex-encoded Values (throws error if not hex).
std::vector< RPCResult > ScriptPubKeyDoc()
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
size_t GetSerializeSize(const T &t)
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
bool IsDeprecatedRPCEnabled(const std::string &method)
ChainstateManager & EnsureAnyChainman(const std::any &context)
NodeContext & EnsureAnyNodeContext(const std::any &context)
CTxMemPool & EnsureMemPool(const NodeContext &node)
PeerManager & EnsurePeerman(const NodeContext &node)
ChainstateManager & EnsureChainman(const NodeContext &node)
ArgsManager & EnsureArgsman(const NodeContext &node)
interfaces::Mining & EnsureMining(const NodeContext &node)
CConnman & EnsureConnman(const NodeContext &node)
ArgsManager & EnsureAnyArgsman(const std::any &context)
unsigned char * UCharCast(char *c)
Detailed status of an enabled BIP9 deployment.
Comparison function for sorting the getchaintips heads.
bool operator()(const CBlockIndex *a, const CBlockIndex *b) const
std::vector< uint8_t > signet_challenge
uint256 powLimit
Proof of work parameters.
int DeploymentHeight(BuriedDeployment dep) const
std::array< BIP9Deployment, MAX_VERSION_BITS_DEPLOYMENTS > vDeployments
int64_t nPowTargetSpacing
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ STR_HEX
Special type that is a STR with only hex chars.
@ OBJ_NAMED_PARAMS
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
std::string DefaultHint
Hint for default value.
@ OMITTED
Optional argument for which the default value is omitted from help text for one of two reasons:
UniValue Default
Default constant value.
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
@ ELISION
Special type to denote elision (...)
@ NUM_TIME
Special numeric to denote unix epoch time.
@ ARR_FIXED
Special array that has a fixed number of entries.
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
@ STR_AMOUNT
Special string to represent a floating point amount.
Hash/height pair to help track and identify blocks.
std::optional< CAmount > total_amount
The total amount, or nullopt if an overflow occurred calculating it.
CAmount total_unspendable_amount
Total cumulative amount of unspendable coins up to and including this block.
CAmount total_unspendables_scripts
Total cumulative amount of outputs sent to unspendable scripts (OP_RETURN for example) up to and incl...
uint64_t coins_count
The number of coins contained.
CAmount total_new_outputs_ex_coinbase_amount
Total cumulative amount of outputs created up to and including this block.
uint64_t nTransactionOutputs
CAmount total_coinbase_amount
Total cumulative amount of coinbase outputs up to and including this block.
bool index_used
Signals if the coinstatsindex was used to retrieve the statistics.
CAmount total_unspendables_bip30
The two unspendable coinbase outputs total amount caused by BIP30.
CAmount total_unspendables_genesis_block
The unspendable coinbase amount from the genesis block.
CAmount total_prevout_spent_amount
Total cumulative amount of prevouts spent up to and including this block.
CAmount total_unspendables_unclaimed_rewards
Total cumulative amount of coins lost due to unclaimed miner rewards up to and including this block.
NodeContext struct containing references to chain state and connection state.
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define LOG_TIME_SECONDS(end_msg)
consteval auto _(util::TranslatedLiteral str)
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0....
const UniValue NullUniValue
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
void PruneBlockFilesManual(Chainstate &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
bool IsBIP30Repeat(const CBlockIndex &block_index)
Identifies blocks that overwrote an existing coinbase output in the UTXO set (see BIP30)
static constexpr int DEFAULT_CHECKLEVEL
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
static const signed int DEFAULT_CHECKBLOCKS