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.
1252# Verify that removing the witness succeeds.1253test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)1255# Now try to add extra witness data to a valid witness tx.1256witness_script = CScript([OP_TRUE])1257script_pubkey = script_to_p2wsh_script(witness_script)1258tx2 = CTransaction()1259tx2.vin.append(CTxIn(COutPoint(tx_hash, 0), b""))1260tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_pubkey))1262tx3 = CTransaction()1263tx3.vin.append(CTxIn(COutPoint(tx2.txid_int, 0), b""))1264tx3.wit.vtxinwit.append(CTxInWitness())1266# Add too-large for IsStandard witness and check that it does not enter reject filter1267p2sh_script = CScript([OP_TRUE])1268witness_script2 = CScript([b'a' * 400000])1269tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, script_to_p2sh_script(p2sh_script)))1270tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_script2]1272# Node will not be blinded to the transaction, requesting it any number of times1273# if it is being announced via txid relay.1274# Node will be blinded to the transaction via wtxid, however.1275self.std_node.announce_tx_and_wait_for_getdata(tx3)1276self.std_wtx_node.announce_tx_and_wait_for_getdata(tx3, use_wtxid=True)1277test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, 'tx-size')1278self.std_node.announce_tx_and_wait_for_getdata(tx3)1279self.std_wtx_node.announce_tx_and_wait_for_getdata(tx3, use_wtxid=True, success=False)1281# Remove witness stuffing, instead add extra witness push on stack1282tx3.vout[0] = CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))1283tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_script]1285test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True)1286test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False)1288# Now do the opposite: strip the witness entirely. This will be detected as witness stripping and1289# the (w)txid won't be added to the reject filter: we can try again and get the same error.1290tx3.wit.vtxinwit[0].scriptWitness.stack = []1291reason = "was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)"1292test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason)1293test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason)1295# Get rid of the extra witness, and verify acceptance.1296tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_script]1297# Also check that old_node gets a tx announcement, even though this is1298# a witness transaction.1299self.old_node.wait_for_inv([CInv(MSG_TX, tx2.txid_int)]) # wait until tx2 was inv'ed1300test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=True)1301self.old_node.wait_for_inv([CInv(MSG_TX, tx3.txid_int)])1303# Test that getrawtransaction returns correct witness information1304# hash, size, vsize1305raw_tx = self.nodes[0].getrawtransaction(tx3.txid_hex, 1)1306assert_equal(raw_tx["hash"], tx3.wtxid_hex)1307assert_equal(raw_tx["size"], len(tx3.serialize_with_witness()))1308vsize = tx3.get_vsize()1309assert_equal(raw_tx["vsize"], vsize)1310assert_equal(raw_tx["weight"], tx3.get_weight())1311assert_equal(len(raw_tx["vin"][0]["txinwitness"]), 1)1312assert_equal(raw_tx["vin"][0]["txinwitness"][0], witness_script.hex())1313assert_not_equal(vsize, raw_tx["size"])1315# Cleanup: mine the transactions and update utxo for next test1316self.generate(self.nodes[0], 1)1317assert_equal(len(self.nodes[0].getrawmempool()), 0)1319self.utxo.pop(0)1320self.utxo.append(UTXO(tx3.txid_int, 0, tx3.vout[0].nValue))1322@subtest1323def test_segwit_versions(self):1324"""Test validity of future segwit version transactions.1326Future segwit versions are non-standard to spend, but valid in blocks.1327Sending to future segwit versions is always allowed.1328Can run this before and after segwit activation."""1330NUM_SEGWIT_VERSIONS = 17 # will test OP_0, OP1, ..., OP_161331if len(self.utxo) < NUM_SEGWIT_VERSIONS:1332tx = CTransaction()1333tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1334split_value = (self.utxo[0].nValue - 4000) // NUM_SEGWIT_VERSIONS1335for _ in range(NUM_SEGWIT_VERSIONS):1336tx.vout.append(CTxOut(split_value, CScript([OP_TRUE])))1337block = self.build_next_block()1338self.update_witness_block_with_transactions(block, [tx])1339test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1340self.utxo.pop(0)1341for i in range(NUM_SEGWIT_VERSIONS):1342self.utxo.append(UTXO(tx.txid_int, i, split_value))1344self.sync_blocks()1345temp_utxo = []1346tx = CTransaction()1347witness_script = CScript([OP_TRUE])1348witness_hash = sha256(witness_script)1349assert_equal(len(self.nodes[1].getrawmempool()), 0)1350for version in list(range(OP_1, OP_16 + 1)) + [OP_0]:1351# First try to spend to a future version segwit script_pubkey.1352if version == OP_1:1353# Don't use 32-byte v1 witness (used by Taproot; see BIP 341)1354script_pubkey = CScript([CScriptOp(version), witness_hash + b'\x00'])1355else:1356script_pubkey = CScript([CScriptOp(version), witness_hash])1357tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")]1358tx.vout = [CTxOut(self.utxo[0].nValue - 1000, script_pubkey)]1359test_transaction_acceptance(self.nodes[1], self.std_node, tx, with_witness=True, accepted=False)1360test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=True)1361self.utxo.pop(0)1362temp_utxo.append(UTXO(tx.txid_int, 0, tx.vout[0].nValue))1364self.generate(self.nodes[0], 1) # Mine all the transactions1365assert_equal(len(self.nodes[0].getrawmempool()), 0)1367# Finally, verify that version 0 -> version 2 transactions1368# are standard1369script_pubkey = CScript([CScriptOp(OP_2), witness_hash])1370tx2 = CTransaction()1371tx2.vin = [CTxIn(COutPoint(tx.txid_int, 0), b"")]1372tx2.vout = [CTxOut(tx.vout[0].nValue - 1000, script_pubkey)]1373tx2.wit.vtxinwit.append(CTxInWitness())1374tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_script]1375# Gets accepted to both policy-enforcing nodes and others.1376test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True)1377test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=True)1378temp_utxo.pop() # last entry in temp_utxo was the output we just spent1379temp_utxo.append(UTXO(tx2.txid_int, 0, tx2.vout[0].nValue))1381# Spend everything in temp_utxo into an segwit v1 output.1382tx3 = CTransaction()1383total_value = 01384for i in temp_utxo:1385tx3.vin.append(CTxIn(COutPoint(i.sha256, i.n), b""))1386tx3.wit.vtxinwit.append(CTxInWitness())1387total_value += i.nValue1388tx3.wit.vtxinwit[-1].scriptWitness.stack = [witness_script]1389tx3.vout.append(CTxOut(total_value - 1000, script_pubkey))1391# First we test this transaction against std_node1392# making sure the txid is added to the reject filter1393self.std_node.announce_tx_and_wait_for_getdata(tx3)1394test_transaction_acceptance(self.nodes[1], self.std_node, tx3, with_witness=True, accepted=False, reason="bad-txns-nonstandard-inputs")1395# Now the node will no longer ask for getdata of this transaction when advertised by same txid1396self.std_node.announce_tx_and_wait_for_getdata(tx3, success=False)1398# Spending a higher version witness output is not allowed by policy,1399# even with the node that accepts non-standard txs.1400test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False, reason="reserved for soft-fork upgrades")1402# Building a block with the transaction must be valid, however.1403block = self.build_next_block()1404self.update_witness_block_with_transactions(block, [tx2, tx3])1405test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1406self.sync_blocks()1408# Add utxo to our list1409self.utxo.append(UTXO(tx3.txid_int, 0, tx3.vout[0].nValue))1411@subtest1412def test_premature_coinbase_witness_spend(self):1414block = self.build_next_block()1415# Change the output of the block to be a witness output.1416witness_script = CScript([OP_TRUE])1417script_pubkey = script_to_p2wsh_script(witness_script)1418block.vtx[0].vout[0].scriptPubKey = script_pubkey1419# This next line will rehash the coinbase and update the merkle1420# root, and solve.1421self.update_witness_block_with_transactions(block, [])1422test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1424spend_tx = CTransaction()1425spend_tx.vin = [CTxIn(COutPoint(block.vtx[0].txid_int, 0), b"")]1426spend_tx.vout = [CTxOut(block.vtx[0].vout[0].nValue, witness_script)]1427spend_tx.wit.vtxinwit.append(CTxInWitness())1428spend_tx.wit.vtxinwit[0].scriptWitness.stack = [witness_script]1430# Now test a premature spend.1431self.generate(self.nodes[0], 98)1432block2 = self.build_next_block()1433self.update_witness_block_with_transactions(block2, [spend_tx])1434test_witness_block(self.nodes[0], self.test_node, block2, accepted=False, reason='bad-txns-premature-spend-of-coinbase')1436# Advancing one more block should allow the spend.1437self.generate(self.nodes[0], 1)1438block2 = self.build_next_block()1439self.update_witness_block_with_transactions(block2, [spend_tx])1440test_witness_block(self.nodes[0], self.test_node, block2, accepted=True)1441self.sync_blocks()1443@subtest1444def test_uncompressed_pubkey(self):1445"""Test uncompressed pubkey validity in segwit transactions.1447Uncompressed pubkeys are no longer supported in default relay policy,1448but (for now) are still valid in blocks."""1450# Segwit transactions using uncompressed pubkeys are not accepted1451# under default policy, but should still pass consensus.1452key, pubkey = generate_keypair(compressed=False)1453assert_equal(len(pubkey), 65) # This should be an uncompressed pubkey1455utxo = self.utxo.pop(0)1457# Test 1: P2WPKH1458# First create a P2WPKH output that uses an uncompressed pubkey1459pubkeyhash = hash160(pubkey)1460script_pkh = key_to_p2wpkh_script(pubkey)1461tx = CTransaction()1462tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b""))1463tx.vout.append(CTxOut(utxo.nValue - 1000, script_pkh))1465# Confirm it in a block.1466block = self.build_next_block()1467self.update_witness_block_with_transactions(block, [tx])1468test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1470# Now try to spend it. Send it to a P2WSH output, which we'll1471# use in the next test.1472witness_script = key_to_p2pk_script(pubkey)1473script_wsh = script_to_p2wsh_script(witness_script)1475tx2 = CTransaction()1476tx2.vin.append(CTxIn(COutPoint(tx.txid_int, 0), b""))1477tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_wsh))1478script = keyhash_to_p2pkh_script(pubkeyhash)1479tx2.wit.vtxinwit.append(CTxInWitness())1480tx2.wit.vtxinwit[0].scriptWitness.stack = [pubkey]1481sign_input_segwitv0(tx2, 0, script, tx.vout[0].nValue, key)1483# Should fail policy test.1484test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)')1485# But passes consensus.1486block = self.build_next_block()1487self.update_witness_block_with_transactions(block, [tx2])1488test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1490# Test 2: P2WSH1491# Try to spend the P2WSH output created in last test.1492# Send it to a P2SH(P2WSH) output, which we'll use in the next test.1493script_p2sh = script_to_p2sh_script(script_wsh)1494script_sig = CScript([script_wsh])1496tx3 = CTransaction()1497tx3.vin.append(CTxIn(COutPoint(tx2.txid_int, 0), b""))1498tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, script_p2sh))1499tx3.wit.vtxinwit.append(CTxInWitness())1500sign_p2pk_witness_input(witness_script, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key)
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.