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.
501missing_ancestor_block.hashPrevBlock = 123502assert_raises_rpc_error(-25, 'Must submit previous header', lambda: node.submitheader(hexdata=super(CBlock, missing_ancestor_block).serialize().hex()))504block.nTime += 1505block.solve()507def chain_tip(b_hash, *, status='headers-only', branchlen=1):508return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status}510assert chain_tip(block.hash_hex) not in node.getchaintips()511node.submitheader(hexdata=block.serialize().hex())512assert chain_tip(block.hash_hex) in node.getchaintips()513node.submitheader(hexdata=CBlockHeader(block).serialize().hex()) # Noop514assert chain_tip(block.hash_hex) in node.getchaintips()516bad_block_root = copy.deepcopy(block)517bad_block_root.hashMerkleRoot += 2518bad_block_root.solve()519assert chain_tip(bad_block_root.hash_hex) not in node.getchaintips()520node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex())521assert chain_tip(bad_block_root.hash_hex) in node.getchaintips()522# Should still reject invalid blocks, even if we have the header:523assert_equal(node.submitblock(hexdata=bad_block_root.serialize().hex()), 'bad-txnmrklroot')524assert_equal(node.submitblock(hexdata=bad_block_root.serialize().hex()), 'bad-txnmrklroot')525assert chain_tip(bad_block_root.hash_hex) in node.getchaintips()526# We know the header for this invalid block, so should just return early without error:527node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex())528assert chain_tip(bad_block_root.hash_hex) in node.getchaintips()530bad_block_lock = copy.deepcopy(block)531bad_block_lock.vtx[0].nLockTime = 2**32 - 1532bad_block_lock.hashMerkleRoot = bad_block_lock.calc_merkle_root()533bad_block_lock.solve()534assert_equal(node.submitblock(hexdata=bad_block_lock.serialize().hex()), 'bad-txns-nonfinal')535assert_equal(node.submitblock(hexdata=bad_block_lock.serialize().hex()), 'duplicate-invalid')536# Build a "good" block on top of the submitted bad block537bad_block2 = copy.deepcopy(block)538bad_block2.hashPrevBlock = bad_block_lock.hash_int539bad_block2.solve()540assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=CBlockHeader(bad_block2).serialize().hex()))542# Should reject invalid header right away543bad_block_time = copy.deepcopy(block)544bad_block_time.nTime = 1545bad_block_time.solve()546assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=CBlockHeader(bad_block_time).serialize().hex()))548# Should ask for the block from a p2p node, if they announce the header as well:549peer = node.add_p2p_connection(P2PDataStore())550peer.wait_for_getheaders(timeout=5, block_hash=block.hashPrevBlock)551peer.send_blocks_and_test(blocks=[block], node=node)552# Must be active now:553assert chain_tip(block.hash_hex, status='active', branchlen=0) in node.getchaintips()555# Building a few blocks should give the same results556self.generatetoaddress(node, 10, node.get_deterministic_priv_key().address)557assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=CBlockHeader(bad_block_time).serialize().hex()))558assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=CBlockHeader(bad_block2).serialize().hex()))559node.submitheader(hexdata=CBlockHeader(block).serialize().hex())560node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex())561assert_equal(node.submitblock(hexdata=block.serialize().hex()), 'duplicate') # valid563self.test_fees_and_sigops()564self.test_blockmintxfee_parameter()565self.test_block_max_weight()566self.test_timewarp()567self.test_murch_zawy_mintime()568self.test_pruning()569self.test_height_in_locktime()572if __name__ == '__main__':573MiningTest(__file__).main()
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.