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.
1001script_pubkey = script_to_p2wsh_script(witness_script)1003# First try extra witness data on a tx that doesn't require a witness1004tx = CTransaction()1005tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1006tx.vout.append(CTxOut(self.utxo[0].nValue - 2000, script_pubkey))1007tx.vout.append(CTxOut(1000, CScript([OP_TRUE]))) # non-witness output1008tx.wit.vtxinwit.append(CTxInWitness())1009tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])]1010self.update_witness_block_with_transactions(block, [tx])1012# Extra witness data should not be allowed.1013test_witness_block(self.nodes[0], self.test_node, block, accepted=False,1014reason='block-script-verify-flag-failed (Witness provided for non-witness script)')1016# Try extra signature data. Ok if we're not spending a witness output.1017block.vtx[1].wit.vtxinwit = []1018block.vtx[1].vin[0].scriptSig = CScript([OP_0])1019add_witness_commitment(block)1020block.solve()1022test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1024# Now try extra witness/signature data on an input that DOES require a1025# witness1026tx2 = CTransaction()1027tx2.vin.append(CTxIn(COutPoint(tx.txid_int, 0), b"")) # witness output1028tx2.vin.append(CTxIn(COutPoint(tx.txid_int, 1), b"")) # non-witness1029tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))1030tx2.wit.vtxinwit.extend([CTxInWitness(), CTxInWitness()])1031tx2.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_script]1032tx2.wit.vtxinwit[1].scriptWitness.stack = []1034block = self.build_next_block()1035self.update_witness_block_with_transactions(block, [tx2])1037# This has extra witness data, so it should fail.1038test_witness_block(self.nodes[0], self.test_node, block, accepted=False,1039reason='block-script-verify-flag-failed (Stack size must be exactly one after execution)')1041# Now get rid of the extra witness, but add extra scriptSig data1042tx2.vin[0].scriptSig = CScript([OP_TRUE])1043tx2.vin[1].scriptSig = CScript([OP_TRUE])1044tx2.wit.vtxinwit[0].scriptWitness.stack.pop(0)1045tx2.wit.vtxinwit[1].scriptWitness.stack = []1046add_witness_commitment(block)1047block.solve()1049# This has extra signature data for a witness input, so it should fail.1050test_witness_block(self.nodes[0], self.test_node, block, accepted=False,1051reason='block-script-verify-flag-failed (Witness requires empty scriptSig)')1053# Now get rid of the extra scriptsig on the witness input, and verify1054# success (even with extra scriptsig data in the non-witness input)1055tx2.vin[0].scriptSig = b""1056add_witness_commitment(block)1057block.solve()1059test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1061# Update utxo for later tests1062self.utxo.pop(0)1063self.utxo.append(UTXO(tx2.txid_int, 0, tx2.vout[0].nValue))1065@subtest1066def test_max_witness_push_length(self):1067"""Test that witness stack can only allow up to MAX_SCRIPT_ELEMENT_SIZE byte pushes."""1069block = self.build_next_block()1071witness_script = CScript([OP_DROP, OP_TRUE])1072script_pubkey = script_to_p2wsh_script(witness_script)1074tx = CTransaction()1075tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1076tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))1078tx2 = CTransaction()1079tx2.vin.append(CTxIn(COutPoint(tx.txid_int, 0), b""))1080tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, CScript([OP_TRUE])))1081tx2.wit.vtxinwit.append(CTxInWitness())1082# First try a 521-byte stack element1083tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a' * (MAX_SCRIPT_ELEMENT_SIZE + 1), witness_script]1085self.update_witness_block_with_transactions(block, [tx, tx2])1086test_witness_block(self.nodes[0], self.test_node, block, accepted=False,1087reason='block-script-verify-flag-failed (Push value size limit exceeded)')1089# Now reduce the length of the stack element1090tx2.wit.vtxinwit[0].scriptWitness.stack[0] = b'a' * (MAX_SCRIPT_ELEMENT_SIZE)1092add_witness_commitment(block)1093block.solve()1094test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1096# Update the utxo for later tests1097self.utxo.pop()1098self.utxo.append(UTXO(tx2.txid_int, 0, tx2.vout[0].nValue))1100@subtest1101def test_max_witness_script_length(self):1102"""Test that witness outputs greater than 10kB can't be spent."""1104MAX_WITNESS_SCRIPT_LENGTH = 100001106# This script is 19 max pushes (9937 bytes), then 64 more opcode-bytes.1107long_witness_script = CScript([b'a' * MAX_SCRIPT_ELEMENT_SIZE] * 19 + [OP_DROP] * 63 + [OP_TRUE])1108assert_equal(len(long_witness_script), MAX_WITNESS_SCRIPT_LENGTH + 1)1109long_script_pubkey = script_to_p2wsh_script(long_witness_script)1111block = self.build_next_block()1113tx = CTransaction()1114tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1115tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, long_script_pubkey))1117tx2 = CTransaction()1118tx2.vin.append(CTxIn(COutPoint(tx.txid_int, 0), b""))1119tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, CScript([OP_TRUE])))1120tx2.wit.vtxinwit.append(CTxInWitness())1121tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a'] * 44 + [long_witness_script]1123self.update_witness_block_with_transactions(block, [tx, tx2])1125test_witness_block(self.nodes[0], self.test_node, block, accepted=False,1126reason='block-script-verify-flag-failed (Script is too big)')1128# Try again with one less byte in the witness script1129witness_script = CScript([b'a' * MAX_SCRIPT_ELEMENT_SIZE] * 19 + [OP_DROP] * 62 + [OP_TRUE])1130assert_equal(len(witness_script), MAX_WITNESS_SCRIPT_LENGTH)1131script_pubkey = script_to_p2wsh_script(witness_script)1133tx.vout[0] = CTxOut(tx.vout[0].nValue, script_pubkey)1134tx2.vin[0].prevout.hash = tx.txid_int1135tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a'] * 43 + [witness_script]1136block.vtx = [block.vtx[0]]1137self.update_witness_block_with_transactions(block, [tx, tx2])1138test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1140self.utxo.pop()1141self.utxo.append(UTXO(tx2.txid_int, 0, tx2.vout[0].nValue))1143@subtest1144def test_witness_input_length(self):1145"""Test that vin length must match vtxinwit length."""1147witness_script = CScript([OP_DROP, OP_TRUE])1148script_pubkey = script_to_p2wsh_script(witness_script)1150# Create a transaction that splits our utxo into many outputs1151tx = CTransaction()1152tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1153value = self.utxo[0].nValue1154for _ in range(10):1155tx.vout.append(CTxOut(int(value / 10), script_pubkey))1156tx.vout[0].nValue -= 10001157assert tx.vout[0].nValue >= 01159block = self.build_next_block()1160self.update_witness_block_with_transactions(block, [tx])1161test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1163# Try various ways to spend tx that should all break.1164# This "broken" transaction serializer will not normalize1165# the length of vtxinwit.1166class BrokenCTransaction(CTransaction):1167def serialize_with_witness(self):1168flags = 01169if not self.wit.is_null():1170flags |= 11171r = b""1172r += self.version.to_bytes(4, "little")1173if flags:1174dummy = []1175r += ser_vector(dummy)1176r += flags.to_bytes(1, "little")1177r += ser_vector(self.vin)1178r += ser_vector(self.vout)1179if flags & 1:1180r += self.wit.serialize()1181r += self.nLockTime.to_bytes(4, "little")1182return r1184tx2 = BrokenCTransaction()1185for i in range(10):1186tx2.vin.append(CTxIn(COutPoint(tx.txid_int, i), b""))1187tx2.vout.append(CTxOut(value - 3000, CScript([OP_TRUE])))1189# First try using a too long vtxinwit1190for i in range(11):1191tx2.wit.vtxinwit.append(CTxInWitness())1192tx2.wit.vtxinwit[i].scriptWitness.stack = [b'a', witness_script]1194block = self.build_next_block()1195self.update_witness_block_with_transactions(block, [tx2])1196test_witness_block(self.nodes[0], self.test_node, block, accepted=False, reason='bad-txnmrklroot')1198# Now try using a too short vtxinwit1199tx2.wit.vtxinwit.pop()1200tx2.wit.vtxinwit.pop()1202block.vtx = [block.vtx[0]]1203self.update_witness_block_with_transactions(block, [tx2])1204# This block doesn't result in a specific reject reason, but an iostream exception:1205with self.nodes[0].assert_debug_log(["Exception 'DataStream::read(): end of data"]):1206test_witness_block(self.nodes[0], self.test_node, block, accepted=False)1208# Now make one of the intermediate witnesses be incorrect1209tx2.wit.vtxinwit.append(CTxInWitness())1210tx2.wit.vtxinwit[-1].scriptWitness.stack = [b'a', witness_script]1211tx2.wit.vtxinwit[5].scriptWitness.stack = [witness_script]1213block.vtx = [block.vtx[0]]1214self.update_witness_block_with_transactions(block, [tx2])1215test_witness_block(self.nodes[0], self.test_node, block, accepted=False,1216reason='block-script-verify-flag-failed (Operation not valid with the current stack size)')1218# Fix the broken witness and the block should be accepted.1219tx2.wit.vtxinwit[5].scriptWitness.stack = [b'a', witness_script]1220block.vtx = [block.vtx[0]]1221self.update_witness_block_with_transactions(block, [tx2])1222test_witness_block(self.nodes[0], self.test_node, block, accepted=True)1224self.utxo.pop()1225self.utxo.append(UTXO(tx2.txid_int, 0, tx2.vout[0].nValue))1227@subtest1228def test_tx_relay_after_segwit_activation(self):1229"""Test transaction relay after segwit activation.1231After segwit activates, verify that mempool:1232- rejects transactions with unnecessary/extra witnesses1233- accepts transactions with valid witnesses1234and that witness transactions are relayed to non-upgraded peers."""1236# Generate a transaction that doesn't require a witness, but send it1237# with a witness. Should be rejected because we can't use a witness1238# when spending a non-witness output.1239tx = CTransaction()1240tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))1241tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))1242tx.wit.vtxinwit.append(CTxInWitness())1243tx.wit.vtxinwit[0].scriptWitness.stack = [b'a']1245tx_hash = tx.txid_int1247# Verify that unnecessary witnesses are rejected.1248self.test_node.announce_tx_and_wait_for_getdata(tx)1249assert_equal(len(self.nodes[0].getrawmempool()), 0)1250test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=False)
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.