Skip to content

Commit 8b56fc0

Browse files
committed
[qa] Test that v0 segwit outputs can't be spent pre-activation
Also updates the comments for an existing test, that now should be rewritten. Includes changes suggested by John Newbery.
1 parent ccb8ca4 commit 8b56fc0

File tree

1 file changed

+84
-4
lines changed

1 file changed

+84
-4
lines changed

test/functional/p2p_segwit.py

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_transaction_acceptance(rpc, p2p, tx, with_witness, accepted, reason=Non
4747
with mininode_lock:
4848
assert_equal(p2p.last_message["reject"].reason, reason)
4949

50-
def test_witness_block(rpc, p2p, block, accepted, with_witness=True):
50+
def test_witness_block(rpc, p2p, block, accepted, with_witness=True, reason=None):
5151
"""Send a block to the node and check that it's accepted
5252
5353
- Submit the block over the p2p interface
@@ -58,6 +58,10 @@ def test_witness_block(rpc, p2p, block, accepted, with_witness=True):
5858
p2p.send_message(msg_block(block))
5959
p2p.sync_with_ping()
6060
assert_equal(rpc.getbestblockhash() == block.hash, accepted)
61+
if (reason != None and not accepted):
62+
# Check the rejection reason as well.
63+
with mininode_lock:
64+
assert_equal(p2p.last_message["reject"].reason, reason)
6165

6266
class TestP2PConn(P2PInterface):
6367
def __init__(self):
@@ -271,6 +275,80 @@ def test_unnecessary_witness_before_segwit_activation(self):
271275
self.utxo.pop(0)
272276
self.utxo.append(UTXO(tx4.sha256, 0, tx4.vout[0].nValue))
273277

278+
# ~6 months after segwit activation, the SCRIPT_VERIFY_WITNESS flag was
279+
# backdated so that it applies to all blocks, going back to the genesis
280+
# block.
281+
#
282+
# Consequently, version 0 witness outputs are never spendable without
283+
# witness, and so can't be spent before segwit activation (the point at which
284+
# blocks are permitted to contain witnesses).
285+
def test_v0_outputs_arent_spendable(self):
286+
self.log.info("Testing that v0 witness program outputs aren't spendable before activation")
287+
288+
assert len(self.utxo), "self.utxo is empty"
289+
290+
# Create two outputs, a p2wsh and p2sh-p2wsh
291+
witness_program = CScript([OP_TRUE])
292+
witness_hash = sha256(witness_program)
293+
scriptPubKey = CScript([OP_0, witness_hash])
294+
295+
p2sh_pubkey = hash160(scriptPubKey)
296+
p2sh_scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
297+
298+
value = self.utxo[0].nValue // 3
299+
300+
tx = CTransaction()
301+
tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b'')]
302+
tx.vout = [CTxOut(value, scriptPubKey), CTxOut(value, p2sh_scriptPubKey)]
303+
tx.vout.append(CTxOut(value, CScript([OP_TRUE])))
304+
tx.rehash()
305+
txid = tx.sha256
306+
307+
# Add it to a block
308+
block = self.build_next_block()
309+
self.update_witness_block_with_transactions(block, [tx])
310+
# Verify that segwit isn't activated. A block serialized with witness
311+
# should be rejected prior to activation.
312+
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason = b'unexpected-witness')
313+
# Now send the block without witness. It should be accepted
314+
test_witness_block(self.nodes[0], self.test_node, block, accepted=True, with_witness=False)
315+
316+
# Now try to spend the outputs. This should fail since SCRIPT_VERIFY_WITNESS is always enabled.
317+
p2wsh_tx = CTransaction()
318+
p2wsh_tx.vin = [CTxIn(COutPoint(txid, 0), b'')]
319+
p2wsh_tx.vout = [CTxOut(value, CScript([OP_TRUE]))]
320+
p2wsh_tx.wit.vtxinwit.append(CTxInWitness())
321+
p2wsh_tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
322+
p2wsh_tx.rehash()
323+
324+
p2sh_p2wsh_tx = CTransaction()
325+
p2sh_p2wsh_tx.vin = [CTxIn(COutPoint(txid, 1), CScript([scriptPubKey]))]
326+
p2sh_p2wsh_tx.vout = [CTxOut(value, CScript([OP_TRUE]))]
327+
p2sh_p2wsh_tx.wit.vtxinwit.append(CTxInWitness())
328+
p2sh_p2wsh_tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
329+
p2sh_p2wsh_tx.rehash()
330+
331+
for tx in [p2wsh_tx, p2sh_p2wsh_tx]:
332+
333+
block = self.build_next_block()
334+
self.update_witness_block_with_transactions(block, [tx])
335+
336+
# When the block is serialized with a witness, the block will be rejected because witness
337+
# data isn't allowed in blocks that don't commit to witness data.
338+
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason=b'unexpected-witness')
339+
340+
# When the block is serialized without witness, validation fails because the transaction is
341+
# invalid (transactions are always validated with SCRIPT_VERIFY_WITNESS so a segwit v0 transaction
342+
# without a witness is invalid).
343+
# Note: The reject reason for this failure could be
344+
# 'block-validation-failed' (if script check threads > 1) or
345+
# 'non-mandatory-script-verify-flag (Witness program was passed an
346+
# empty witness)' (otherwise).
347+
# TODO: support multiple acceptable reject reasons.
348+
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=False)
349+
350+
self.utxo.pop(0)
351+
self.utxo.append(UTXO(txid, 2, value))
274352

275353
# Mine enough blocks for segwit's vb state to be 'started'.
276354
def advance_to_segwit_started(self):
@@ -1476,9 +1554,10 @@ def test_p2sh_witness(self, segwit_activated):
14761554
block = self.build_next_block()
14771555
self.update_witness_block_with_transactions(block, [spend_tx])
14781556

1479-
# If we're before activation, then sending this without witnesses
1480-
# should be valid. If we're after activation, then sending this with
1481-
# witnesses should be valid.
1557+
# If we're after activation, then sending this with witnesses should be valid.
1558+
# This no longer works before activation, because SCRIPT_VERIFY_WITNESS
1559+
# is always set.
1560+
# TODO: rewrite this test to make clear that it only works after activation.
14821561
if segwit_activated:
14831562
test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
14841563
else:
@@ -1897,6 +1976,7 @@ def run_test(self):
18971976
self.test_witness_services() # Verifies NODE_WITNESS
18981977
self.test_non_witness_transaction() # non-witness tx's are accepted
18991978
self.test_unnecessary_witness_before_segwit_activation()
1979+
self.test_v0_outputs_arent_spendable()
19001980
self.test_block_relay(segwit_activated=False)
19011981

19021982
# Advance to segwit being 'started'

0 commit comments

Comments
 (0)