Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <rpc/blockchain.h>7#include <rpc/register.h> // IWYU pragma: associated9#include <arith_uint256.h>10#include <blockfilter.h>11#include <chain.h>12#include <chainparams.h>13#include <chainparamsbase.h>14#include <coins.h>15#include <common/args.h>16#include <consensus/amount.h>17#include <consensus/consensus.h>18#include <consensus/params.h>19#include <consensus/validation.h>20#include <core_io.h>21#include <crypto/hex_base.h>22#include <dbwrapper.h>23#include <deploymentinfo.h>24#include <flatfile.h>25#include <index/base.h>26#include <index/blockfilterindex.h>27#include <index/coinstatsindex.h>28#include <interfaces/mining.h>29#include <interfaces/types.h>30#include <kernel/coinstats.h>31#include <logging/timer.h>32#include <net.h>33#include <net_processing.h>34#include <node/blockstorage.h>35#include <node/context.h>36#include <node/utxo_snapshot.h>37#include <node/warnings.h>38#include <policy/feerate.h>39#include <prevector.h>40#include <primitives/block.h>41#include <primitives/transaction.h>42#include <protocol.h>43#include <rpc/protocol.h>44#include <rpc/rawtransaction_util.h>45#include <rpc/request.h>46#include <rpc/server.h>47#include <rpc/server_util.h>48#include <rpc/util.h>49#include <script/descriptor.h>50#include <script/interpreter.h>51#include <script/script.h>52#include <script/signingprovider.h>53#include <serialize.h>54#include <span.h>55#include <streams.h>56#include <sync.h>57#include <tinyformat.h>58#include <txdb.h>59#include <txmempool.h>60#include <uint256.h>61#include <undo.h>62#include <univalue.h>63#include <util/chaintype.h>64#include <util/check.h>65#include <util/expected.h>66#include <util/fs.h>67#include <util/log.h>68#include <util/result.h>69#include <util/string.h>70#include <util/syserror.h>71#include <util/time.h>72#include <util/translation.h>73#include <validation.h>74#include <validationinterface.h>75#include <versionbits.h>77#include <algorithm>78#include <array>79#include <atomic>80#include <cerrno>81#include <compare>82#include <cstddef>83#include <cstdint>84#include <cstdio>85#include <functional>86#include <ios>87#include <map>88#include <memory>89#include <optional>90#include <ratio>91#include <set>92#include <span>93#include <stdexcept>94#include <string>95#include <string_view>96#include <tuple>97#include <vector>99using kernel::CCoinsStats;100using kernel::CoinStatsHashType;102using interfaces::BlockRef;103using interfaces::Mining;104using node::BlockManager;105using node::NodeContext;106using node::SnapshotMetadata;107using util::MakeUnorderedList;109std::tuple<std::unique_ptr<CCoinsViewCursor>, CCoinsStats, const CBlockIndex*>110PrepareUTXOSnapshot(111Chainstate& chainstate,112const std::function<void()>& interruption_point = {})113EXCLUSIVE_LOCKS_REQUIRED(::cs_main);115UniValue WriteUTXOSnapshot(116Chainstate& chainstate,117CCoinsViewCursor* pcursor,118CCoinsStats* maybe_stats,119const CBlockIndex* tip,120AutoFile&& afile,121const fs::path& path,122const fs::path& temppath,123const std::function<void()>& interruption_point = {});125UniValue CreateRolledBackUTXOSnapshot(126NodeContext& node,127Chainstate& chainstate,128const CBlockIndex* target,129AutoFile&& afile,130const fs::path& path,131const fs::path& tmppath,132bool in_memory);134/* Calculate the difficulty for a given block index.135*/136double GetDifficulty(const CBlockIndex& blockindex)137{138int nShift = (blockindex.nBits >> 24) & 0xff;139double dDiff =140(double)0x0000ffff / (double)(blockindex.nBits & 0x00ffffff);142while (nShift < 29)143{144dDiff *= 256.0;145nShift++;146}147while (nShift > 29)148{149dDiff /= 256.0;150nShift--;151}153return dDiff;154}156static int ComputeNextBlockAndDepth(const CBlockIndex& tip, const CBlockIndex& blockindex, const CBlockIndex*& next)157{158next = tip.GetAncestor(blockindex.nHeight + 1);159if (next && next->pprev == &blockindex) {160return tip.nHeight - blockindex.nHeight + 1;161}162next = nullptr;163return &blockindex == &tip ? 1 : -1;164}166static const CBlockIndex* ParseHashOrHeight(const UniValue& param, ChainstateManager& chainman)167{168LOCK(::cs_main);169CChain& active_chain = chainman.ActiveChain();171if (param.isNum()) {172const int height{param.getInt<int>()};173if (height < 0) {174throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d is negative", height));175}176const int current_tip{active_chain.Height()};177if (height > current_tip) {178throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d after current tip %d", height, current_tip));179}181return active_chain[height];182} else {183const uint256 hash{ParseHashV(param, "hash_or_height")};184const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);186if (!pindex) {187throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");188}190return pindex;191}192}194UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex, const uint256 pow_limit)195{196// Serialize passed information without accessing chain state of the active chain!197AssertLockNotHeld(cs_main); // For performance reasons199UniValue result(UniValue::VOBJ);200result.pushKV("hash", blockindex.GetBlockHash().GetHex());201const CBlockIndex* pnext;202int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);203result.pushKV("confirmations", confirmations);204result.pushKV("height", blockindex.nHeight);205result.pushKV("version", blockindex.nVersion);206result.pushKV("versionHex", strprintf("%08x", blockindex.nVersion));207result.pushKV("merkleroot", blockindex.hashMerkleRoot.GetHex());208result.pushKV("time", blockindex.nTime);209result.pushKV("mediantime", blockindex.GetMedianTimePast());210result.pushKV("nonce", blockindex.nNonce);211result.pushKV("bits", strprintf("%08x", blockindex.nBits));212result.pushKV("target", GetTarget(blockindex, pow_limit).GetHex());213result.pushKV("difficulty", GetDifficulty(blockindex));214result.pushKV("chainwork", blockindex.nChainWork.GetHex());215result.pushKV("nTx", blockindex.nTx);217if (blockindex.pprev)218result.pushKV("previousblockhash", blockindex.pprev->GetBlockHash().GetHex());219if (pnext)220result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());221return result;222}224/** Serialize coinbase transaction metadata */225UniValue coinbaseTxToJSON(const CTransaction& coinbase_tx)226{227CHECK_NONFATAL(!coinbase_tx.vin.empty());228const CTxIn& vin_0{coinbase_tx.vin[0]};229UniValue coinbase_tx_obj(UniValue::VOBJ);230coinbase_tx_obj.pushKV("version", coinbase_tx.version);231coinbase_tx_obj.pushKV("locktime", coinbase_tx.nLockTime);232coinbase_tx_obj.pushKV("sequence", vin_0.nSequence);233coinbase_tx_obj.pushKV("coinbase", HexStr(vin_0.scriptSig));234const auto& witness_stack{vin_0.scriptWitness.stack};235if (!witness_stack.empty()) {236CHECK_NONFATAL(witness_stack.size() == 1);237coinbase_tx_obj.pushKV("witness", HexStr(witness_stack[0]));238}239return coinbase_tx_obj;240}242UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity, const uint256 pow_limit)243{244UniValue result = blockheaderToJSON(tip, blockindex, pow_limit);246result.pushKV("strippedsize", ::GetSerializeSize(TX_NO_WITNESS(block)));247result.pushKV("size", ::GetSerializeSize(TX_WITH_WITNESS(block)));248result.pushKV("weight", ::GetBlockWeight(block));250CHECK_NONFATAL(!block.vtx.empty());