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.
251block.hashMerkleRoot = block.vtx.back()->GetHash().ToUint256();252assert(block.vtx.back()->IsCoinBase());253assert(GetSerializeSize(TX_NO_WITNESS(block.vtx.back())) == 64);254}255BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));256}258{259// Test merkle root malleation261// Pseudo code to mine transactions tx{1,2,3}:262//263// ```264// loop {265// tx1 = random_tx()266// tx2 = random_tx()267// tx3 = deserialize_tx(txid(tx1) || txid(tx2));268// if serialized_size_without_witness(tx3) == 64 {269// print(hex(tx3))270// break271// }272// }273// ```274//275// The `random_tx` function used to mine the txs below simply created276// empty transactions with a random version field.277CMutableTransaction tx1;278BOOST_CHECK(DecodeHexTx(tx1, "ff204bd0000000000000", /*try_no_witness=*/true, /*try_witness=*/false));279CMutableTransaction tx2;280BOOST_CHECK(DecodeHexTx(tx2, "8ae53c92000000000000", /*try_no_witness=*/true, /*try_witness=*/false));281CMutableTransaction tx3;282BOOST_CHECK(DecodeHexTx(tx3, "cdaf22d00002c6a7f848f8ae4d30054e61dcf3303d6fe01d282163341f06feecc10032b3160fcab87bdfe3ecfb769206ef2d991b92f8a268e423a6ef4d485f06", /*try_no_witness=*/true, /*try_witness=*/false));283{284// Verify that double_sha256(txid1||txid2) == txid3285HashWriter hasher;286hasher.write(tx1.GetHash());287hasher.write(tx2.GetHash());288assert(hasher.GetHash() == tx3.GetHash().ToUint256());289// Verify that tx3 is 64 bytes in size (without witness).290assert(GetSerializeSize(TX_NO_WITNESS(tx3)) == 64);291}293CBlock block;294block.vtx.push_back(MakeTransactionRef(tx1));295block.vtx.push_back(MakeTransactionRef(tx2));296uint256 merkle_root = block.hashMerkleRoot = BlockMerkleRoot(block);297BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));299// Mutate the block by replacing the two transactions with one 64-byte300// transaction that serializes into the concatenation of the txids of301// the transactions in the unmutated block.302block.vtx.clear();303block.vtx.push_back(MakeTransactionRef(tx3));304BOOST_CHECK(!block.vtx.back()->IsCoinBase());305BOOST_CHECK(BlockMerkleRoot(block) == merkle_root);306BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));307}309{310CBlock block;311block.vtx.push_back(create_coinbase_tx(/*include_witness=*/true));312{313CMutableTransaction mtx;314mtx.vin.resize(1);315mtx.vin[0].scriptWitness.stack.resize(1);316mtx.vin[0].scriptWitness.stack[0] = {0};317block.vtx.push_back(MakeTransactionRef(mtx));318}319block.hashMerkleRoot = BlockMerkleRoot(block);320// Block with witnesses is considered mutated if the witness commitment321// is not validated.322BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));323// Block with invalid witness commitment is considered mutated.324BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));326// Block with valid commitment is not mutated327{328auto commitment{BlockWitnessMerkleRoot(block)};329insert_witness_commitment(block, commitment);330block.hashMerkleRoot = BlockMerkleRoot(block);331}332BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/true));334// Malleating witnesses should be caught by `IsBlockMutated`.335{336CMutableTransaction mtx{*block.vtx[1]};337assert(!mtx.vin[0].scriptWitness.stack[0].empty());338++mtx.vin[0].scriptWitness.stack[0][0];339block.vtx[1] = MakeTransactionRef(mtx);340}341// Without also updating the witness commitment, the merkle root should342// not change when changing one of the witnesses.343BOOST_CHECK(block.hashMerkleRoot == BlockMerkleRoot(block));344BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));345{346auto commitment{BlockWitnessMerkleRoot(block)};347insert_witness_commitment(block, commitment);348block.hashMerkleRoot = BlockMerkleRoot(block);349}350BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/true));352// Test malleating the coinbase witness reserved value353{354CMutableTransaction mtx{*block.vtx[0]};355mtx.vin[0].scriptWitness.stack.resize(0);356block.vtx[0] = MakeTransactionRef(mtx);357block.hashMerkleRoot = BlockMerkleRoot(block);358}359BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));360}361}363BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.