Repository: bitcoin/bitcoin
File: test/functional/p2p_segwit.py (Python)

Code before:
        tx.wit.vtxinwit.append(CTxInWitness())
        tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])]
        tx.rehash()
        self.update_witness_block_with_transactions(block, [tx])

        # Extra witness data should not be allowed.
        test_witness_block(self.nodes[0], self.test_node, block, accepted=False,
                           reason='mandatory-script-verify-flag-failed (Witness provided for non-witness script)')

        # Try extra signature data.  Ok if we're not spending a witness output.
        block.vtx[1].wit.vtxinwit = []
        block.vtx[1].vin[0].scriptSig = CScript([OP_0])
        block.vtx[1].rehash()
        add_witness_commitment(block)
        block.solve()

        test_witness_block(self.nodes[0], self.test_node, block, accepted=True)

        # Now try extra witness/signature data on an input that DOES require a
        # witness
        tx2 = CTransaction()
        tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))  # witness output
        tx2.vin.append(CTxIn(COutPoint(tx.sha256, 1), b""))  # non-witness
        tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))
        tx2.wit.vtxinwit.extend([CTxInWitness(), CTxInWitness()])
        tx2.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_script]
        tx2.wit.vtxinwit[1].scriptWitness.stack = [CScript([OP_TRUE])]

        block = self.build_next_block()
        self.update_witness_block_with_transactions(block, [tx2])

        # This has extra witness data, so it should fail.
        test_witness_block(self.nodes[0], self.test_node, block, accepted=False,
                           reason='mandatory-script-verify-flag-failed (Stack size must be exactly one after execution)')

        # Now get rid of the extra witness, but add extra scriptSig data
        tx2.vin[0].scriptSig = CScript([OP_TRUE])
        tx2.vin[1].scriptSig = CScript([OP_TRUE])
        tx2.wit.vtxinwit[0].scriptWitness.stack.pop(0)
        tx2.wit.vtxinwit[1].scriptWitness.stack = []
        tx2.rehash()
        add_witness_commitment(block)
        block.solve()

        # This has extra signature data for a witness input, so it should fail.
        test_witness_block(self.nodes[0], self.test_node, block, accepted=False,
                           reason='mandatory-script-verify-flag-failed (Witness requires empty scriptSig)')

        # Now get rid of the extra scriptsig on the witness input, and verify
        # success (even with extra scriptsig data in the non-witness input)
        tx2.vin[0].scriptSig = b""

Review comment (suggestion):
note: this is removed because it's causing a 2nd error that may mask the first's error being reported. Seems like a mistake in the original test code? Agree with its removal.

Code after:
        tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])]
        tx.rehash()
        self.update_witness_block_with_transactions(block, [tx])

        # Extra witness data should not be allowed.
        test_witness_block(self.nodes[0], self.test_node, block, accepted=False,
                           reason='mandatory-script-verify-flag-failed (Witness provided for non-witness script)')

        # Try extra signature data.  Ok if we're not spending a witness output.
        block.vtx[1].wit.vtxinwit = []
        block.vtx[1].vin[0].scriptSig = CScript([OP_0])
        block.vtx[1].rehash()
        add_witness_commitment(block)
        block.solve()

        test_witness_block(self.nodes[0], self.test_node, block, accepted=True)

        # Now try extra witness/signature data on an input that DOES require a
        # witness
        tx2 = CTransaction()
        tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))  # witness output
        tx2.vin.append(CTxIn(COutPoint(tx.sha256, 1), b""))  # non-witness
        tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))
        tx2.wit.vtxinwit.extend([CTxInWitness(), CTxInWitness()])
        tx2.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_script]
        tx2.wit.vtxinwit[1].scriptWitness.stack = []

        block = self.build_next_block()
        self.update_witness_block_with_transactions(block, [tx2])

        # This has extra witness data, so it should fail.
        test_witness_block(self.nodes[0], self.test_node, block, accepted=False,
                           reason='mandatory-script-verify-flag-failed (Stack size must be exactly one after execution)')

        # Now get rid of the extra witness, but add extra scriptSig data
        tx2.vin[0].scriptSig = CScript([OP_TRUE])
        tx2.vin[1].scriptSig = CScript([OP_TRUE])
        tx2.wit.vtxinwit[0].scriptWitness.stack.pop(0)
        tx2.wit.vtxinwit[1].scriptWitness.stack = []
        tx2.rehash()
        add_witness_commitment(block)
        block.solve()

        # This has extra signature data for a witness input, so it should fail.
        test_witness_block(self.nodes[0], self.test_node, block, accepted=False,
                           reason='mandatory-script-verify-flag-failed (Witness requires empty scriptSig)')

        # Now get rid of the extra scriptsig on the witness input, and verify
        # success (even with extra scriptsig data in the non-witness input)
        tx2.vin[0].scriptSig = b""
        tx2.rehash()