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.
1#!/usr/bin/env python32# Copyright (c) 2014-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.5"""Test the getchaintips RPC.7- introduce a network split8- work on chains of different lengths9- join the network together again10- verify that getchaintips now returns two chain tips.11"""13from test_framework.blocktools import (14create_block,15create_coinbase,16)17from test_framework.test_framework import BitcoinTestFramework18from test_framework.util import assert_equal20class GetChainTipsTest (BitcoinTestFramework):21def set_test_params(self):22self.num_nodes = 424def run_test(self):25self.log.info("Test getchaintips behavior with two chains of different length")26tips = self.nodes[0].getchaintips()27assert_equal(len(tips), 1)28assert_equal(tips[0]['branchlen'], 0)29assert_equal(tips[0]['height'], 200)30assert_equal(tips[0]['status'], 'active')32self.log.info("Split the network and build two chains of different lengths.")33self.split_network()34self.generate(self.nodes[0], 10, sync_fun=lambda: self.sync_all(self.nodes[:2]))35self.generate(self.nodes[2], 20, sync_fun=lambda: self.sync_all(self.nodes[2:]))37tips = self.nodes[1].getchaintips()38assert_equal(len(tips), 1)39shortTip = tips[0]40assert_equal(shortTip['branchlen'], 0)41assert_equal(shortTip['height'], 210)42assert_equal(tips[0]['status'], 'active')44tips = self.nodes[3].getchaintips()45assert_equal(len(tips), 1)46longTip = tips[0]47assert_equal(longTip['branchlen'], 0)48assert_equal(longTip['height'], 220)49assert_equal(tips[0]['status'], 'active')51self.log.info("Join the network halves and check that we now have two tips")52# (at least at the nodes that previously had the short chain).53self.join_network()55tips = self.nodes[0].getchaintips()56assert_equal(len(tips), 2)57assert_equal(tips[0], longTip)59assert_equal(tips[1]['branchlen'], 10)60assert_equal(tips[1]['status'], 'valid-fork')61tips[1]['branchlen'] = 062tips[1]['status'] = 'active'63assert_equal(tips[1], shortTip)65self.log.info("Test getchaintips behavior with invalid blocks")66self.disconnect_nodes(0, 1)67n0 = self.nodes[0]68tip = int(n0.getbestblockhash(), 16)69start_height = self.nodes[0].getblockcount()70# Create invalid block (too high coinbase)71block_time = n0.getblock(n0.getbestblockhash())['time'] + 172invalid_block = create_block(tip, create_coinbase(start_height + 1, nValue=100), ntime=block_time)73invalid_block.solve()75block_time += 176block2 = create_block(invalid_block.hash_int, height=2, ntime=block_time, version=4)77block2.solve()79self.log.info("Submit headers-only chain")80n0.submitheader(invalid_block.serialize().hex())81n0.submitheader(block2.serialize().hex())82tips = n0.getchaintips()83assert_equal(len(tips), 3)84assert_equal(tips[0]['status'], 'headers-only')86self.log.info("Submit invalid block that invalidates the headers-only chain")87n0.submitblock(invalid_block.serialize().hex())88tips = n0.getchaintips()89assert_equal(len(tips), 3)90assert_equal(tips[0]['status'], 'invalid')93if __name__ == '__main__':94GetChainTipsTest(__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.