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) 2016-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 segwit transactions and blocks on P2P network."""6from decimal import Decimal7import random9from test_framework.blocktools import (10WITNESS_COMMITMENT_HEADER,11add_witness_commitment,12create_block,13)14from test_framework.messages import (15MAX_BIP125_RBF_SEQUENCE,16CBlockHeader,17CInv,18COutPoint,19CTransaction,20CTxIn,21CTxInWitness,22CTxOut,23CTxWitness,24MAX_BLOCK_WEIGHT,25MSG_BLOCK,26MSG_TX,27MSG_WITNESS_FLAG,28MSG_WITNESS_TX,29MSG_WTX,30NODE_NETWORK,31NODE_WITNESS,32WITNESS_SCALE_FACTOR,33msg_no_witness_block,34msg_getdata,35msg_headers,36msg_inv,37msg_tx,38msg_block,39msg_no_witness_tx,40ser_uint256,41ser_vector,42sha256,43)44from test_framework.p2p import (45P2PInterface,46p2p_lock,47P2P_SERVICES,48)49from test_framework.script import (50CScript,51CScriptNum,52CScriptOp,53MAX_SCRIPT_ELEMENT_SIZE,54OP_0,55OP_1,56OP_2,57OP_16,58OP_2DROP,59OP_CHECKMULTISIG,60OP_CHECKSIG,61OP_DROP,62OP_ELSE,63OP_ENDIF,64OP_IF,65OP_RETURN,66OP_TRUE,67SIGHASH_ALL,68SIGHASH_ANYONECANPAY,69SIGHASH_NONE,70SIGHASH_SINGLE,71hash160,72sign_input_legacy,73sign_input_segwitv0,74)75from test_framework.script_util import (76key_to_p2pk_script,77key_to_p2wpkh_script,78keyhash_to_p2pkh_script,79script_to_p2sh_script,80script_to_p2wsh_script,81)82from test_framework.test_framework import BitcoinTestFramework83from test_framework.util import (84assert_not_equal,85assert_greater_than_or_equal,86assert_equal,87assert_raises_rpc_error,88ensure_for,89softfork_active,90)91from test_framework.wallet import MiniWallet92from test_framework.wallet_util import generate_keypair95MAX_SIGOP_COST = 8000097SEGWIT_HEIGHT = 12099class UTXO():100"""Used to keep track of anyone-can-spend outputs that we can use in the tests."""101def __init__(self, sha256, n, value):102self.sha256 = sha256103self.n = n104self.nValue = value107def subtest(func):108"""Wraps the subtests for logging and state assertions."""109def func_wrapper(self, *args, **kwargs):110self.log.info("Subtest: {} (Segwit active = {})".format(func.__name__, self.segwit_active))111# Assert segwit status is as expected112assert_equal(softfork_active(self.nodes[0], 'segwit'), self.segwit_active)113func(self, *args, **kwargs)114# Each subtest should leave some utxos for the next subtest115assert self.utxo116self.sync_blocks()117# Assert segwit status is as expected at end of subtest118assert_equal(softfork_active(self.nodes[0], 'segwit'), self.segwit_active)120return func_wrapper123def sign_p2pk_witness_input(script, tx_to, in_idx, hashtype, value, key):124"""Add signature for a P2PK witness script."""125tx_to.wit.vtxinwit[in_idx].scriptWitness.stack = [script]126sign_input_segwitv0(tx_to, in_idx, script, value, key, hashtype)128def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=None):129"""Send a transaction to the node and check that it's accepted to the mempool131- Submit the transaction over the p2p interface132- use the getrawmempool rpc to check for acceptance."""133reason = [reason] if reason else []134with node.assert_debug_log(expected_msgs=reason):135p2p.send_and_ping(msg_tx(tx) if with_witness else msg_no_witness_tx(tx))136assert_equal(tx.txid_hex in node.getrawmempool(), accepted)139def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=None):140"""Send a block to the node and check that it's accepted142- Submit the block over the p2p interface143- use the getbestblockhash rpc to check for acceptance."""144reason = [reason] if reason else []145with node.assert_debug_log(expected_msgs=reason):146p2p.send_and_ping(msg_block(block) if with_witness else msg_no_witness_block(block))147assert_equal(node.getbestblockhash() == block.hash_hex, accepted)150class TestP2PConn(P2PInterface):151def __init__(self, wtxidrelay=False):152super().__init__(wtxidrelay=wtxidrelay)153self.getdataset = set()154self.last_wtxidrelay = []155self.lastgetdata = []156self.wtxidrelay = wtxidrelay158# Don't send getdata message replies to invs automatically.159# We'll send the getdata messages explicitly in the test logic.160def on_inv(self, message):161pass163def on_getdata(self, message):164self.lastgetdata = message.inv165for inv in message.inv:166self.getdataset.add(inv.hash)168def on_wtxidrelay(self, message):169self.last_wtxidrelay.append(message)171def announce_tx_and_wait_for_getdata(self, tx, success=True, use_wtxid=False):172if success:173# sanity check174assert (self.wtxidrelay and use_wtxid) or (not self.wtxidrelay and not use_wtxid)175with p2p_lock:176self.last_message.pop("getdata", None)177if use_wtxid:178wtxid = tx.wtxid_int179self.send_without_ping(msg_inv(inv=[CInv(MSG_WTX, wtxid)]))180else:181self.send_without_ping(msg_inv(inv=[CInv(MSG_TX, tx.txid_int)]))183if success:184if use_wtxid:185self.wait_for_getdata([wtxid])186else:187self.wait_for_getdata([tx.txid_int])188else:189ensure_for(duration=5, f=lambda: not self.last_message.get("getdata"))191def announce_block_and_wait_for_getdata(self, block, use_header, timeout=60):192with p2p_lock:193self.last_message.pop("getdata", None)194msg = msg_headers()195msg.headers = [CBlockHeader(block)]196if use_header:197self.send_without_ping(msg)198else:199self.send_without_ping(msg_inv(inv=[CInv(MSG_BLOCK, block.hash_int)]))200self.wait_for_getheaders(block_hash=block.hashPrevBlock, timeout=timeout)201self.send_without_ping(msg)202self.wait_for_getdata([block.hash_int], timeout=timeout)204def request_block(self, blockhash, inv_type, timeout=60):205with p2p_lock:206self.last_message.pop("block", None)207self.send_without_ping(msg_getdata(inv=[CInv(inv_type, blockhash)]))208self.wait_for_block(blockhash, timeout=timeout)209return self.last_message["block"].block211class SegWitTest(BitcoinTestFramework):212def set_test_params(self):213self.setup_clean_chain = True214self.num_nodes = 2215# whitelist peers to speed up tx relay / mempool sync216self.noban_tx_relay = True217# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.218self.extra_args = [219# -par=1 should not affect validation outcome or logging/reported failures. It is kept220# here to exercise the code path still (as it is distinct for multithread script221# validation).222["-acceptnonstdtxn=1", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}", "-par=1"],223["-acceptnonstdtxn=0", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}"],224]226# Helper functions228def build_next_block(self):229"""Build a block on top of node0's tip."""230tip = self.nodes[0].getbestblockhash()231height = self.nodes[0].getblockcount() + 1232block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1233block = create_block(int(tip, 16), height=height, ntime=block_time)234return block236def update_witness_block_with_transactions(self, block, tx_list, nonce=0):237"""Add list of transactions to block, adds witness commitment, then solves."""238block.vtx.extend(tx_list)239add_witness_commitment(block, nonce)240block.solve()242def run_test(self):243# Setup the p2p connections244# self.test_node sets P2P_SERVICES, i.e. NODE_WITNESS | NODE_NETWORK245self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn(), services=P2P_SERVICES)246# self.old_node sets only NODE_NETWORK247self.old_node = self.nodes[0].add_p2p_connection(TestP2PConn(), services=NODE_NETWORK)248# self.std_node is for testing node1 (requires standard txs)249self.std_node = self.nodes[1].add_p2p_connection(TestP2PConn(), services=P2P_SERVICES)250# self.std_wtx_node is for testing node1 with wtxid relay
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.