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.
251self.std_wtx_node = self.nodes[1].add_p2p_connection(TestP2PConn(wtxidrelay=True), services=P2P_SERVICES)253assert_not_equal(self.test_node.nServices & NODE_WITNESS, 0)255# Keep a place to store utxo's that can be used in later tests256self.utxo = []258self.log.info("Starting tests before segwit activation")259self.segwit_active = False260self.wallet = MiniWallet(self.nodes[0])262self.test_non_witness_transaction()263self.test_v0_outputs_arent_spendable()264self.test_block_relay()265self.test_unnecessary_witness_before_segwit_activation()266self.test_witness_tx_relay_before_segwit_activation()267self.test_standardness_v0()269self.log.info("Advancing to segwit activation")270self.advance_to_segwit_active()272# Segwit status 'active'274self.test_p2sh_witness()275self.test_witness_commitments()276self.test_block_malleability()277self.test_witness_block_size()278self.test_submit_block()279self.test_extra_witness_data()280self.test_max_witness_push_length()281self.test_max_witness_script_length()282self.test_witness_input_length()283self.test_block_relay()284self.test_tx_relay_after_segwit_activation()285self.test_standardness_v0()286self.test_segwit_versions()287self.test_premature_coinbase_witness_spend()288self.test_uncompressed_pubkey()289self.test_signature_version_1()290self.test_non_standard_witness_blinding()291self.test_non_standard_witness()292self.test_witness_sigops()293self.test_superfluous_witness()294self.test_wtxid_relay()296# Individual tests298@subtest299def test_non_witness_transaction(self):300"""See if sending a regular transaction works, and create a utxo to use in later tests."""301# Mine a block with an anyone-can-spend coinbase,302# let it mature, then try to spend it.304block = self.build_next_block()305block.solve()306self.test_node.send_and_ping(msg_no_witness_block(block)) # make sure the block was processed307txid = block.vtx[0].txid_int309self.generate(self.wallet, 99) # let the block mature311# Create a transaction that spends the coinbase312tx = CTransaction()313tx.vin.append(CTxIn(COutPoint(txid, 0), b""))314tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))316# Check that serializing it with or without witness is the same317# This is a sanity check of our testing framework.318assert_equal(msg_no_witness_tx(tx).serialize(), msg_tx(tx).serialize())320self.test_node.send_and_ping(msg_tx(tx)) # make sure the block was processed321assert tx.txid_hex in self.nodes[0].getrawmempool()322# Save this transaction for later323self.utxo.append(UTXO(tx.txid_int, 0, 49 * 100000000))324self.generate(self.nodes[0], 1)326@subtest327def test_unnecessary_witness_before_segwit_activation(self):328"""Verify that blocks with witnesses are rejected before activation."""330tx = CTransaction()331tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))332tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, CScript([OP_TRUE])))333tx.wit.vtxinwit.append(CTxInWitness())334tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)])]336# Verify the hash with witness differs from the txid337# (otherwise our testing framework must be broken!)338assert_not_equal(tx.txid_hex, tx.wtxid_hex)340# Construct a block that includes the transaction.341block = self.build_next_block()342self.update_witness_block_with_transactions(block, [tx])343# Sending witness data before activation is not allowed (anti-spam344# rule).345test_witness_block(self.nodes[0], self.test_node, block, accepted=False, reason='unexpected-witness')347# But it should not be permanently marked bad...348# Resend without witness information.349self.test_node.send_and_ping(msg_no_witness_block(block)) # make sure the block was processed350assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)352# Update our utxo list; we spent the first entry.353self.utxo.pop(0)354self.utxo.append(UTXO(tx.txid_int, 0, tx.vout[0].nValue))356@subtest357def test_block_relay(self):358"""Test that block requests to NODE_WITNESS peer are with MSG_WITNESS_FLAG.360This is true regardless of segwit activation.361Also test that we don't ask for blocks from unupgraded peers."""363blocktype = 2 | MSG_WITNESS_FLAG365# test_node has set NODE_WITNESS, so all getdata requests should be for366# witness blocks.367# Test announcing a block via inv results in a getdata, and that368# announcing a block with a header results in a getdata369block1 = self.build_next_block()370block1.solve()372# Send an empty headers message, to clear out any prior getheaders373# messages that our peer may be waiting for us on.374self.test_node.send_without_ping(msg_headers())376self.test_node.announce_block_and_wait_for_getdata(block1, use_header=False)377assert_equal(self.test_node.last_message["getdata"].inv[0].type, blocktype)378test_witness_block(self.nodes[0], self.test_node, block1, True)380block2 = self.build_next_block()381block2.solve()383self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True)384assert_equal(self.test_node.last_message["getdata"].inv[0].type, blocktype)385test_witness_block(self.nodes[0], self.test_node, block2, True)387# Check that we can getdata for witness blocks or regular blocks,388# and the right thing happens.389if not self.segwit_active:390# Before activation, we should be able to request old blocks with391# or without witness, and they should be the same.392chain_height = self.nodes[0].getblockcount()393# Pick 10 random blocks on main chain, and verify that getdata's394# for MSG_BLOCK, MSG_WITNESS_BLOCK, and rpc getblock() are equal.395all_heights = list(range(chain_height + 1))396random.shuffle(all_heights)397all_heights = all_heights[0:10]398for height in all_heights:399block_hash = self.nodes[0].getblockhash(height)400rpc_block = self.nodes[0].getblock(block_hash, False)401block_hash = int(block_hash, 16)402block = self.test_node.request_block(block_hash, 2)403wit_block = self.test_node.request_block(block_hash, 2 | MSG_WITNESS_FLAG)404assert_equal(block.serialize(), wit_block.serialize())405assert_equal(block.serialize(), bytes.fromhex(rpc_block))406else:407# After activation, witness blocks and non-witness blocks should408# be different. Verify rpc getblock() returns witness blocks, while409# getdata respects the requested type.410block = self.build_next_block()411self.update_witness_block_with_transactions(block, [])412# This gives us a witness commitment.413assert_equal(len(block.vtx[0].wit.vtxinwit), 1)414assert_equal(len(block.vtx[0].wit.vtxinwit[0].scriptWitness.stack), 1)415test_witness_block(self.nodes[0], self.test_node, block, accepted=True)416# Now try to retrieve it...417rpc_block = self.nodes[0].getblock(block.hash_hex, False)418non_wit_block = self.test_node.request_block(block.hash_int, 2)419wit_block = self.test_node.request_block(block.hash_int, 2 | MSG_WITNESS_FLAG)420assert_equal(wit_block.serialize(), bytes.fromhex(rpc_block))421assert_equal(wit_block.serialize(False), non_wit_block.serialize())422assert_equal(wit_block.serialize(), block.serialize())424# Test size, vsize, weight425rpc_details = self.nodes[0].getblock(block.hash_hex, True)426assert_equal(rpc_details["size"], len(block.serialize()))427assert_equal(rpc_details["strippedsize"], len(block.serialize(False)))428assert_equal(rpc_details["weight"], block.get_weight())430# Upgraded node should not ask for blocks from unupgraded431block4 = self.build_next_block()432block4.solve()433self.old_node.getdataset = set()435# Blocks can be requested via direct-fetch (immediately upon processing the announcement)436# or via parallel download (with an indeterminate delay from processing the announcement)437# so to test that a block is NOT requested, we could guess a time period to sleep for,438# and then check. We can avoid the sleep() by taking advantage of transaction getdata's439# being processed after block getdata's, and announce a transaction as well,440# and then check to see if that particular getdata has been received.441# Since 0.14, inv's will only be responded to with a getheaders, so send a header442# to announce this block.443msg = msg_headers()444msg.headers = [CBlockHeader(block4)]445self.old_node.send_without_ping(msg)446self.old_node.announce_tx_and_wait_for_getdata(block4.vtx[0])447assert block4.hash_int not in self.old_node.getdataset449@subtest450def test_v0_outputs_arent_spendable(self):451"""Test that v0 outputs aren't spendable before segwit activation.453~6 months after segwit activation, the SCRIPT_VERIFY_WITNESS flag was454backdated so that it applies to all blocks, going back to the genesis455block.457Consequently, version 0 witness outputs are never spendable without458witness, and so can't be spent before segwit activation (the point at which459blocks are permitted to contain witnesses)."""461# Create two outputs, a p2wsh and p2sh-p2wsh462witness_script = CScript([OP_TRUE])463script_pubkey = script_to_p2wsh_script(witness_script)464p2sh_script_pubkey = script_to_p2sh_script(script_pubkey)466value = self.utxo[0].nValue // 3468tx = CTransaction()469tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b'')]470tx.vout = [CTxOut(value, script_pubkey), CTxOut(value, p2sh_script_pubkey)]471tx.vout.append(CTxOut(value, CScript([OP_TRUE])))472txid = tx.txid_int474# Add it to a block475block = self.build_next_block()476self.update_witness_block_with_transactions(block, [tx])477# Verify that segwit isn't activated. A block serialized with witness478# should be rejected prior to activation.479test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason='unexpected-witness')480# Now send the block without witness. It should be accepted481test_witness_block(self.nodes[0], self.test_node, block, accepted=True, with_witness=False)483# Now try to spend the outputs. This should fail since SCRIPT_VERIFY_WITNESS is always enabled.484p2wsh_tx = CTransaction()485p2wsh_tx.vin = [CTxIn(COutPoint(txid, 0), b'')]486p2wsh_tx.vout = [CTxOut(value, CScript([OP_TRUE]))]487p2wsh_tx.wit.vtxinwit.append(CTxInWitness())488p2wsh_tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]490p2sh_p2wsh_tx = CTransaction()491p2sh_p2wsh_tx.vin = [CTxIn(COutPoint(txid, 1), CScript([script_pubkey]))]492p2sh_p2wsh_tx.vout = [CTxOut(value, CScript([OP_TRUE]))]493p2sh_p2wsh_tx.wit.vtxinwit.append(CTxInWitness())494p2sh_p2wsh_tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]496for tx in [p2wsh_tx, p2sh_p2wsh_tx]:498block = self.build_next_block()499self.update_witness_block_with_transactions(block, [tx])
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.