Inside Bitcoin
Opening the selected file…
Inside Bitcoin
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.
4001block.vtx[0] = MakeTransactionRef(std::move(tx));4002}4003}4005void ChainstateManager::GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev) const4006{4007int commitpos = GetWitnessCommitmentIndex(block);4008std::vector<unsigned char> ret(32, 0x00);4009if (commitpos == NO_WITNESS_COMMITMENT) {4010uint256 witnessroot = BlockWitnessMerkleRoot(block);4011CHash256().Write(witnessroot).Write(ret).Finalize(witnessroot);4012CTxOut out;4013out.nValue = 0;4014out.scriptPubKey.resize(MINIMUM_WITNESS_COMMITMENT);4015out.scriptPubKey[0] = OP_RETURN;4016out.scriptPubKey[1] = 0x24;4017out.scriptPubKey[2] = 0xaa;4018out.scriptPubKey[3] = 0x21;4019out.scriptPubKey[4] = 0xa9;4020out.scriptPubKey[5] = 0xed;4021memcpy(&out.scriptPubKey[6], witnessroot.begin(), 32);4022CMutableTransaction tx(*block.vtx[0]);4023tx.vout.push_back(out);4024block.vtx[0] = MakeTransactionRef(std::move(tx));4025}4026UpdateUncommittedBlockStructures(block, pindexPrev);4027}4029bool HasValidProofOfWork(std::span<const CBlockHeader> headers, const Consensus::Params& consensusParams)4030{4031return std::ranges::all_of(headers,4032[&](const auto& header) { return CheckProofOfWork(header.GetHash(), header.nBits, consensusParams); });4033}4035bool IsBlockMutated(const CBlock& block, bool check_witness_root)4036{4037BlockValidationState state;4038if (!CheckMerkleRoot(block, state)) {4039LogDebug(BCLog::VALIDATION, "Block mutated: %s\n", state.ToString());4040return true;4041}4043if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {4044// Consider the block mutated if any transaction is 64 bytes in size (see 3.14045// in "Weaknesses in Bitcoin’s Merkle Root Construction":4046// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20190225/a27d8837/attachment-0001.pdf).4047//4048// Note: This is not a consensus change as this only applies to blocks that4049// don't have a coinbase transaction and would therefore already be invalid.4050return std::any_of(block.vtx.begin(), block.vtx.end(),4051[](auto& tx) { return GetSerializeSize(TX_NO_WITNESS(tx)) == 64; });4052} else {4053// Theoretically it is still possible for a block with a 64 byte4054// coinbase transaction to be mutated but we neglect that possibility4055// here as it requires at least 224 bits of work.4056}4058if (!CheckWitnessMalleation(block, check_witness_root, state)) {4059LogDebug(BCLog::VALIDATION, "Block mutated: %s\n", state.ToString());4060return true;4061}4063return false;4064}4066arith_uint256 CalculateClaimedHeadersWork(std::span<const CBlockHeader> headers)4067{4068arith_uint256 total_work{0};4069for (const CBlockHeader& header : headers) {4070total_work += GetBlockProof(header);4071}4072return total_work;4073}4075/** Context-dependent validity checks.4076* By "context", we mean only the previous block headers, but not the UTXO4077* set; UTXO-related validity checks are done in ConnectBlock().4078* NOTE: This function is not currently invoked by ConnectBlock(), so we4079* should consider upgrade issues if we change which consensus rules are4080* enforced in this function (eg by adding a new consensus rule). See comment4081* in ConnectBlock().4082* Note that -reindex-chainstate skips the validation that happens here!4083*4084* NOTE: failing to check the header's height against the last checkpoint's opened a DoS vector between4085* v0.12 and v0.15 (when no additional protection was in place) whereby an attacker could unboundedly4086* grow our in-memory block index. See https://bitcoincore.org/en/2024/07/03/disclose-header-spam.4087*/4088static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)4089{4090AssertLockHeld(::cs_main);4091assert(pindexPrev != nullptr);4092const int nHeight = pindexPrev->nHeight + 1;4094// Check proof of work4095const Consensus::Params& consensusParams = chainman.GetConsensus();4096if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))4097return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");4099// Check timestamp against prev4100if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())4101return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", "block's timestamp is too early");4103// Testnet4 and regtest only: Check timestamp against prev for difficulty-adjustment4104// blocks to prevent timewarp attacks (see https://github.com/bitcoin/bitcoin/pull/15482).4105if (consensusParams.enforce_BIP94) {4106// Check timestamp for the first block of each difficulty adjustment4107// interval, except the genesis block.4108if (nHeight % consensusParams.DifficultyAdjustmentInterval() == 0) {4109if (block.GetBlockTime() < pindexPrev->GetBlockTime() - MAX_TIMEWARP) {4110return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-timewarp-attack", "block's timestamp is too early on diff adjustment block");4111}4112}4113}4115// Check timestamp4116if (block.Time() > NodeClock::now() + std::chrono::seconds{MAX_FUTURE_BLOCK_TIME}) {4117return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");4118}4120// Reject blocks with outdated version4121if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB)) ||4122(block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_DERSIG)) ||4123(block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CLTV))) {4124return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),4125strprintf("rejected nVersion=0x%08x block", block.nVersion));4126}4128return true;4129}4131/** NOTE: This function is not currently invoked by ConnectBlock(), so we4132* should consider upgrade issues if we change which consensus rules are4133* enforced in this function (eg by adding a new consensus rule). See comment4134* in ConnectBlock().4135* Note that -reindex-chainstate skips the validation that happens here!4136*/4137static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev)4138{4139const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;4141// Enforce BIP113 (Median Time Past).4142bool enforce_locktime_median_time_past{false};4143if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CSV)) {4144assert(pindexPrev != nullptr);4145enforce_locktime_median_time_past = true;4146}4148const int64_t nLockTimeCutoff{enforce_locktime_median_time_past ?4149pindexPrev->GetMedianTimePast() :4150block.GetBlockTime()};4152// Check that all transactions are finalized4153for (const auto& tx : block.vtx) {4154if (!IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {4155return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal", "non-final transaction");4156}4157}4159// Enforce rule that the coinbase starts with serialized block height4160if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB))4161{4162CScript expect = CScript() << nHeight;4163if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||4164!std::equal(expect.begin(), expect.end(), block.vtx[0]->vin[0].scriptSig.begin())) {4165return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-height", "block height mismatch in coinbase");4166}4167}4169// Validation for witness commitments.4170// * We compute the witness hash (which is the hash including witnesses) of all the block's transactions, except the4171// coinbase (where 0x0000....0000 is used instead).4172// * The coinbase scriptWitness is a stack of a single 32-byte vector, containing a witness reserved value (unconstrained).4173// * We build a merkle tree with all those witness hashes as leaves (similar to the hashMerkleRoot in the block header).4174// * There must be at least one output whose scriptPubKey is a single 36-byte push, the first 4 bytes of which are4175// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are4176// multiple, the last one is used.4177if (!CheckWitnessMalleation(block, DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT), state)) {4178return false;4179}4181// After the coinbase witness reserved value and commitment are verified,4182// we can check if the block weight passes (before we've checked the4183// coinbase witness, it would be possible for the weight to be too4184// large by filling up the coinbase witness, which doesn't change4185// the block hash, so we couldn't mark the block as permanently4186// failed).4187if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) {4188return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-weight", strprintf("%s : weight limit failed", __func__));4189}4191return true;4192}4194bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, CBlockIndex** ppindex, bool min_pow_checked)4195{4196AssertLockHeld(cs_main);4198// Check for duplicate4199uint256 hash = block.GetHash();4200BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};4201if (hash != GetConsensus().hashGenesisBlock) {4202if (miSelf != m_blockman.m_block_index.end()) {4203// Block header is already known.4204CBlockIndex* pindex = &(miSelf->second);4205if (ppindex)4206*ppindex = pindex;4207if (pindex->nStatus & BLOCK_FAILED_VALID) {4208LogDebug(BCLog::VALIDATION, "%s: block %s is marked invalid\n", __func__, hash.ToString());4209return state.Invalid(BlockValidationResult::BLOCK_CACHED_INVALID, "duplicate-invalid",4210strprintf("block %s was previously marked invalid", hash.ToString()));4211}4212return true;4213}4215if (!CheckBlockHeader(block, state, GetConsensus())) {4216LogDebug(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());4217return false;4218}4220// Get prev block index4221CBlockIndex* pindexPrev = nullptr;4222BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)};4223if (mi == m_blockman.m_block_index.end()) {4224LogDebug(BCLog::VALIDATION, "header %s has prev block not found: %s\n", hash.ToString(), block.hashPrevBlock.ToString());4225return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found");4226}4227pindexPrev = &((*mi).second);4228if (pindexPrev->nStatus & BLOCK_FAILED_VALID) {4229LogDebug(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString());4230return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");4231}4232if (!ContextualCheckBlockHeader(block, state, *this, pindexPrev)) {4233LogDebug(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());4234return false;4235}4236}4237if (!min_pow_checked) {4238LogDebug(BCLog::VALIDATION, "%s: not adding new block header %s, missing anti-dos proof-of-work validation\n", __func__, hash.ToString());4239return state.Invalid(BlockValidationResult::BLOCK_HEADER_LOW_WORK, "too-little-chainwork");4240}4241CBlockIndex* pindex{m_blockman.AddToBlockIndex(block, m_best_header)};4243if (ppindex)4244*ppindex = pindex;4246return true;4247}4249// Exposed wrapper for AcceptBlockHeader4250bool ChainstateManager::ProcessNewBlockHeaders(std::span<const CBlockHeader> headers, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex)