From c3738d0344f589162b9ffb78b8e2d78f612d3786 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Sat, 21 Jan 2023 13:43:15 +0100 Subject: [PATCH] miniscript: introduce a MsContext() helper to contexts We are going to introduce Tapscript support in Miniscript, for which some of Miniscript rules and properties change (new or modified fragments, different typing rules, different resources consumption, ..). --- src/script/descriptor.cpp | 13 ++++++++++--- src/script/miniscript.h | 5 +++++ src/script/sign.cpp | 6 ++++++ src/test/fuzz/miniscript.cpp | 8 ++++++++ src/test/miniscript_tests.cpp | 6 ++++++ 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 896fb0b5b31..eaef481c51b 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -1426,8 +1426,11 @@ struct KeyParser { mutable std::vector> m_keys; //! Used to detect key parsing errors within a Miniscript. mutable std::string m_key_parsing_error; + //! The script context we're operating within (Tapscript or P2WSH). + const miniscript::MiniscriptContext m_script_ctx; - KeyParser(FlatSigningProvider* out LIFETIMEBOUND, const SigningProvider* in LIFETIMEBOUND) : m_out(out), m_in(in) {} + KeyParser(FlatSigningProvider* out LIFETIMEBOUND, const SigningProvider* in LIFETIMEBOUND, miniscript::MiniscriptContext ctx) + : m_out(out), m_in(in), m_script_ctx(ctx) {} bool KeyCompare(const Key& a, const Key& b) const { return *m_keys.at(a) < *m_keys.at(b); @@ -1475,6 +1478,10 @@ struct KeyParser { } return {}; } + + miniscript::MiniscriptContext MsContext() const { + return m_script_ctx; + } }; /** Parse a script in a particular context. */ @@ -1714,7 +1721,7 @@ std::unique_ptr ParseScript(uint32_t& key_exp_index, Span InferScript(const CScript& script, ParseScriptCo } if (ctx == ParseScriptContext::P2WSH) { - KeyParser parser(nullptr, &provider); + KeyParser parser(/* out = */nullptr, /* in = */&provider, /* ctx = */miniscript::MiniscriptContext::P2WSH); auto node = miniscript::FromScript(script, parser); if (node && node->IsSane()) { return std::make_unique(std::move(parser.m_keys), std::move(node)); diff --git a/src/script/miniscript.h b/src/script/miniscript.h index 4effa5ce4e6..635efeed44c 100644 --- a/src/script/miniscript.h +++ b/src/script/miniscript.h @@ -229,6 +229,11 @@ enum class Availability { MAYBE, }; +enum class MiniscriptContext { + P2WSH, + TAPSCRIPT, +}; + namespace internal { //! Helper function for Node::CalcType. diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 92b7ad50b57..92c42dfe256 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -404,6 +404,8 @@ struct Satisfier { SignatureData& m_sig_data; const BaseSignatureCreator& m_creator; const CScript& m_witness_script; + //! For now Miniscript is only available under P2WSH. + const miniscript::MiniscriptContext m_script_ctx{miniscript::MiniscriptContext::P2WSH}; explicit Satisfier(const SigningProvider& provider LIFETIMEBOUND, SignatureData& sig_data LIFETIMEBOUND, const BaseSignatureCreator& creator LIFETIMEBOUND, @@ -466,6 +468,10 @@ struct Satisfier { miniscript::Availability SatHASH160(const std::vector& hash, std::vector& preimage) const { return MsLookupHelper(m_sig_data.hash160_preimages, hash, preimage); } + + miniscript::MiniscriptContext MsContext() const { + return m_script_ctx; + } }; bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata) diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp index 0246507da11..072938bbd20 100644 --- a/src/test/fuzz/miniscript.cpp +++ b/src/test/fuzz/miniscript.cpp @@ -128,6 +128,10 @@ struct ParserContext { if (it == TEST_DATA.dummy_keys_map.end()) return {}; return it->second; } + + miniscript::MiniscriptContext MsContext() const { + return miniscript::MiniscriptContext::P2WSH; + } } PARSER_CTX; //! Context that implements naive conversion from/to script only, for roundtrip testing. @@ -172,6 +176,10 @@ struct ScriptParserContext { key.is_hash = true; return key; } + + miniscript::MiniscriptContext MsContext() const { + return miniscript::MiniscriptContext::P2WSH; + } } SCRIPT_PARSER_CONTEXT; //! Context to produce a satisfaction for a Miniscript node using the pre-computed data. diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp index b69317c4d92..7f90cbc3dd1 100644 --- a/src/test/miniscript_tests.cpp +++ b/src/test/miniscript_tests.cpp @@ -114,6 +114,8 @@ typedef std::pair Challenge; struct KeyConverter { typedef CPubKey Key; + const miniscript::MiniscriptContext m_script_ctx{miniscript::MiniscriptContext::P2WSH}; + bool KeyCompare(const Key& a, const Key& b) const { return a < b; } @@ -158,6 +160,10 @@ struct KeyConverter { std::optional ToString(const Key& key) const { return HexStr(ToPKBytes(key)); } + + miniscript::MiniscriptContext MsContext() const { + return m_script_ctx; + } }; /** A class that encapsulates all signing/hash revealing operations. */