8 #include <blockfilter.h> 10 #include <chainparams.h> 45 #include <txmempool.h> 59 #include <condition_variable> 65 #include <string_view> 81 const std::function<
void()>& interruption_point = {})
92 const std::function<
void()>& interruption_point = {});
98 int nShift = (blockindex.
nBits >> 24) & 0xff;
100 (double)0x0000ffff / (
double)(blockindex.
nBits & 0x00ffffff);
119 if (next && next->
pprev == &blockindex) {
123 return &blockindex == &tip ? 1 : -1;
132 const int height{param.
getInt<
int>()};
136 const int current_tip{active_chain.
Height()};
137 if (height > current_tip) {
141 return active_chain[height];
163 result.pushKV(
"confirmations", confirmations);
177 if (blockindex.
pprev)
188 const CTxIn& vin_0{coinbase_tx.
vin[0]};
192 coinbase_tx_obj.
pushKV(
"sequence", vin_0.nSequence);
193 coinbase_tx_obj.
pushKV(
"coinbase",
HexStr(vin_0.scriptSig));
194 const auto& witness_stack{vin_0.scriptWitness.stack};
195 if (!witness_stack.empty()) {
197 coinbase_tx_obj.
pushKV(
"witness",
HexStr(witness_stack[0]));
199 return coinbase_tx_obj;
226 const bool is_not_pruned{
WITH_LOCK(::
cs_main,
return !blockman.IsBlockPruned(blockindex))};
228 if (have_undo && !blockman.
ReadBlockUndo(blockUndo, blockindex)) {
229 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.");
231 for (
size_t i = 0; i < block.
vtx.size(); ++i) {
234 const CTxUndo* txundo = (have_undo && i > 0) ? &blockUndo.
vtxundo.at(i - 1) :
nullptr;
242 result.pushKV(
"tx", std::move(txs));
251 "Returns the height of the most-work fully-validated chain.\n" 252 "The genesis block has height 0.\n",
273 "Returns the hash of the best (tip) block in the most-work fully-validated chain.\n",
294 "Waits for any new block and returns useful info about it.\n" 295 "\nReturns the current block on timeout or exit.\n" 296 "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
314 if (!request.params[0].isNull())
315 timeout = request.params[0].
getInt<
int>();
329 uint256 tip_hash{request.params[1].isNull()
331 :
ParseHashV(request.params[1],
"current_tip")};
335 std::optional<BlockRef> block = timeout ? miner.
waitTipChanged(tip_hash, std::chrono::milliseconds(timeout)) :
339 if (block) current_block = *block;
342 ret.pushKV(
"hash", current_block.hash.GetHex());
343 ret.pushKV(
"height", current_block.height);
353 "Waits for a specific new block and returns useful info about it.\n" 354 "\nReturns the current block on timeout or exit.\n" 355 "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
367 HelpExampleCli(
"waitforblock",
"\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000")
368 +
HelpExampleRpc(
"waitforblock",
"\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
376 if (!request.params[1].isNull())
377 timeout = request.params[1].getInt<
int>();
386 const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
387 while (current_block.hash != hash) {
388 std::optional<BlockRef> block;
390 auto now{std::chrono::steady_clock::now()};
391 if (now >= deadline)
break;
399 current_block = *block;
403 ret.pushKV(
"hash", current_block.hash.GetHex());
404 ret.pushKV(
"height", current_block.height);
413 "waitforblockheight",
414 "Waits for (at least) block height and returns the height and hash\n" 415 "of the current tip.\n" 416 "\nReturns the current block on timeout or exit.\n" 417 "\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
436 int height = request.params[0].
getInt<
int>();
438 if (!request.params[1].isNull())
439 timeout = request.params[1].getInt<
int>();
448 const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
450 while (current_block.height < height) {
451 std::optional<BlockRef> block;
453 auto now{std::chrono::steady_clock::now()};
454 if (now >= deadline)
break;
462 current_block = *block;
466 ret.pushKV(
"hash", current_block.hash.GetHex());
467 ret.pushKV(
"height", current_block.height);
476 "syncwithvalidationinterfacequeue",
477 "Waits for the validation interface queue to catch up on everything that was there when we entered this function.\n",
497 "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.\n",
500 RPCResult::Type::NUM,
"",
"the proof-of-work difficulty as a multiple of the minimum difficulty."},
518 "Attempt to fetch block from a given peer.\n\n" 519 "We must have the header for this block, e.g. using submitheader.\n" 520 "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" 521 "Subsequent calls for the same block may cause the response from the previous peer to be ignored.\n" 522 "Peers generally ignore requests for a stale block that they never fully verified, or one that is more than a month old.\n" 523 "When a peer does not respond with a block, we will disconnect.\n" 524 "Note: The block could be re-pruned as soon as it is received.\n\n" 525 "Returns an empty JSON object if the request was successfully scheduled.",
532 HelpExampleCli(
"getblockfrompeer",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
533 +
HelpExampleRpc(
"getblockfrompeer",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
542 const NodeId peer_id{request.params[1].getInt<int64_t>()};
553 throw JSONRPCError(
RPC_MISC_ERROR,
"In prune mode, only blocks that the node has already synced previously can be fetched from a peer");
557 if (block_has_data) {
561 if (
const auto res{peerman.
FetchBlock(peer_id, *index)}; !res) {
573 "Returns hash of block in best-block-chain at height provided.\n",
589 int nHeight = request.params[0].getInt<
int>();
590 if (nHeight < 0 || nHeight > active_chain.
Height())
603 "If verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" 604 "If verbose is true, returns an Object with information about blockheader <hash>.\n",
614 {
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations, or -1 if the block is not on the main chain"},
634 HelpExampleCli(
"getblockheader",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
635 +
HelpExampleRpc(
"getblockheader",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
641 bool fVerbose =
true;
642 if (!request.params[1].isNull())
643 fVerbose = request.params[1].get_bool();
662 std::string strHex =
HexStr(ssBlock);
675 if (!(blockindex.nStatus & flag)) {
676 if (blockman.IsBlockPruned(blockindex)) {
679 if (check_for_undo) {
694 if (!blockman.
ReadBlock(block, blockindex)) {
723 if (blockindex.
nHeight == 0)
return blockUndo;
753 {
RPCResult::Type::STR,
"address",
true,
"The Bitcoin address (only if a well-defined address exists)"},
765 "If verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n" 766 "If verbosity is 1, returns an Object with information about block <hash>.\n" 767 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.\n" 768 "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",
771 {
"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",
781 {
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations, or -1 if the block is not on the main chain"},
791 {
RPCResult::Type::STR_HEX,
"witness",
true,
"The coinbase input's first (and only) witness stack element, if present"},
805 {
RPCResult::Type::STR_HEX,
"chainwork",
"Expected number of hashes required to produce the chain up to this block (in hex)"},
818 {
RPCResult::Type::ELISION,
"",
"The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result"},
837 HelpExampleCli(
"getblock",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
838 +
HelpExampleRpc(
"getblock",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
861 if (verbosity <= 0) {
862 return HexStr(block_data);
869 if (verbosity == 1) {
871 }
else if (verbosity == 2) {
893 if (!first_block || !chain_tip)
return std::nullopt;
898 const auto& first_unpruned{blockman.GetFirstBlock(*chain_tip,
BLOCK_HAVE_MASK, first_block)};
899 if (&first_unpruned == first_block) {
911 "Attempts to delete block and undo data up to a specified height or timestamp, if eligible for pruning.\n" 912 "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",
915 " to prune blocks whose block time is at least 2 hours older than the provided timestamp."},
934 int heightParam = request.params[0].getInt<
int>();
935 if (heightParam < 0) {
941 if (heightParam > 1000000000) {
950 unsigned int height = (
unsigned int) heightParam;
951 unsigned int chainHeight = (
unsigned int) active_chain.
Height();
954 }
else if (height > chainHeight) {
957 LogDebug(
BCLog::RPC,
"Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.\n");
969 if (hash_type_input ==
"hash_serialized_3") {
970 return CoinStatsHashType::HASH_SERIALIZED;
971 }
else if (hash_type_input ==
"muhash") {
972 return CoinStatsHashType::MUHASH;
973 }
else if (hash_type_input ==
"none") {
987 const std::function<
void()>& interruption_point = {},
989 bool index_requested =
true)
1014 "Returns statistics about the unspent transaction output set.\n" 1015 "Note this call may take some time if you are not using coinstatsindex.\n",
1017 {
"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'."},
1021 .type_str = {
"",
"string or numeric"},
1031 {
RPCResult::Type::NUM,
"bogosize",
"Database-independent, meaningless metric indicating the UTXO set size"},
1032 {
RPCResult::Type::STR_HEX,
"hash_serialized_3",
true,
"The serialized hash (only present if 'hash_serialized_3' hash_type is chosen)"},
1034 {
RPCResult::Type::NUM,
"transactions",
true,
"The number of transactions with unspent outputs (not available when coinstatsindex is used)"},
1035 {
RPCResult::Type::NUM,
"disk_size",
true,
"The estimated size of the chainstate on disk (not available when coinstatsindex is used)"},
1037 {
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)"},
1038 {
RPCResult::Type::OBJ,
"block_info",
true,
"Info on amounts in the block at this block height (only available if coinstatsindex is used)",
1057 HelpExampleCli("gettxoutsetinfo", R
"("none" '"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"')") + 1058 HelpExampleCli("-named gettxoutsetinfo", R
"(hash_type='muhash' use_index='false')") + 1062 HelpExampleRpc("gettxoutsetinfo", R
"("none", "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09")") 1070 bool index_requested = request.params[2].isNull() || request.params[2].get_bool();
1081 coins_view = &active_chainstate.
CoinsDB();
1085 if (!request.params[1].isNull()) {
1090 if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1094 if (!index_requested) {
1106 if (pindex && pindex->
nHeight > summary.best_block_height) {
1112 const std::optional<CCoinsStats> maybe_stats =
GetUTXOStats(coins_view, *blockman, hash_type,
node.rpc_interruption_point, pindex, index_requested);
1113 if (maybe_stats.has_value()) {
1119 if (hash_type == CoinStatsHashType::HASH_SERIALIZED) {
1122 if (hash_type == CoinStatsHashType::MUHASH) {
1134 const std::optional<CCoinsStats> maybe_prev_stats =
GetUTXOStats(coins_view, *blockman, hash_type,
node.rpc_interruption_point, block_index.
pprev, index_requested);
1135 if (!maybe_prev_stats) {
1138 prev_stats = maybe_prev_stats.value();
1145 CAmount prev_block_total_unspendable_amount = prev_stats.total_unspendables_genesis_block +
1146 prev_stats.total_unspendables_bip30 +
1147 prev_stats.total_unspendables_scripts +
1148 prev_stats.total_unspendables_unclaimed_rewards;
1150 ret.pushKV(
"total_unspendable_amount",
ValueFromAmount(block_total_unspendable_amount));
1163 block_info.
pushKV(
"unspendable",
ValueFromAmount(block_total_unspendable_amount - prev_block_total_unspendable_amount));
1170 block_info.
pushKV(
"unspendables", std::move(unspendables));
1172 ret.pushKV(
"block_info", std::move(block_info));
1186 "Returns details about an unspent transaction output.\n",
1190 {
"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."},
1203 {
RPCResult::Type::STR,
"address",
true,
"The Bitcoin address (only if a well-defined address exists)"},
1209 "\nGet unspent transactions\n" 1211 "\nView the details\n" 1213 "\nAs a JSON-RPC call\n" 1225 COutPoint out{hash, request.params[1].getInt<uint32_t>()};
1226 bool fMempool =
true;
1227 if (!request.params[2].isNull())
1228 fMempool = request.params[2].get_bool();
1233 std::optional<Coin> coin;
1247 ret.pushKV(
"confirmations", 0);
1249 ret.pushKV(
"confirmations", pindex->
nHeight - coin->nHeight + 1);
1254 ret.pushKV(
"scriptPubKey", std::move(o));
1255 ret.pushKV(
"coinbase", static_cast<bool>(coin->fCoinBase));
1266 "Verifies blockchain database.\n",
1273 RPCResult::Type::BOOL,
"",
"Verification finished successfully. If false, check debug.log for reason."},
1281 const int check_depth{request.params[1].isNull() ?
DEFAULT_CHECKBLOCKS : request.params[1].getInt<
int>()};
1300 rv.
pushKV(
"type",
"buried");
1312 if (blockindex ==
nullptr)
return;
1319 if (info.stats.has_value()) {
1320 bip9.
pushKV(
"bit", depparams.bit);
1322 bip9.
pushKV(
"start_time", depparams.nStartTime);
1323 bip9.
pushKV(
"timeout", depparams.nTimeout);
1324 bip9.
pushKV(
"min_activation_height", depparams.min_activation_height);
1327 bip9.
pushKV(
"status", info.current_state);
1328 bip9.
pushKV(
"since", info.since);
1329 bip9.
pushKV(
"status_next", info.next_state);
1332 if (info.stats.has_value()) {
1334 statsUV.
pushKV(
"period", info.stats->period);
1335 statsUV.
pushKV(
"elapsed", info.stats->elapsed);
1336 statsUV.
pushKV(
"count", info.stats->count);
1337 if (info.stats->threshold > 0 || info.stats->possible) {
1338 statsUV.
pushKV(
"threshold", info.stats->threshold);
1339 statsUV.
pushKV(
"possible", info.stats->possible);
1341 bip9.
pushKV(
"statistics", std::move(statsUV));
1344 sig.reserve(info.signalling_blocks.size());
1345 for (
const bool s : info.signalling_blocks) {
1346 sig.push_back(
s ?
'#' :
'-');
1348 bip9.
pushKV(
"signalling", sig);
1352 rv.
pushKV(
"type",
"bip9");
1353 bool is_active =
false;
1354 if (info.active_since.has_value()) {
1355 rv.
pushKV(
"height", *info.active_since);
1356 is_active = (*info.active_since <= blockindex->
nHeight + 1);
1358 rv.
pushKV(
"active", is_active);
1367 "Returns an object containing various state info regarding blockchain processing.\n",
1373 {
RPCResult::Type::NUM,
"blocks",
"the height of the most-work fully-validated chain. The genesis block has height 0"},
1382 {
RPCResult::Type::BOOL,
"initialblockdownload",
"(debug information) estimate of whether this node is in Initial Block Download mode"},
1384 {
RPCResult::Type::NUM,
"size_on_disk",
"the estimated size of the block and undo files on disk"},
1386 {
RPCResult::Type::NUM,
"pruneheight",
true,
"the first block unpruned, all previous blocks were pruned (only present if pruning is enabled)"},
1387 {
RPCResult::Type::BOOL,
"automatic_pruning",
true,
"whether automatic pruning is enabled (only present if pruning is enabled)"},
1388 {
RPCResult::Type::NUM,
"prune_target_size",
true,
"the target size used by pruning (only present if automatic pruning is enabled)"},
1389 {
RPCResult::Type::STR_HEX,
"signet_challenge",
true,
"the block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
1392 RPCResult{
RPCResult::Type::ARR,
"warnings",
"any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
1410 const int height{tip.
nHeight};
1413 obj.
pushKV(
"blocks", height);
1414 obj.
pushKV(
"headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
1428 obj.
pushKV(
"pruneheight", prune_height ? prune_height.value() + 1 : 0);
1431 obj.
pushKV(
"automatic_pruning", automatic_pruning);
1432 if (automatic_pruning) {
1437 const std::vector<uint8_t>& signet_challenge =
1439 obj.
pushKV(
"signet_challenge",
HexStr(signet_challenge));
1450 const std::vector<RPCResult> RPCHelpForDeployment{
1452 {
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)"},
1453 {
RPCResult::Type::BOOL,
"active",
"true if the rules are enforced for the mempool and the next block"},
1456 {
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)"},
1457 {
RPCResult::Type::NUM_TIME,
"start_time",
"the minimum median time past of a block at which the bit gains its meaning"},
1458 {
RPCResult::Type::NUM_TIME,
"timeout",
"the median time past of a block at which the deployment is considered failed if not yet locked in"},
1459 {
RPCResult::Type::NUM,
"min_activation_height",
"minimum height of blocks for which the rules may be enforced"},
1460 {
RPCResult::Type::STR,
"status",
"status of deployment at specified block (one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\")"},
1463 {
RPCResult::Type::OBJ,
"statistics",
true,
"numeric statistics about signalling for a softfork (only for \"started\" and \"locked_in\" status)",
1466 {
RPCResult::Type::NUM,
"threshold",
true,
"the number of blocks with the version bit set required to activate the feature (only for \"started\" status)"},
1467 {
RPCResult::Type::NUM,
"elapsed",
"the number of blocks elapsed since the beginning of the current period"},
1468 {
RPCResult::Type::NUM,
"count",
"the number of blocks with the version bit set in the current period"},
1469 {
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)"},
1471 {
RPCResult::Type::STR,
"signalling",
true,
"indicates blocks that signalled with a # and blocks that did not with a -"},
1492 "Returns an object containing various state info regarding deployments of consensus changes.",
1516 if (request.params[0].isNull()) {
1532 uv_flagnames.
push_backV(flagnames.begin(), flagnames.end());
1533 deploymentinfo.
pushKV(
"script_flags", uv_flagnames);
1535 deploymentinfo.
pushKV(
"deployments", DeploymentInfo(blockindex, chainman));
1536 return deploymentinfo;
1559 "Return information about all known tips in the block tree," 1560 " including the main chain as well as orphaned branches.\n",
1568 {
RPCResult::Type::NUM,
"branchlen",
"zero for main chain, otherwise length of branch connecting the tip to the main chain"},
1570 "Possible values for status:\n" 1571 "1. \"invalid\" This branch contains at least one invalid block\n" 1572 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" 1573 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" 1574 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" 1575 "5. \"active\" This is the tip of the active main chain, which is certainly valid"},
1594 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1595 std::set<const CBlockIndex*> setOrphans;
1596 std::set<const CBlockIndex*> setPrevs;
1598 for (
const auto& [
_, block_index] : chainman.
BlockIndex()) {
1599 if (!active_chain.
Contains(&block_index)) {
1600 setOrphans.insert(&block_index);
1601 setPrevs.insert(block_index.
pprev);
1605 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) {
1606 if (setPrevs.erase(*it) == 0) {
1607 setTips.insert(*it);
1612 setTips.insert(active_chain.
Tip());
1618 obj.
pushKV(
"height", block->nHeight);
1619 obj.
pushKV(
"hash", block->phashBlock->GetHex());
1621 const int branchLen = block->nHeight - active_chain.
FindFork(block)->
nHeight;
1622 obj.
pushKV(
"branchlen", branchLen);
1625 if (active_chain.
Contains(block)) {
1631 }
else if (!block->HaveNumChainTxs()) {
1633 status =
"headers-only";
1636 status =
"valid-fork";
1639 status =
"valid-headers";
1644 obj.
pushKV(
"status", status);
1658 "Treats a block as if it were received before others with the same work.\n" 1659 "\nA later preciousblock call can override the effect of an earlier one.\n" 1660 "\nThe effects of preciousblock are not retained across restarts.\n",
1720 "Permanently marks a block as invalid, as if it violated a consensus rule.\n",
1750 chainman.RecalculateBestHeader();
1765 "Removes invalidity status of a block, its ancestors and its descendants, reconsider them for activation.\n" 1766 "This can be used to undo the effects of invalidateblock.\n",
1791 "Compute statistics about the total number and rate of transactions in the chain.\n",
1801 "The total number of transactions in the chain up to that point, if known. " 1802 "It may be unknown when using assumeutxo."},
1804 {
RPCResult::Type::NUM,
"window_final_block_height",
"The height of the final block in the window."},
1806 {
RPCResult::Type::NUM,
"window_interval",
true,
"The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0"},
1808 "The number of transactions in the window. " 1809 "Only returned if \"window_block_count\" is > 0 and if txcount exists for the start and end of the window."},
1811 "The average rate of transactions per second in the window. " 1812 "Only returned if \"window_interval\" is > 0 and if window_tx_count exists."},
1824 if (request.params[1].isNull()) {
1841 if (request.params[0].isNull()) {
1842 blockcount = std::max(0, std::min(blockcount, pindex->
nHeight - 1));
1844 blockcount = request.params[0].getInt<
int>();
1846 if (blockcount < 0 || (blockcount > 0 && blockcount >= pindex->
nHeight)) {
1852 const int64_t nTimeDiff{pindex->
GetMedianTimePast() - past_block.GetMedianTimePast()};
1860 ret.pushKV(
"window_final_block_height", pindex->
nHeight);
1861 ret.pushKV(
"window_block_count", blockcount);
1862 if (blockcount > 0) {
1863 ret.pushKV(
"window_interval", nTimeDiff);
1865 const auto window_tx_count = pindex->
m_chain_tx_count - past_block.m_chain_tx_count;
1866 ret.pushKV(
"window_tx_count", window_tx_count);
1867 if (nTimeDiff > 0) {
1868 ret.pushKV(
"txrate",
double(window_tx_count) / nTimeDiff);
1878 template<
typename T>
1881 size_t size = scores.size();
1886 std::sort(scores.begin(), scores.end());
1887 if (size % 2 == 0) {
1888 return (scores[size / 2 - 1] + scores[size / 2]) / 2;
1890 return scores[size / 2];
1896 if (scores.empty()) {
1900 std::sort(scores.begin(), scores.end());
1904 total_weight / 10.0, total_weight / 4.0, total_weight / 2.0, (total_weight * 3.0) / 4.0, (total_weight * 9.0) / 10.0
1907 int64_t next_percentile_index = 0;
1908 int64_t cumulative_weight = 0;
1909 for (
const auto& element : scores) {
1910 cumulative_weight += element.second;
1911 while (next_percentile_index < NUM_GETBLOCKSTATS_PERCENTILES && cumulative_weight >= weights[next_percentile_index]) {
1912 result[next_percentile_index] = element.first;
1913 ++next_percentile_index;
1919 result[i] = scores.back().first;
1923 template<
typename T>
1924 static inline bool SetHasKeys(
const std::set<T>&
set) {
return false;}
1925 template<
typename T,
typename Tk,
typename... Args>
1926 static inline bool SetHasKeys(
const std::set<T>&
set,
const Tk& key,
const Args&...
args)
1938 "Compute per block statistics for a given window. All amounts are in satoshis.\n" 1939 "It won't work for some heights with pruning.\n",
1944 .type_str = {
"",
"string or numeric"},
1960 {
RPCResult::Type::ARR_FIXED,
"feerate_percentiles",
true,
"Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)",
1985 {
RPCResult::Type::NUM,
"total_out",
true,
"Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])"},
1990 {
RPCResult::Type::NUM,
"utxo_increase",
true,
"The increase/decrease in the number of unspent outputs (not discounting op_return and similar)"},
1991 {
RPCResult::Type::NUM,
"utxo_size_inc",
true,
"The increase/decrease in size for the utxo index (not discounting op_return and similar)"},
1992 {
RPCResult::Type::NUM,
"utxo_increase_actual",
true,
"The increase/decrease in the number of unspent outputs, not counting unspendables"},
1993 {
RPCResult::Type::NUM,
"utxo_size_inc_actual",
true,
"The increase/decrease in size for the utxo index, not counting unspendables"},
1996 HelpExampleCli(
"getblockstats", R
"('"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"' '["minfeerate","avgfeerate"]')") + 1997 HelpExampleCli("getblockstats", R
"(1000 '["minfeerate","avgfeerate"]')") + 1998 HelpExampleRpc("getblockstats", R
"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") + 1999 HelpExampleRpc("getblockstats", R
"(1000, ["minfeerate","avgfeerate"])") 2006 std::set<std::string> stats;
2007 if (!request.params[1].isNull()) {
2009 for (
unsigned int i = 0; i < stats_univalue.
size(); i++) {
2010 const std::string stat = stats_univalue[i].
get_str();
2018 const bool do_all = stats.size() == 0;
2019 const bool do_mediantxsize = do_all || stats.contains(
"mediantxsize");
2020 const bool do_medianfee = do_all || stats.contains(
"medianfee");
2021 const bool do_feerate_percentiles = do_all || stats.contains(
"feerate_percentiles");
2022 const bool loop_inputs = do_all || do_medianfee || do_feerate_percentiles ||
2023 SetHasKeys(stats,
"utxo_increase",
"utxo_increase_actual",
"utxo_size_inc",
"utxo_size_inc_actual",
"totalfee",
"avgfee",
"avgfeerate",
"minfee",
"maxfee",
"minfeerate",
"maxfeerate");
2024 const bool loop_outputs = do_all || loop_inputs || stats.contains(
"total_out");
2025 const bool do_calculate_size = do_mediantxsize ||
2026 SetHasKeys(stats,
"total_size",
"avgtxsize",
"mintxsize",
"maxtxsize",
"swtotal_size");
2027 const bool do_calculate_weight = do_all ||
SetHasKeys(stats,
"total_weight",
"avgfeerate",
"swtotal_weight",
"avgfeerate",
"feerate_percentiles",
"minfeerate",
"maxfeerate");
2028 const bool do_calculate_sw = do_all ||
SetHasKeys(stats,
"swtxs",
"swtotal_size",
"swtotal_weight");
2037 int64_t maxtxsize = 0;
2039 int64_t outputs = 0;
2040 int64_t swtotal_size = 0;
2041 int64_t swtotal_weight = 0;
2043 int64_t total_size = 0;
2044 int64_t total_weight = 0;
2046 int64_t utxo_size_inc = 0;
2047 int64_t utxo_size_inc_actual = 0;
2048 std::vector<CAmount> fee_array;
2049 std::vector<std::pair<CAmount, int64_t>> feerate_array;
2050 std::vector<int64_t> txsize_array;
2052 for (
size_t i = 0; i < block.
vtx.size(); ++i) {
2053 const auto& tx = block.
vtx.at(i);
2054 outputs += tx->vout.size();
2059 tx_total_out +=
out.nValue;
2062 utxo_size_inc += out_size;
2068 if (
out.scriptPubKey.IsUnspendable())
continue;
2071 utxo_size_inc_actual += out_size;
2075 if (tx->IsCoinBase()) {
2079 inputs += tx->vin.size();
2080 total_out += tx_total_out;
2082 int64_t tx_size = 0;
2083 if (do_calculate_size) {
2085 tx_size = tx->ComputeTotalSize();
2086 if (do_mediantxsize) {
2087 txsize_array.push_back(tx_size);
2089 maxtxsize = std::max(maxtxsize, tx_size);
2090 mintxsize = std::min(mintxsize, tx_size);
2091 total_size += tx_size;
2095 if (do_calculate_weight) {
2097 total_weight += weight;
2100 if (do_calculate_sw && tx->HasWitness()) {
2102 swtotal_size += tx_size;
2103 swtotal_weight += weight;
2108 const auto& txundo = blockUndo.
vtxundo.at(i - 1);
2109 for (
const Coin& coin: txundo.vprevout) {
2112 tx_total_in += prevoutput.
nValue;
2114 utxo_size_inc -= prevout_size;
2115 utxo_size_inc_actual -= prevout_size;
2118 CAmount txfee = tx_total_in - tx_total_out;
2121 fee_array.push_back(txfee);
2123 maxfee = std::max(maxfee, txfee);
2124 minfee = std::min(minfee, txfee);
2129 if (do_feerate_percentiles) {
2130 feerate_array.emplace_back(feerate, weight);
2132 maxfeerate = std::max(maxfeerate, feerate);
2133 minfeerate = std::min(minfeerate, feerate);
2142 feerates_res.
push_back(feerate_percentiles[i]);
2146 ret_all.
pushKV(
"avgfee", (block.
vtx.size() > 1) ? totalfee / (block.
vtx.size() - 1) : 0);
2148 ret_all.
pushKV(
"avgtxsize", (block.
vtx.size() > 1) ? total_size / (block.
vtx.size() - 1) : 0);
2150 ret_all.
pushKV(
"feerate_percentiles", std::move(feerates_res));
2152 ret_all.
pushKV(
"ins", inputs);
2153 ret_all.
pushKV(
"maxfee", maxfee);
2154 ret_all.
pushKV(
"maxfeerate", maxfeerate);
2155 ret_all.
pushKV(
"maxtxsize", maxtxsize);
2160 ret_all.
pushKV(
"minfeerate", (minfeerate ==
MAX_MONEY) ? 0 : minfeerate);
2162 ret_all.
pushKV(
"outs", outputs);
2164 ret_all.
pushKV(
"swtotal_size", swtotal_size);
2165 ret_all.
pushKV(
"swtotal_weight", swtotal_weight);
2166 ret_all.
pushKV(
"swtxs", swtxs);
2168 ret_all.
pushKV(
"total_out", total_out);
2169 ret_all.
pushKV(
"total_size", total_size);
2170 ret_all.
pushKV(
"total_weight", total_weight);
2171 ret_all.
pushKV(
"totalfee", totalfee);
2172 ret_all.
pushKV(
"txs", block.
vtx.size());
2173 ret_all.
pushKV(
"utxo_increase", outputs - inputs);
2174 ret_all.
pushKV(
"utxo_size_inc", utxo_size_inc);
2175 ret_all.
pushKV(
"utxo_increase_actual", utxos - inputs);
2176 ret_all.
pushKV(
"utxo_size_inc_actual", utxo_size_inc_actual);
2183 for (
const std::string& stat : stats) {
2184 const UniValue& value = ret_all[stat];
2188 ret.pushKV(stat, value);
2197 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, std::function<
void()>& interruption_point)
2201 while (cursor->
Valid()) {
2204 if (!cursor->
GetKey(key) || !cursor->
GetValue(coin))
return false;
2205 if (++
count % 8192 == 0) {
2206 interruption_point();
2212 if (
count % 256 == 0) {
2215 scan_progress = (int)(high * 100.0 / 65536.0 + 0.5);
2218 out_results.emplace(key, coin);
2222 scan_progress = 100;
2258 "\"start\" for starting a scan\n" 2259 "\"abort\" for aborting the current scan (returns true when abort was successful)\n" 2260 "\"status\" for progress report (in %) of the current scan" 2273 "Every scan object is either a string descriptor or an object:",
2283 "True if scan will be aborted (not necessarily before this RPC returns), or false if there is no scan to abort" 2286 "when action=='status' and no scan is in progress - possibly already completed",
RPCResult::Type::NONE,
"",
"" 2297 const std::string EXAMPLE_DESCRIPTOR_RAW =
"raw(76a91411b366edfc0a8b66feebae5c2e25a7b6a5d1cf3188ac)#fm24fxxy";
2301 "Scans the unspent transaction output set for entries that match certain output descriptors.\n" 2302 "Examples of output descriptors are:\n" 2303 " addr(<address>) Outputs whose output script corresponds to the specified address (does not include P2PK)\n" 2304 " raw(<hex script>) Outputs whose output script equals the specified hex-encoded bytes\n" 2305 " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n" 2306 " pkh(<pubkey>) P2PKH outputs for the given pubkey\n" 2307 " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n" 2308 " tr(<pubkey>) P2TR\n" 2309 " tr(<pubkey>,{pk(<pubkey>)}) P2TR with single fallback pubkey in tapscript\n" 2310 " rawtr(<pubkey>) P2TR with the specified key as output key rather than inner\n" 2311 " wsh(and_v(v:pk(<pubkey>),after(2))) P2WSH miniscript with mandatory pubkey and a timelock\n" 2312 "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n" 2313 "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n" 2314 "unhardened or hardened child keys.\n" 2315 "In the latter case, a range needs to be specified by below if different from 1000.\n" 2316 "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n",
2339 {
RPCResult::Type::NUM,
"confirmations",
"Number of confirmations of the unspent transaction output when the scan was done"},
2349 HelpExampleCli(
"scantxoutset",
"start \'[\"" + EXAMPLE_DESCRIPTOR_RAW +
"\"]\'") +
2352 HelpExampleRpc(
"scantxoutset",
"\"start\", [\"" + EXAMPLE_DESCRIPTOR_RAW +
"\"]") +
2359 const auto action{
self.Arg<std::string_view>(
"action")};
2360 if (action ==
"status") {
2368 }
else if (action ==
"abort") {
2377 }
else if (action ==
"start") {
2383 if (request.params.size() < 2) {
2387 std::set<CScript> needles;
2388 std::map<CScript, std::string> descriptors;
2398 descriptors.emplace(std::move(
script), std::move(inferred));
2404 std::vector<CTxOut> input_txos;
2405 std::map<COutPoint, Coin> coins;
2408 std::unique_ptr<CCoinsViewCursor> pcursor;
2420 result.pushKV(
"success", res);
2425 for (
const auto& it : coins) {
2427 const Coin& coin = it.second;
2430 input_txos.push_back(txo);
2435 unspent.
pushKV(
"vout", outpoint.
n);
2441 unspent.
pushKV(
"blockhash", coinb_block.GetBlockHash().GetHex());
2446 result.pushKV(
"unspents", std::move(unspents));
2490 for (
const auto& tx : block.vtx) {
2491 if (std::any_of(tx->vout.cbegin(), tx->vout.cend(), [&](
const auto& txout) {
2492 return needles.contains(std::vector<unsigned char>(txout.scriptPubKey.begin(), txout.scriptPubKey.end()));
2498 for (
const auto& txundo : block_undo.vtxundo) {
2499 if (std::any_of(txundo.vprevout.cbegin(), txundo.vprevout.cend(), [&](
const auto& coin) {
2513 "Return relevant blockhashes for given descriptors (requires blockfilterindex).\n" 2514 "This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
2523 {
"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"},
2545 HelpExampleCli(
"scanblocks",
"start '[\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"]' 300000") +
2546 HelpExampleCli(
"scanblocks",
"start '[\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"]' 100 150 basic") +
2548 HelpExampleRpc(
"scanblocks",
"\"start\", [\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"], 300000") +
2549 HelpExampleRpc(
"scanblocks",
"\"start\", [\"addr(bcrt1q4u4nsgk6ug0sqz7r3rj9tykjxrsl0yy4d0wwte)\"], 100, 150, \"basic\"") +
2555 auto action{
self.Arg<std::string_view>(
"action")};
2556 if (action ==
"status") {
2565 }
else if (action ==
"abort") {
2574 }
else if (action ==
"start") {
2579 auto filtertype_name{
self.Arg<std::string_view>(
"filtertype")};
2587 bool filter_false_positives{options.exists(
"filter_false_positives") ? options[
"filter_false_positives"].get_bool() :
false};
2603 start_index = active_chain.
Genesis();
2604 stop_block = active_chain.
Tip();
2605 if (!request.params[2].isNull()) {
2606 start_index = active_chain[request.params[2].getInt<
int>()];
2611 if (!request.params[3].isNull()) {
2612 stop_block = active_chain[request.params[3].getInt<
int>()];
2631 const int amount_per_chunk = 10000;
2632 std::vector<BlockFilter> filters;
2633 int start_block_height = start_index->
nHeight;
2634 const int total_blocks_to_process = stop_block->
nHeight - start_block_height;
2639 bool completed =
true;
2643 node.rpc_interruption_point();
2650 int start_block = !end_range ? start_index->
nHeight : start_index->
nHeight + 1;
2651 end_range = (start_block + amount_per_chunk < stop_block->
nHeight) ?
2658 if (filter.GetFilter().MatchAny(needle_set)) {
2659 if (filter_false_positives) {
2668 blocks.
push_back(filter.GetBlockHash().GetHex());
2672 start_index = end_range;
2675 int blocks_processed = end_range->
nHeight - start_block_height;
2676 if (total_blocks_to_process > 0) {
2684 }
while (start_index != stop_block);
2686 ret.pushKV(
"from_height", start_block_height);
2687 ret.pushKV(
"to_height", start_index->
nHeight);
2688 ret.pushKV(
"relevant_blocks", std::move(blocks));
2689 ret.pushKV(
"completed", completed);
2701 "getdescriptoractivity",
2702 "Get spend and receive activity associated with a set of descriptors for a set of blocks. " 2703 "This command pairs well with the `relevant_blocks` output of `scanblocks()`.\n" 2704 "This call may take several minutes. If you encounter timeouts, try specifying no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
2746 HelpExampleCli(
"getdescriptoractivity",
"'[\"000000000000000000001347062c12fded7c528943c8ce133987e2e2f5a840ee\"]' '[\"addr(bc1qzl6nsgqzu89a66l50cvwapnkw5shh23zarqkw9)\"]'")
2755 struct CompareByHeightAscending {
2761 std::set<const CBlockIndex*, CompareByHeightAscending> blockindexes_sorted;
2775 blockindexes_sorted.insert(pindex);
2779 std::set<CScript> scripts_to_watch;
2787 scripts_to_watch.insert(
script);
2791 const auto AddSpend = [&](
2803 event.pushKV(
"type",
"spend");
2806 event.pushKV(
"blockhash", index->GetBlockHash().ToString());
2807 event.pushKV(
"height", index->nHeight);
2809 event.pushKV(
"spend_txid", tx->GetHash().ToString());
2810 event.pushKV(
"spend_vin", vin);
2811 event.pushKV(
"prevout_txid", txin.prevout.hash.ToString());
2812 event.pushKV(
"prevout_vout", txin.prevout.n);
2813 event.pushKV(
"prevout_spk", spkUv);
2823 event.pushKV(
"type",
"receive");
2826 event.pushKV(
"blockhash", index->GetBlockHash().ToString());
2827 event.pushKV(
"height", index->nHeight);
2829 event.pushKV(
"txid", tx->GetHash().ToString());
2830 event.pushKV(
"vout", vout);
2831 event.pushKV(
"output_spk", spkUv);
2843 for (
const CBlockIndex* blockindex : blockindexes_sorted) {
2847 for (
size_t i = 0; i < block.vtx.size(); ++i) {
2848 const auto& tx = block.vtx.at(i);
2850 if (!tx->IsCoinBase()) {
2852 const auto& txundo = block_undo.
vtxundo.at(i - 1);
2854 for (
size_t vin_idx = 0; vin_idx < tx->vin.size(); ++vin_idx) {
2855 const auto& coin = txundo.vprevout.at(vin_idx);
2856 const auto& txin = tx->vin.at(vin_idx);
2864 for (
size_t vout_idx = 0; vout_idx < tx->vout.size(); ++vout_idx) {
2865 const auto& vout = tx->vout.at(vout_idx);
2866 if (scripts_to_watch.contains(vout.scriptPubKey)) {
2867 activity.
push_back(AddReceive(vout, blockindex, vout_idx, tx));
2873 bool search_mempool =
true;
2874 if (!request.params[2].isNull()) {
2875 search_mempool = request.params[2].get_bool();
2878 if (search_mempool) {
2885 const auto& tx = e.GetSharedTx();
2887 for (
size_t vin_idx = 0; vin_idx < tx->vin.size(); ++vin_idx) {
2890 const auto& txin = tx->vin.at(vin_idx);
2891 std::optional<Coin> coin = coins_view.
GetCoin(txin.prevout);
2899 if (txin.prevout.n >= prev_tx->vout.size()) {
2900 throw std::runtime_error(
"Invalid output index");
2902 const CTxOut&
out = prev_tx->vout[txin.prevout.n];
2903 scriptPubKey =
out.scriptPubKey;
2908 scriptPubKey =
out.scriptPubKey;
2912 if (scripts_to_watch.contains(scriptPubKey)) {
2915 scriptPubKey, value, tx, vin_idx, txin,
nullptr));
2919 for (
size_t vout_idx = 0; vout_idx < tx->vout.size(); ++vout_idx) {
2920 const auto& vout = tx->vout.at(vout_idx);
2921 if (scripts_to_watch.contains(vout.scriptPubKey)) {
2922 activity.
push_back(AddReceive(vout,
nullptr, vout_idx, tx));
2928 ret.pushKV(
"activity", activity);
2938 "Retrieve a BIP 157 content filter for a particular block.\n",
2950 HelpExampleCli(
"getblockfilter",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") +
2951 HelpExampleRpc(
"getblockfilter",
"\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"")
2956 auto filtertype_name{
self.Arg<std::string_view>(
"filtertype")};
2969 bool block_was_connected;
2980 bool index_ready = index->BlockUntilSyncedToCurrentChain();
2987 std::string errmsg =
"Filter not found.";
2989 if (!block_was_connected) {
2991 errmsg +=
" Block was not connected to active chain.";
2992 }
else if (!index_ready) {
2994 errmsg +=
" Block filters are still in the process of being indexed.";
2997 errmsg +=
" This error is unexpected and indicates index corruption.";
3005 ret.pushKV(
"header", filter_header.
GetHex());
3056 "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" 3057 "Unless the \"latest\" type is requested, the node will roll back to the requested height and network activity will be suspended during this process. " 3058 "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" 3059 "This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
3062 {
"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."},
3066 "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.",
3079 {
RPCResult::Type::NUM,
"nchaintx",
"the number of transactions in the chain up to and including the base block"},
3083 HelpExampleCli(
"-rpcclienttimeout=0 dumptxoutset",
"utxo.dat latest") +
3084 HelpExampleCli(
"-rpcclienttimeout=0 dumptxoutset",
"utxo.dat rollback") +
3085 HelpExampleCli(
"-rpcclienttimeout=0 -named dumptxoutset", R
"(utxo.dat rollback=853456)") 3092 const auto snapshot_type{
self.Arg<std::string_view>(
"type")};
3094 if (options.exists(
"rollback")) {
3095 if (!snapshot_type.empty() && snapshot_type !=
"rollback") {
3099 }
else if (snapshot_type ==
"rollback") {
3100 auto snapshot_heights =
node.chainman->GetParams().GetAvailableSnapshotHeights();
3102 auto max_height = std::max_element(snapshot_heights.begin(), snapshot_heights.end());
3104 }
else if (snapshot_type ==
"latest") {
3114 const fs::path temppath = path +
".incomplete";
3119 path.
utf8string() +
" already exists. If you are sure this is what you want, " 3120 "move it out of the way first");
3125 if (afile.IsNull()) {
3128 "Couldn't open file " + temppath.utf8string() +
" for writing.");
3133 std::optional<NetworkDisable> disable_network;
3134 std::optional<TemporaryRollback> temporary_rollback;
3138 if (target_index != tip) {
3141 if (
node.chainman->m_blockman.IsPruneMode()) {
3145 if (first_block.nHeight > target_index->nHeight) {
3159 disable_network.emplace(connman);
3162 invalidate_index =
WITH_LOCK(::
cs_main,
return node.chainman->ActiveChain().Next(target_index));
3163 temporary_rollback.emplace(*
node.chainman, *invalidate_index);
3167 std::unique_ptr<CCoinsViewCursor> cursor;
3177 chainstate = &
node.chainman->ActiveChainstate();
3184 if (target_index != chainstate->m_chain.Tip()) {
3185 LogWarning(
"dumptxoutset failed to roll back to requested height, reverting to tip.\n");
3199 node.rpc_interruption_point);
3200 fs::rename(temppath, path);
3202 result.pushKV(
"path", path.utf8string());
3211 const std::function<
void()>& interruption_point)
3213 std::unique_ptr<CCoinsViewCursor> pcursor;
3214 std::optional<CCoinsStats> maybe_stats;
3254 const std::function<
void()>& interruption_point)
3267 unsigned int iter{0};
3268 size_t written_coins_count{0};
3269 std::vector<std::pair<uint32_t, Coin>> coins;
3278 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) {
3281 for (
const auto& [n, coin] : coins) {
3284 ++written_coins_count;
3289 last_hash = key.
hash;
3290 while (pcursor->
Valid()) {
3291 if (iter % 5000 == 0) interruption_point();
3294 if (key.
hash != last_hash) {
3295 write_coins_to_file(afile, last_hash, coins, written_coins_count);
3296 last_hash = key.
hash;
3299 coins.emplace_back(key.
n, coin);
3304 if (!coins.empty()) {
3305 write_coins_to_file(afile, last_hash, coins, written_coins_count);
3310 if (afile.
fclose() != 0) {
3311 throw std::ios_base::failure(
3316 result.pushKV(
"coins_written", written_coins_count);
3340 node.rpc_interruption_point);
3347 "Load the serialized UTXO set from a file.\n" 3348 "Once this snapshot is loaded, its contents will be " 3349 "deserialized into a second chainstate data structure, which is then used to sync to " 3350 "the network's tip. " 3351 "Meanwhile, the original chainstate will complete the initial block download process in " 3352 "the background, eventually validating up to the block that the snapshot is based upon.\n\n" 3354 "The result is a usable bitcoind instance that is current with the network tip in a " 3355 "matter of minutes rather than hours. UTXO snapshot are typically obtained from " 3356 "third-party sources (HTTP, torrent, etc.) which is reasonable since their " 3357 "contents are always checked by hash.\n\n" 3359 "You can find more information on this process in the `assumeutxo` design " 3360 "document (<https://github.com/bitcoin/bitcoin/blob/master/doc/design/assumeutxo.md>).",
3365 "path to the snapshot file. If relative, will be prefixed by datadir."},
3387 if (afile.IsNull()) {
3390 "Couldn't open file " + path.
utf8string() +
" for reading.");
3396 }
catch (
const std::ios_base::failure& e) {
3401 if (!activation_result) {
3415 result.pushKV(
"coins_loaded", metadata.m_coins_count);
3416 result.pushKV(
"tip_hash", snapshot_index.GetBlockHash().ToString());
3417 result.pushKV(
"base_height", snapshot_index.nHeight);
3431 {
RPCResult::Type::STR_HEX,
"snapshot_blockhash",
true,
"the base block of the snapshot this chainstate is based on, if any"},
3434 {
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."},
3441 "Return information about chainstates.\n",
3463 if (!
cs.m_chain.Tip()) {
3475 data.pushKV(
"coins_db_cache_bytes",
cs.m_coinsdb_cache_size_bytes);
3476 data.pushKV(
"coins_tip_cache_bytes",
cs.m_coinstip_cache_size_bytes);
3477 if (
cs.m_from_snapshot_blockhash) {
3478 data.pushKV(
"snapshot_blockhash",
cs.m_from_snapshot_blockhash->ToString());
3484 obj.
pushKV(
"headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
3487 obj_chainstates.push_back(make_chain_data(*
cs));
3490 obj.
pushKV(
"chainstates", std::move(obj_chainstates));
3531 for (
const auto& c : commands) {
3532 t.appendCommand(c.name, &c);
std::shared_ptr< const CTransaction > CTransactionRef
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
const std::vector< RPCResult > RPCHelpForChainstate
std::vector< RPCResult > ScriptPubKeyDoc()
std::string GetHex() const
void PruneBlockFilesManual(Chainstate &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
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...
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
bool LookupFilter(const CBlockIndex *block_index, BlockFilter &filter_out) const
Get a single filter by block.
static RPCHelpMan syncwithvalidationinterfacequeue()
static const auto scan_result_abort
Interval between compact filter checkpoints.
void push_back(UniValue val)
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES
static RPCHelpMan getblock()
static std::atomic< int > g_scanfilter_progress_height
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
The same as previous option with information about prevouts if available.
arith_uint256 total_new_outputs_ex_coinbase_amount
Total cumulative amount of outputs created up to and including this block.
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
std::array< BIP9Deployment, MAX_VERSION_BITS_DEPLOYMENTS > vDeployments
const std::vector< UniValue > & getValues() const
bool BlockFilterTypeByName(std::string_view name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
std::unique_ptr< CCoinsViewCursor > Cursor() const override
Get a cursor to iterate over the whole state.
static const int WITNESS_SCALE_FACTOR
bool IsPruneMode() const
Whether running in -prune mode.
int64_t GetBlockTime() const
FILE * fopen(const fs::path &p, const char *mode)
UniValue ValueFromAmount(const CAmount amount)
static std::vector< std::byte > GetRawBlockChecked(BlockManager &blockman, const CBlockIndex &blockindex)
CBlockIndex * pprev
pointer to the index of the predecessor of this block
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
static RPCHelpMan getblockfrompeer()
uint256 GetTarget(const CBlockIndex &blockindex, const uint256 pow_limit)
std::string GetChainTypeString() const
Return the chain type string.
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances...
CTxMemPool & EnsureMemPool(const NodeContext &node)
TxVerbosity
Verbose level for block's transaction.
UniValue blockToJSON(BlockManager &blockman, const CBlock &block, const CBlockIndex &tip, const CBlockIndex &blockindex, TxVerbosity verbosity, const uint256 pow_limit)
Block description to JSON.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
An in-memory indexed chain of blocks.
static std::atomic< bool > g_scanfilter_should_abort_scan
BlockFiltersScanReserver()=default
virtual util::Expected< void, std::string > FetchBlock(NodeId peer_id, const CBlockIndex &block_index)=0
Attempt to manually fetch block from a given peer.
NetworkDisable(CConnman &connman)
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
bool index_used
Signals if the coinstatsindex was used to retrieve the statistics.
Comparison function for sorting the getchaintips heads.
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Chainstate &InitializeChainstate(CTxMemPool *mempool) EXCLUSIVE_LOCKS_REQUIRED(util::Result< CBlockIndex * ActivateSnapshot)(AutoFile &coins_file, const node::SnapshotMetadata &metadata, bool in_memory)
Instantiate a new chainstate.
All parent headers found, difficulty matches, timestamp >= median previous.
static constexpr int DEFAULT_CHECKLEVEL
bool MoneyRange(const CAmount &nValue)
CBlockHeader GetBlockHeader() const
#define CHECK_NONFATAL(condition)
Identity function.
int Height() const
Return the maximal height in the chain.
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
CTxOut out
unspent transaction output
bool DeploymentActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache &versionbitscache)
Determine if a deployment is active for the next block.
stage after last reached validness failed
std::optional< CAmount > total_amount
The total amount, or nullopt if an overflow occurred calculating it.
constexpr const std::byte * begin() const
Hash/height pair to help track and identify blocks.
#define LOG_TIME_SECONDS(end_msg)
static const auto scan_result_status_some
const std::string & get_str() const
CTransactionRef get(const Txid &hash) const
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
const UniValue & get_array() const
uint64_t coins_count
The number of coins contained.
undo data available in rev*.dat
#define LIST_CHAIN_NAMES
List of possible chain / network names.
static RPCHelpMan scantxoutset()
bool IsInitialBlockDownload() const noexcept
Check whether we are doing an initial block download (synchronizing from disk or network) ...
CChain m_chain
The current chain of blockheaders we consult and build on.
consteval auto _(util::TranslatedLiteral str)
void TxToUniv(const CTransaction &tx, const uint256 &block_hash, UniValue &entry, bool include_hex, const CTxUndo *txundo, TxVerbosity verbosity, std::function< bool(const CTxOut &)> is_change_func)
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
static int ComputeNextBlockAndDepth(const CBlockIndex &tip, const CBlockIndex &blockindex, const CBlockIndex *&next)
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
GetCoin, returning whether it exists and is not spent.
static std::atomic< int > g_scan_progress
RAII object to prevent concurrency issue when scanning the txout set.
Non-refcounted RAII wrapper for FILE*.
static int32_t GetTransactionWeight(const CTransaction &tx)
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
static RPCHelpMan loadtxoutset()
void ForceFlushStateToDisk(bool wipe_cache=true)
Flush all changes to disk.
arith_uint256 total_coinbase_amount
Total cumulative amount of coinbase outputs 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...
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
bool isSpent(const COutPoint &outpoint) const
void reserve(size_t new_cap)
const std::vector< CTxIn > vin
Invalid, missing or duplicate parameter.
static RPCHelpMan getdescriptoractivity()
RAII class that temporarily rolls back the local chain in it's constructor and rolls it forward again...
RPCHelpMan getblockchaininfo()
VersionBitsCache m_versionbitscache
Track versionbit status.
~BlockFiltersScanReserver()
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Minimal stream for reading from an existing byte array by std::span.
bool DeploymentEnabled(const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is enabled (can ever be active)
std::string SysErrorString(int err)
Return system error string from errno value.
CoinsViewScanReserver()=default
static RPCHelpMan getchaintxstats()
const RPCResult getblock_vin
int64_t CAmount
Amount in satoshis (Can be negative)
CAmount total_unspendables_unclaimed_rewards
Total cumulative amount of coins lost due to unclaimed miner rewards up to and including this block...
CAmount total_unspendables_bip30
The two unspendable coinbase outputs total amount caused by BIP30.
static T CalculateTruncatedMedian(std::vector< T > &scores)
std::string GetAllOutputTypes()
Gets all existing output types formatted for RPC help sections.
virtual bool GetValue(Coin &coin) const =0
uint256 GetBlockHash() const
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={})
arith_uint256 total_prevout_spent_amount
Total cumulative amount of prevouts spent up to and including this block.
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.
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
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...
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
static RPCHelpMan getblockfilter()
uint64_t PruneAfterHeight() const
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
Special type that is a STR with only hex chars.
NodeContext struct containing references to chain state and connection state.
bool IsBIP30Repeat(const CBlockIndex &block_index)
Identifies blocks that overwrote an existing coinbase output in the UTXO set (see BIP30) ...
static bool exists(const path &p)
uint256 powLimit
Proof of work parameters.
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
Interface giving clients (RPC, Stratum v2 Template Provider in the future) ability to create block te...
static std::atomic< bool > g_scan_in_progress
UniValue JSONRPCError(int code, const std::string &message)
void ReconsiderBlock(ChainstateManager &chainman, uint256 block_hash)
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
bool operator()(const CBlockIndex *a, const CBlockIndex *b) const
Special string with only hex chars.
virtual bool Valid() const =0
Chainstate stores and provides an API to update our local knowledge of the current best chain...
static RPCHelpMan waitfornewblock()
Include TXID, inputs, outputs, and other common block's transaction information.
static void SoftForkDescPushBack(const CBlockIndex *blockindex, UniValue &softforks, const ChainstateManager &chainman, Consensus::BuriedDeployment dep)
static const CBlockIndex * ParseHashOrHeight(const UniValue ¶m, ChainstateManager &chainman)
void RegisterBlockchainRPCCommands(CRPCTable &t)
Abstract view on the open txout dataset.
UniValue blockheaderToJSON(const CBlockIndex &tip, const CBlockIndex &blockindex, const uint256 pow_limit)
Block header to JSON.
An input of a transaction.
uint64_t m_chain_tx_count
(memory only) Number of transactions in the chain up to and including this block. ...
Double ended buffer combining vector and stream-like interfaces.
int DeploymentHeight(BuriedDeployment dep) const
std::string ToString() const
static RPCHelpMan dumptxoutset()
Serialize the UTXO set to a file for loading elsewhere.
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache)
Get a single filter header by block.
static RPCHelpMan getblockheader()
Complete block filter struct as defined in BIP 157.
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).
Special array that has a fixed number of entries.
static RPCHelpMan getchainstates()
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
kernel::Notifications & GetNotifications() const
int64_t size()
Return the size of the file.
int64_t nPowTargetSpacing
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
static const auto output_descriptor_obj
uint64_t GetSerializeSize(const T &t)
interfaces::Mining & EnsureMining(const NodeContext &node)
static RPCHelpMan getblockstats()
const Consensus::Params & GetConsensus() const
const std::string CURRENCY_UNIT
ReadRawBlockResult ReadRawBlock(const FlatFilePos &pos, std::optional< std::pair< size_t, size_t >> block_part=std::nullopt) const
SnapshotCompletionResult MaybeValidateSnapshot(Chainstate &validated_cs, Chainstate &unvalidated_cs) EXCLUSIVE_LOCKS_REQUIRED(Chainstate & CurrentChainstate() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Try to validate an assumeutxo snapshot by using a validated historical chainstate targeted at the sna...
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(
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...
General application defined errors.
std::string DefaultHint
Hint for default value.
void push_backV(const std::vector< UniValue > &vec)
Every block in the chain has been validated.
void SetNetworkActive(bool active)
bool GetNetworkActive() const
An output of a transaction.
std::string ToString() const
CoinStatsHashType ParseHashType(std::string_view hash_type_input)
RAII class that disables the network in its constructor and enables it in its destructor.
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
static std::atomic< bool > g_scanfilter_in_progress
static const auto scan_result_status_none
An outpoint - a combination of a transaction hash and an index n into its vout.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
bool IsDeprecatedRPCEnabled(const std::string &method)
Special numeric to denote unix epoch time.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
UniValue Default
Default constant value.
256-bit unsigned big integer.
int64_t GetMedianTimePast() const
static RPCHelpMan getdifficulty()
static RPCHelpMan invalidateblock()
std::unordered_set< Element, ByteVectorHash > ElementSet
virtual bool GetKey(COutPoint &key) const =0
UniValue GetWarningsForRpc(const Warnings &warnings, bool use_deprecated)
RPC helper function that wraps warnings.GetMessages().
node::BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
static RPCHelpMan getblockcount()
script_verify_flags GetBlockScriptFlags(const CBlockIndex &block_index, const ChainstateManager &chainman)
void ScriptToUniv(const CScript &script, UniValue &out, bool include_hex, bool include_address, const SigningProvider *provider)
void InvalidateBlock(ChainstateManager &chainman, const uint256 block_hash)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Special type that is a NUM or [NUM,NUM].
int32_t nVersion
block header
const CChainParams & GetParams() const
#define LogDebug(category,...)
Optional argument for which the default value is omitted from help text for one of two reasons: ...
static const auto scan_action_arg_desc
static std::atomic< bool > g_should_abort_scan
ChainType GetChainType() const
Return the chain type.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static RPCHelpMan waitforblock()
std::vector< CTransactionRef > vtx
std::string utf8string() const
Return a UTF-8 representation of the path as a std::string, for compatibility with code using std::st...
static const auto scan_objects_arg_desc
static CBlock GetBlockChecked(BlockManager &blockman, const CBlockIndex &blockindex)
Detailed status of an enabled BIP9 deployment.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
static bool SetHasKeys(const std::set< T > &set)
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.
int ParseVerbosity(const UniValue &arg, int default_verbosity, bool allow_bool)
Parses verbosity from provided UniValue.
Only TXID for each block's transaction.
Special string to represent a floating point amount.
static RPCHelpMan gettxout()
static RPCHelpMan verifychain()
The block chain is a tree shaped structure starting with the genesis block at the root...
void pushKV(std::string key, UniValue val)
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
static transaction_identifier FromUint256(const uint256 &id)
uint256 ParseHashV(const UniValue &v, std::string_view name)
Utilities: convert hex-encoded Values (throws error if not hex).
static const signed int DEFAULT_CHECKBLOCKS
Undo information for a CTransaction.
uint64_t GetLow64() const
ChainstateManager & EnsureChainman(const NodeContext &node)
static bool ComputeUTXOStats(CCoinsView *view, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point, std::unique_ptr< CCoinsViewCursor > pcursor)
Calculate statistics about the unspent transaction output set.
const MessageStartChars & MessageStart() const
virtual std::optional< BlockRef > getTip()=0
Returns the hash and height for the tip of this chain.
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
BIP9Info Info(const CBlockIndex &block_index, const Consensus::Params ¶ms, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
std::vector< uint8_t > signet_challenge
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
static RPCHelpMan preciousblock()
std::string GetHex() const
static constexpr size_t PER_UTXO_OVERHEAD
static std::string PathToString(const path &path)
Convert path object to a byte string.
static RPCHelpMan waitforblockheight()
static RPCHelpMan gettxoutsetinfo()
ArgsManager & EnsureAnyArgsman(const std::any &context)
const UniValue NullUniValue
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
static RPCHelpMan pruneblockchain()
#define AssertLockNotHeld(cs)
bool ReadBlock(CBlock &block, const FlatFilePos &pos, const std::optional< uint256 > &expected_hash) const
Functions for disk access for blocks.
bilingual_str ErrorString(const Result< T > &result)
TemporaryRollback(ChainstateManager &chainman, const CBlockIndex &index)
static CBlockUndo GetUndoChecked(BlockManager &blockman, const CBlockIndex &blockindex)
RPCHelpMan getdeploymentinfo()
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 ...
static RPCHelpMan reconsiderblock()
PeerManager & EnsurePeerman(const NodeContext &node)
const CBlockIndex & m_invalidate_index
unsigned char * UCharCast(char *c)
ChainstateManager & m_chainman
static RPCHelpMan getchaintips()
bool IsValid(enum BlockStatus nUpTo) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
std::unique_ptr< CoinStatsIndex > g_coin_stats_index
The global UTXO set hash object.
double GetDifficulty(const CBlockIndex &blockindex)
Get the difficulty of the net wrt to the given block index.
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
UniValue coinbaseTxToJSON(const CTransaction &coinbase_tx)
Serialize coinbase transaction metadata.
static path u8path(std::string_view utf8_str)
std::string GetHex() const
Hex encoding of the number (with the most significant digits first).
static bool CheckBlockFilterMatches(BlockManager &blockman, const CBlockIndex &blockindex, const GCSFilter::ElementSet &needles)
CAmount total_unspendables_genesis_block
The unspendable coinbase amount from the genesis block.
The basic transaction that is broadcasted on the network and contained in blocks. ...
static std::atomic< int > g_scanfilter_progress
RAII object to prevent concurrency issue when scanning blockfilters.
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
const std::vector< unsigned char > & GetEncodedFilter() const LIFETIMEBOUND
const Consensus::Params & GetConsensus() const
void CheckBlockDataAvailability(BlockManager &blockman, const CBlockIndex &blockindex, bool check_for_undo)
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
Special dictionary with keys that are not literals.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
full block available in blk*.dat
std::vector< std::string > GetScriptFlagNames(script_verify_flags flags)
virtual std::optional< BlockRef > waitTipChanged(uint256 current_tip, MillisecondsDouble timeout=MillisecondsDouble::max())=0
Waits for the connected tip to change.
ChainstateManager & EnsureAnyChainman(const std::any &context)
Chainstate * HistoricalChainstate() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Return historical chainstate targeting a specific block, if any.
std::vector< CTxUndo > vtxundo
static int64_t GetBlockWeight(const CBlock &block)
static RPCHelpMan scanblocks()
uint64_t nTransactionOutputs
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
uint64_t GetPruneTarget() const
Attempt to stay below this number of bytes of block files.
bool PreciousBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(void SetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(voi ResetBlockFailureFlags)(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as precious and reorganize.
std::tuple< std::unique_ptr< CCoinsViewCursor >, CCoinsStats, const CBlockIndex * > PrepareUTXOSnapshot(Chainstate &chainstate, const std::function< void()> &interruption_point)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
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.
CCoinsView that brings transactions from a mempool into view.
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.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
#define T(expected, seed, data)
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
BuriedDeployment
A buried deployment is one where the height of the activation has been hardcoded into the client impl...
unsigned int nTx
Number of transactions in this block.
std::vector< CTxMemPoolEntryRef > entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs)
NodeContext & EnsureAnyNodeContext(const std::any &context)
static RPCHelpMan getblockhash()
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
ArgsManager & EnsureArgsman(const NodeContext &node)
Error parsing or validating structure in raw format.
CConnman & EnsureConnman(const NodeContext &node)
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency...
static constexpr TransactionSerParams TX_WITH_WITNESS
static constexpr TransactionSerParams TX_NO_WITNESS
Special type to denote elision (...)
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.
std::string DeploymentName(Consensus::BuriedDeployment dep)
bool ReadBlockUndo(CBlockUndo &blockundo, const CBlockIndex &index) const
Cursor for iterating over CoinsView state.
static RPCHelpMan getbestblockhash()