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.
1751# If we send without witness, it should be accepted.1752test_transaction_acceptance(self.nodes[1], self.std_node, tx2, False, True)1754# Now create a new anyone-can-spend utxo for the next test.1755tx3 = CTransaction()1756tx3.vin.append(CTxIn(COutPoint(tx2.txid_int, 0), CScript([p2sh_program])))1757tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))1758test_transaction_acceptance(self.nodes[0], self.test_node, tx2, False, True)1759test_transaction_acceptance(self.nodes[0], self.test_node, tx3, False, True)1761self.generate(self.nodes[0], 1)1763# Update our utxo list; we spent the first entry.1764self.utxo.pop(0)1765self.utxo.append(UTXO(tx3.txid_int, 0, tx3.vout[0].nValue))1767@subtest1768def test_non_standard_witness(self):1769"""Test detection of non-standard P2WSH witness"""1770pad = chr(1).encode('latin-1')1772# Create scripts for tests1773scripts = []1774scripts.append(CScript([OP_DROP] * 100))1775scripts.append(CScript([OP_DROP] * 99))1776scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 60))1777scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 61))1779p2wsh_scripts = []1781tx = CTransaction()1782tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1784# For each script, generate a pair of P2WSH and P2SH-P2WSH output.1785outputvalue = (self.utxo[0].nValue - 1000) // (len(scripts) * 2)1786for i in scripts:1787p2wsh = script_to_p2wsh_script(i)1788p2wsh_scripts.append(p2wsh)1789tx.vout.append(CTxOut(outputvalue, p2wsh))1790tx.vout.append(CTxOut(outputvalue, script_to_p2sh_script(p2wsh)))1791txid = tx.txid_int1792test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)1794self.generate(self.nodes[0], 1)1796# Creating transactions for tests1797p2wsh_txs = []1798p2sh_txs = []1799for i in range(len(scripts)):1800p2wsh_tx = CTransaction()1801p2wsh_tx.vin.append(CTxIn(COutPoint(txid, i * 2)))1802p2wsh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(b"")])))1803p2wsh_tx.wit.vtxinwit.append(CTxInWitness())1804p2wsh_txs.append(p2wsh_tx)1805p2sh_tx = CTransaction()1806p2sh_tx.vin.append(CTxIn(COutPoint(txid, i * 2 + 1), CScript([p2wsh_scripts[i]])))1807p2sh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(b"")])))1808p2sh_tx.wit.vtxinwit.append(CTxInWitness())1809p2sh_txs.append(p2sh_tx)1811# Testing native P2WSH1812# Witness stack size, excluding witnessScript, over 100 is non-standard1813p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]1814test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[0], True, False, 'bad-witness-nonstandard')1815# Non-standard nodes should accept1816test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[0], True, True)1818# Stack element size over 80 bytes is non-standard1819p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]1820test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, False, 'bad-witness-nonstandard')1821# Non-standard nodes should accept1822test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[1], True, True)1823# Standard nodes should accept if element size is not over 80 bytes1824p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]1825test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, True)1827# witnessScript size at 3600 bytes is standard1828p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]]1829test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[2], True, True)1830test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[2], True, True)1832# witnessScript size at 3601 bytes is non-standard1833p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]1834test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[3], True, False, 'bad-witness-nonstandard')1835# Non-standard nodes should accept1836test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[3], True, True)1838# Repeating the same tests with P2SH-P2WSH1839p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]1840test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[0], True, False, 'bad-witness-nonstandard')1841test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[0], True, True)1842p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]1843test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, False, 'bad-witness-nonstandard')1844test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[1], True, True)1845p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]1846test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, True)1847p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]]1848test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[2], True, True)1849test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[2], True, True)1850p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]1851test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[3], True, False, 'bad-witness-nonstandard')1852test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[3], True, True)1854self.generate(self.nodes[0], 1) # Mine and clean up the mempool of non-standard node1855# Valid but non-standard transactions in a block should be accepted by standard node1856self.sync_blocks()1857assert_equal(len(self.nodes[0].getrawmempool()), 0)1858assert_equal(len(self.nodes[1].getrawmempool()), 0)1860self.utxo.pop(0)1862@subtest1863def test_witness_sigops(self):1864"""Test sigop counting is correct inside witnesses."""1866# Keep this under MAX_OPS_PER_SCRIPT (201)1867witness_script = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKMULTISIG] * 5 + [OP_CHECKSIG] * 193 + [OP_ENDIF])1868script_pubkey = script_to_p2wsh_script(witness_script)1870sigops_per_script = 20 * 5 + 193 * 11871# We'll produce 2 extra outputs, one with a program that would take us1872# over max sig ops, and one with a program that would exactly reach max1873# sig ops1874outputs = (MAX_SIGOP_COST // sigops_per_script) + 21875extra_sigops_available = MAX_SIGOP_COST % sigops_per_script1876p2sh_outputs = MAX_SIGOP_COST // (sigops_per_script * WITNESS_SCALE_FACTOR) + 11878# We chose the number of checkmultisigs/checksigs to make this work:1879assert extra_sigops_available < 100 # steer clear of MAX_OPS_PER_SCRIPT1881# This script, when spent with the first1882# N(=MAX_SIGOP_COST//sigops_per_script) outputs of our transaction,1883# would push us just over the block sigop limit.1884witness_script_toomany = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG] * (extra_sigops_available + 1) + [OP_ENDIF])1885script_pubkey_toomany = script_to_p2wsh_script(witness_script_toomany)1887# If we spend this script instead, we would exactly reach our sigop1888# limit (for witness sigops).1889witness_script_justright = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG] * (extra_sigops_available) + [OP_ENDIF])1890script_pubkey_justright = script_to_p2wsh_script(witness_script_justright)1892# First split our available utxo into a bunch of outputs1893split_value = self.utxo[0].nValue // outputs1894tx = CTransaction()1895tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1896for _ in range(outputs):1897tx.vout.append(CTxOut(split_value, script_pubkey))1898tx.vout[-2].scriptPubKey = script_pubkey_toomany1899tx.vout[-1].scriptPubKey = script_pubkey_justright1900tx.vout += [CTxOut(0, script_to_p2sh_script(witness_script)) for _ in range(p2sh_outputs)]1902block_1 = self.build_next_block()1903self.update_witness_block_with_transactions(block_1, [tx])1904test_witness_block(self.nodes[0], self.test_node, block_1, accepted=True)1906tx2 = CTransaction()1907# If we try to spend the first n-1 outputs from tx, that should be1908# too many sigops.1909total_value = 01910for i in range(outputs - 1):1911tx2.vin.append(CTxIn(COutPoint(tx.txid_int, i), b""))1912tx2.wit.vtxinwit.append(CTxInWitness())1913tx2.wit.vtxinwit[-1].scriptWitness.stack = [witness_script]1914total_value += tx.vout[i].nValue1915tx2.wit.vtxinwit[-1].scriptWitness.stack = [witness_script_toomany]1916tx2.vout.append(CTxOut(total_value, CScript([OP_TRUE])))1918block_2 = self.build_next_block()1919self.update_witness_block_with_transactions(block_2, [tx2])1920test_witness_block(self.nodes[0], self.test_node, block_2, accepted=False, reason='bad-blk-sigops')1922# Try dropping the last input in tx2, and add an output that has1923# too many sigops (contributing to legacy sigop count).1924checksig_count = (extra_sigops_available // 4) + 11925script_pubkey_checksigs = CScript([OP_CHECKSIG] * checksig_count)1926tx2.vout.append(CTxOut(0, script_pubkey_checksigs))1927tx2.vin.pop()1928tx2.wit.vtxinwit.pop()1929tx2.vout[0].nValue -= tx.vout[outputs - 2].nValue1930block_3 = self.build_next_block()1931self.update_witness_block_with_transactions(block_3, [tx2])1932test_witness_block(self.nodes[0], self.test_node, block_3, accepted=False, reason='bad-blk-sigops')1934# If we drop the last checksig in this output, the tx should succeed.1935block_4 = self.build_next_block()1936tx2.vout[-1].scriptPubKey = CScript([OP_CHECKSIG] * (checksig_count - 1))1937self.update_witness_block_with_transactions(block_4, [tx2])1938test_witness_block(self.nodes[0], self.test_node, block_4, accepted=True)1940# Reset the tip back down for the next test1941self.sync_blocks()1942for x in self.nodes:1943x.invalidateblock(block_4.hash_hex)1945# Try replacing the last input of tx2 to be spending the last1946# output of tx1947block_5 = self.build_next_block()1948tx2.vout.pop()1949tx2.vin.append(CTxIn(COutPoint(tx.txid_int, outputs - 1), b""))1950tx2.wit.vtxinwit.append(CTxInWitness())1951tx2.wit.vtxinwit[-1].scriptWitness.stack = [witness_script_justright]1952self.update_witness_block_with_transactions(block_5, [tx2])1953test_witness_block(self.nodes[0], self.test_node, block_5, accepted=True)1955p2sh_tx = CTransaction()1956p2sh_tx.vin = [CTxIn(COutPoint(tx.txid_int, outputs + i), CScript([witness_script])) for i in range(p2sh_outputs)]1957p2sh_tx.vout.append(CTxOut(0, CScript([OP_TRUE])))1958block_6 = self.build_next_block()1959self.update_witness_block_with_transactions(block_6, [p2sh_tx])1960test_witness_block(self.nodes[0], self.test_node, block_6, accepted=False, reason='bad-blk-sigops')1962# Add witness data to verify that the transaction's P2SH sigops are still counted.1963p2sh_tx.vin.append(CTxIn(COutPoint(tx.txid_int, outputs - 2), b""))1964p2sh_tx.wit.vtxinwit = [CTxInWitness() for _ in p2sh_tx.vin]1965p2sh_tx.wit.vtxinwit[-1].scriptWitness.stack = [witness_script_toomany]1966block_7 = self.build_next_block()1967self.update_witness_block_with_transactions(block_7, [p2sh_tx])1968test_witness_block(self.nodes[0], self.test_node, block_7, accepted=False, reason='bad-blk-sigops')1970# Cleanup and prep for next test1971self.utxo.pop(0)1972self.utxo.append(UTXO(tx2.txid_int, 0, tx2.vout[0].nValue))1974@subtest1975def test_superfluous_witness(self):1976# Serialization of tx that puts witness flag to 3 always1977def serialize_with_bogus_witness(tx):1978flags = 31979r = b""1980r += tx.version.to_bytes(4, "little")1981if flags:1982dummy = []1983r += ser_vector(dummy)1984r += flags.to_bytes(1, "little")1985r += ser_vector(tx.vin)1986r += ser_vector(tx.vout)1987if flags & 1:1988if (len(tx.wit.vtxinwit) != len(tx.vin)):1989# vtxinwit must have the same length as vin1990tx.wit.vtxinwit = tx.wit.vtxinwit[:len(tx.vin)]1991for _ in range(len(tx.wit.vtxinwit), len(tx.vin)):1992tx.wit.vtxinwit.append(CTxInWitness())1993r += tx.wit.serialize()1994r += tx.nLockTime.to_bytes(4, "little")1995return r1997class msg_bogus_tx(msg_tx):1998def serialize(self):1999return serialize_with_bogus_witness(self.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.