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

Code before:
    pub, _ = compute_xonly_pubkey(sec)
    scripts = [
        ("future_leaf", CScript([pub, OP_CHECKSIG]), 0xc2),
        ("op_success", CScript([pub, OP_CHECKSIG, OP_0, OP_IF, CScriptOp(0x50), OP_ENDIF])),
    ]
    tap = taproot_construct(pub, scripts)

    # Test that features like annex, leaf versions, or OP_SUCCESS are valid but non-standard
    add_spender(spenders, "inactive/scriptpath_valid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")])
    add_spender(spenders, "inactive/scriptpath_invalid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))
    add_spender(spenders, "inactive/scriptpath_valid_opsuccess", key=sec, tap=tap, leaf="op_success", standard=False, inputs=[getter("sign")])
    add_spender(spenders, "inactive/scriptpath_valid_opsuccess", key=sec, tap=tap, leaf="op_success", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))

    return spenders

def sample_spenders():

    # Create key(s) for output creation, as well as key and script-spends
    secs = [generate_privkey() for _ in range(2)]
    pubs = [compute_xonly_pubkey(sec)[0] for sec in secs]

    # Create a list of scripts which will be built into a taptree
    scripts = [
        # leaf label, followed by CScript
        ("encodeable_pushdata1", CScript([OP_DROP, OP_PUSHDATA1, b'aa' * 75])),
        ("nonstd_encodeable_pushdata1", CScript([OP_PUSHDATA1, b'aa'])),
        ("dummyleaf", CScript([])),
    ]

    # Build TaprootInfo using scripts and appropriate pubkey for output creation
    tap = taproot_construct(pubs[0], scripts)

    # Finally, add spender(s).
    # Each spender embodies a test with an optional failure condition.
    # These failure conditions allow for fine-grained success/failure
    # conditions that are tested randomly.
    spenders = []

    # Named comment, using first leaf from scripts, with empty string as witness data, no optional fail condition
    add_spender(spenders, comment="tutorial/pushdata1", tap=tap, leaf="encodeable_pushdata1", inputs=[b'\x00'], no_fail=True)

    # Spender with alternative failure tapscript via over-riding "failure" dictionary, along with the failure's expected err_msg / ERR_*
    add_spender(spenders, comment="tutorial/pushdata1redux", tap=tap, leaf="encodeable_pushdata1", inputs=[b'\x00'], failure={"leaf": "dummyleaf"}, **ERR_EVAL_FALSE)

    # Spender that is non-standard but otherwise valid, with extraneous signature data from inner key for optional failure condition
    add_spender(spenders, comment="tutorial/nonminpushdata1", tap=tap, leaf="nonstd_encodeable_pushdata1", key=secs[0], standard=False, failure={"inputs": [getter("sign")]}, **ERR_CLEANSTACK)

    # New scripts=[] can be defined, and rinse-repeated as necessary until the spenders list is returned for execution
    return spenders

# Consensus validation flags to use in dumps for tests with "legacy/" or "inactive/" prefix.

Review comment (suggestion):
Shouldn't this one be called `nonstd_2byte_pushdata1` because it uses the `PUSHDATA1` opcode?
That's what is mentioned in the comments of the previous PR and in the spender comment down below.

Code after:
    pub, _ = compute_xonly_pubkey(sec)
    scripts = [
        ("future_leaf", CScript([pub, OP_CHECKSIG]), 0xc2),
        ("op_success", CScript([pub, OP_CHECKSIG, OP_0, OP_IF, CScriptOp(0x50), OP_ENDIF])),
    ]
    tap = taproot_construct(pub, scripts)

    # Test that features like annex, leaf versions, or OP_SUCCESS are valid but non-standard
    add_spender(spenders, "inactive/scriptpath_valid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")])
    add_spender(spenders, "inactive/scriptpath_invalid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))
    add_spender(spenders, "inactive/scriptpath_valid_opsuccess", key=sec, tap=tap, leaf="op_success", standard=False, inputs=[getter("sign")])
    add_spender(spenders, "inactive/scriptpath_valid_opsuccess", key=sec, tap=tap, leaf="op_success", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))

    return spenders

def sample_spenders():

    # Create key(s) for output creation, as well as key and script-spends
    secs = [generate_privkey() for _ in range(2)]
    pubs = [compute_xonly_pubkey(sec)[0] for sec in secs]

    # Create a list of scripts which will be built into a taptree
    scripts = [
        # leaf label, followed by CScript
        ("2byte_push", CScript([OP_DROP, b'\xaa\xaa'])),
        ("nonstd_2byte_push", CScript.fromhex("4c02aaaa")),
        ("dummyleaf", CScript([])),
    ]

    # Build TaprootInfo using scripts and appropriate pubkey for output creation
    tap = taproot_construct(pubs[0], scripts)

    # Finally, add spender(s).
    # Each spender embodies a test with an optional failure condition.
    # These failure conditions allow for fine-grained success/failure
    # conditions that are tested randomly.
    spenders = []

    # Named comment, using first leaf from scripts, with empty string as witness data, no optional fail condition
    add_spender(spenders, comment="tutorial/push", tap=tap, leaf="2byte_push", inputs=[b'\x00'], no_fail=True)

    # Spender with alternative failure tapscript via over-riding "failure" dictionary, along with the failure's expected err_msg / ERR_*
    add_spender(spenders, comment="tutorial/pushredux", tap=tap, leaf="2byte_push", inputs=[b'\x00'], failure={"leaf": "dummyleaf"}, **ERR_EVAL_FALSE)

    # Spender that is non-standard but otherwise valid, with extraneous signature data from inner key for optional failure condition
    add_spender(spenders, comment="tutorial/nonminpush", tap=tap, leaf="nonstd_2byte_push", key=secs[0], standard=False, failure={"inputs": [getter("sign")]}, **ERR_CLEANSTACK)

    # New scripts=[] can be defined, and rinse-repeated as necessary until the spenders list is returned for execution
    return spenders

# Consensus validation flags to use in dumps for tests with "legacy/" or "inactive/" prefix.