diff options
author | Johnson Lau <jl2012@xbt.hk> | 2020-09-11 14:34:02 -0700 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2020-10-12 17:18:24 -0700 |
commit | 72422ce396b8eba7b1a72c171c2f07dae691d1b5 (patch) | |
tree | d2aa2a75ed54579ed6ddac8f858cf3ca67605b48 /src/script/interpreter.h | |
parent | 330de894a9a48515d9a473448b6c67adc3d188be (diff) |
Implement Tapscript script validation rules (BIP 342)
This adds a new `SigVersion::TAPSCRIPT`, makes the necessary interpreter
changes to make it implement BIP342, and uses them for leaf version 0xc0
in Taproot script path spends.
Diffstat (limited to 'src/script/interpreter.h')
-rw-r--r-- | src/script/interpreter.h | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 55aa1f230b..c0c2b012c6 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -86,6 +86,8 @@ enum // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true". // (BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH or WITNESS. + // Note: WITNESS_V0 and TAPSCRIPT script execution have behavior similar to CLEANSTACK as part of their + // consensus rules. It is automatic there and does not need this flag. SCRIPT_VERIFY_CLEANSTACK = (1U << 8), // Verify CHECKLOCKTIMEVERIFY @@ -108,6 +110,8 @@ enum // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector // + // Note: TAPSCRIPT script execution has behavior similar to MINIMALIF as part of its consensus + // rules. It is automatic there and does not depend on this flag. SCRIPT_VERIFY_MINIMALIF = (1U << 13), // Signature(s) must be empty vector if a CHECK(MULTI)SIG operation failed @@ -122,13 +126,19 @@ enum // SCRIPT_VERIFY_CONST_SCRIPTCODE = (1U << 16), - // Taproot validation (BIP 341) + // Taproot/Tapscript validation (BIPs 341 & 342) // SCRIPT_VERIFY_TAPROOT = (1U << 17), // Making unknown Taproot leaf versions non-standard // SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION = (1U << 18), + + // Making unknown OP_SUCCESS non-standard + SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS = (1U << 19), + + // Making unknown public key versions (in BIP 342 scripts) non-standard + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1U << 20), }; bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror); @@ -168,16 +178,32 @@ enum class SigVersion BASE = 0, //!< Bare scripts and BIP16 P2SH-wrapped redeemscripts WITNESS_V0 = 1, //!< Witness v0 (P2WPKH and P2WSH); see BIP 141 TAPROOT = 2, //!< Witness v1 with 32-byte program, not BIP16 P2SH-wrapped, key path spending; see BIP 341 + TAPSCRIPT = 3, //!< Witness v1 with 32-byte program, not BIP16 P2SH-wrapped, script path spending, leaf version 0xc0; see BIP 342 }; struct ScriptExecutionData { + //! Whether m_tapleaf_hash is initialized. + bool m_tapleaf_hash_init = false; + //! The tapleaf hash. + uint256 m_tapleaf_hash; + + //! Whether m_codeseparator_pos is initialized. + bool m_codeseparator_pos_init = false; + //! Opcode position of the last executed OP_CODESEPARATOR (or 0xFFFFFFFF if none executed). + uint32_t m_codeseparator_pos; + //! Whether m_annex_present and (when needed) m_annex_hash are initialized. bool m_annex_init = false; //! Whether an annex is present. bool m_annex_present; //! Hash of the annex data. uint256 m_annex_hash; + + //! Whether m_validation_weight_left is initialized. + bool m_validation_weight_left_init = false; + //! How much validation weight is left (decremented for every successful non-empty signature check). + int64_t m_validation_weight_left; }; /** Signature hash sizes */ @@ -186,6 +212,7 @@ static constexpr size_t WITNESS_V0_KEYHASH_SIZE = 20; static constexpr size_t WITNESS_V1_TAPROOT_SIZE = 32; static constexpr uint8_t TAPROOT_LEAF_MASK = 0xfe; +static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT = 0xc0; static constexpr size_t TAPROOT_CONTROL_BASE_SIZE = 33; static constexpr size_t TAPROOT_CONTROL_NODE_SIZE = 32; static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT = 128; |