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 RPCs related to blockchainstate.7Test the following RPCs:8- getblockchaininfo9- getdeploymentinfo10- getchaintxstats11- gettxoutsetinfo12- gettxout13- getblockheader14- getdifficulty15- getnetworkhashps16- waitforblockheight17- getblock18- getblockhash19- getbestblockhash20- verifychain22Tests correspond to code in rpc/blockchain.cpp.23"""25from decimal import Decimal26import http.client27import os28import subprocess29import textwrap31from test_framework.blocktools import (32MAX_FUTURE_BLOCK_TIME,33TIME_GENESIS_BLOCK,34REGTEST_N_BITS,35REGTEST_TARGET,36create_block,37create_coinbase,38create_tx_with_script,39nbits_str,40target_str,41)42from test_framework.messages import (43CBlockHeader,44COIN,45from_hex,46msg_block,47)48from test_framework.p2p import P2PInterface49from test_framework.script import hash256, OP_TRUE50from test_framework.test_framework import BitcoinTestFramework51from test_framework.util import (52assert_not_equal,53assert_equal,54assert_greater_than,55assert_greater_than_or_equal,56assert_raises,57assert_raises_rpc_error,58assert_is_hex_string,59assert_is_hash_string,60)61from test_framework.wallet import MiniWallet64HEIGHT = 200 # blocks mined65TIME_RANGE_STEP = 600 # ten-minute steps66TIME_RANGE_MTP = TIME_GENESIS_BLOCK + (HEIGHT - 6) * TIME_RANGE_STEP67TIME_RANGE_TIP = TIME_GENESIS_BLOCK + (HEIGHT - 1) * TIME_RANGE_STEP68TIME_RANGE_END = TIME_GENESIS_BLOCK + HEIGHT * TIME_RANGE_STEP69DIFFICULTY_ADJUSTMENT_INTERVAL = 14472class BlockchainTest(BitcoinTestFramework):73def set_test_params(self):74self.setup_clean_chain = True75self.num_nodes = 176self.supports_cli = False78def run_test(self):79self.wallet = MiniWallet(self.nodes[0])80self._test_prune_disk_space()81self.mine_chain()82self._test_max_future_block_time()83self.restart_node(840,85extra_args=[86"-stopatheight=207",87"-checkblocks=-1", # Check all blocks88"-prune=1", # Set pruning after rescan is complete89],90)92self._test_getblockchaininfo()93self._test_getchaintxstats()94self._test_gettxoutsetinfo()95self._test_gettxout()96self._test_getblockheader()97self._test_getdifficulty()98self._test_getnetworkhashps()99self._test_stopatheight()100self._test_waitforblock() # also tests waitfornewblock101self._test_waitforblockheight()102self._test_getblock()103self._test_getdeploymentinfo()104self._test_verificationprogress()105self._test_y2106()106assert self.nodes[0].verifychain(4, 0)108def mine_chain(self):109self.log.info(f"Generate {HEIGHT} blocks after the genesis block in ten-minute steps")110for t in range(TIME_GENESIS_BLOCK, TIME_RANGE_END, TIME_RANGE_STEP):111self.nodes[0].setmocktime(t)112self.generate(self.wallet, 1)113assert_equal(self.nodes[0].getblockchaininfo()['blocks'], HEIGHT)115def _test_prune_disk_space(self):116self.log.info("Test that a manually pruned node does not run into "117"integer overflow on first start up")118self.restart_node(0, extra_args=["-prune=1"])119self.log.info("Avoid warning when assumed chain size is enough")120self.restart_node(0, extra_args=["-prune=123456789"])122def _test_max_future_block_time(self):123self.stop_node(0)124self.log.info("A block tip of more than MAX_FUTURE_BLOCK_TIME in the future raises an error")125self.nodes[0].assert_start_raises_init_error(126extra_args=[f"-mocktime={TIME_RANGE_TIP - MAX_FUTURE_BLOCK_TIME - 1}"],127expected_msg="The block database contains a block which appears to be from the future."128" This may be due to your computer's date and time being set incorrectly."129f" Only rebuild the block database if you are sure that your computer's date and time are correct.{os.linesep}"130"Please restart with -reindex or -reindex-chainstate to recover.",131)132self.log.info("A block tip of MAX_FUTURE_BLOCK_TIME in the future is fine")133self.start_node(0, extra_args=[f"-mocktime={TIME_RANGE_TIP - MAX_FUTURE_BLOCK_TIME}"])135def _test_getblockchaininfo(self):136self.log.info("Test getblockchaininfo")138keys = [139'bestblockhash',140'bits',141'blocks',142'chain',143'chainwork',144'difficulty',145'headers',146'initialblockdownload',147'mediantime',148'pruned',149'size_on_disk',150'target',151'time',152'verificationprogress',153'warnings',154]155res = self.nodes[0].getblockchaininfo()157assert_equal(res['time'], TIME_RANGE_END - TIME_RANGE_STEP)158assert_equal(res['mediantime'], TIME_RANGE_MTP)160# result should have these additional pruning keys if manual pruning is enabled161assert_equal(sorted(res.keys()), sorted(['pruneheight', 'automatic_pruning'] + keys))163# size_on_disk should be > 0164assert_greater_than(res['size_on_disk'], 0)166# pruneheight should be greater or equal to 0167assert_greater_than_or_equal(res['pruneheight'], 0)169# check other pruning fields given that prune=1170assert res['pruned']171assert not res['automatic_pruning']173# check background validation is not present when we are not using assumeutxo174assert "backgroundvalidation" not in res.keys()176self.restart_node(0, ['-stopatheight=207'])177res = self.nodes[0].getblockchaininfo()178# should have exact keys179assert_equal(sorted(res.keys()), keys)181self.stop_node(0)182self.nodes[0].assert_start_raises_init_error(183extra_args=['-testactivationheight=name@2'],184expected_msg='Error: Invalid name (name@2) for -testactivationheight=name@height.',185)186self.nodes[0].assert_start_raises_init_error(187extra_args=['-testactivationheight=bip34@-2'],188expected_msg='Error: Invalid height value (bip34@-2) for -testactivationheight=name@height.',189)190self.nodes[0].assert_start_raises_init_error(191extra_args=['-testactivationheight='],192expected_msg='Error: Invalid format () for -testactivationheight=name@height.',193)194self.start_node(0, extra_args=[195'-stopatheight=207',196'-prune=550',197])199res = self.nodes[0].getblockchaininfo()200# result should have these additional pruning keys if prune=550201assert_equal(sorted(res.keys()), sorted(['pruneheight', 'automatic_pruning', 'prune_target_size'] + keys))203# check related fields204assert res['pruned']205assert_equal(res['pruneheight'], 0)206assert res['automatic_pruning']207assert_equal(res['prune_target_size'], 576716800)208assert_greater_than(res['size_on_disk'], 0)210assert_equal(res['bits'], nbits_str(REGTEST_N_BITS))211assert_equal(res['target'], target_str(REGTEST_TARGET))213def check_signalling_deploymentinfo_result(self, gdi_result, height, blockhash, status_next):214assert height >= 144 and height <= 287216assert_equal(gdi_result, {217"hash": blockhash,218"height": height,219"script_flags": ["CHECKLOCKTIMEVERIFY","CHECKSEQUENCEVERIFY","DERSIG","NULLDUMMY","P2SH","TAPROOT","WITNESS"],220"deployments": {221'bip34': {'type': 'buried', 'active': True, 'height': 2},222'bip66': {'type': 'buried', 'active': True, 'height': 3},223'bip65': {'type': 'buried', 'active': True, 'height': 4},224'csv': {'type': 'buried', 'active': True, 'height': 5},225'segwit': {'type': 'buried', 'active': True, 'height': 6},226'testdummy': {227'type': 'bip9',228'bip9': {229'bit': 28,230'start_time': 0,231'timeout': 0x7fffffffffffffff, # testdummy does not have a timeout so is set to the max int64 value232'min_activation_height': 0,233'status': 'started',234'status_next': status_next,235'since': 144,236'statistics': {237'period': 144,238'threshold': 108,239'elapsed': height - 143,240'count': height - 143,241'possible': True,242},243'signalling': '#'*(height-143),244},245'active': False246},247}248})250def _test_getdeploymentinfo(self):
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.