From ce8845f5dda403461178c08e7363978fda423999 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 7 Feb 2023 19:40:03 +0100 Subject: [PATCH] miniscript: account for keys as being 32 bytes under Taproot context --- src/script/miniscript.cpp | 5 +++-- src/script/miniscript.h | 10 +++++----- src/test/fuzz/miniscript.cpp | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/script/miniscript.cpp b/src/script/miniscript.cpp index 03158c5d8a7..344a81bdf05 100644 --- a/src/script/miniscript.cpp +++ b/src/script/miniscript.cpp @@ -258,11 +258,12 @@ Type ComputeType(Fragment fragment, Type x, Type y, Type z, const std::vector& sub_types, uint32_t k, size_t data_size, size_t n_subs, size_t n_keys, MiniscriptContext ms_ctx); //! Helper function for Node::CalcScriptLen. -size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys); +size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys, MiniscriptContext ms_ctx); //! A helper sanitizer/checker for the output of CalcType. Type SanitizeType(Type x); @@ -437,7 +437,7 @@ private: subsize += sub->ScriptSize(); } Type sub0type = subs.size() > 0 ? subs[0]->GetType() : ""_mst; - return internal::ComputeScriptLen(fragment, sub0type, subsize, k, subs.size(), keys.size()); + return internal::ComputeScriptLen(fragment, sub0type, subsize, k, subs.size(), keys.size(), m_script_ctx); } /* Apply a recursive algorithm to a Miniscript tree, without actual recursive calls. @@ -1698,7 +1698,7 @@ inline NodeRef Parse(Span in, const Ctx& ctx) auto& [key, key_size] = *res; constructed.push_back(MakeNodeRef(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_C, Vector(MakeNodeRef(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key)))))); in = in.subspan(key_size + 1); - script_size += 34; + script_size += IsTapscript(ctx.MsContext()) ? 33 : 34; } else if (Const("pkh(", in)) { auto res = ParseKeyEnd(in, ctx); if (!res) return {}; @@ -1712,7 +1712,7 @@ inline NodeRef Parse(Span in, const Ctx& ctx) auto& [key, key_size] = *res; constructed.push_back(MakeNodeRef(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key)))); in = in.subspan(key_size + 1); - script_size += 33; + script_size += IsTapscript(ctx.MsContext()) ? 32 : 33; } else if (Const("pk_h(", in)) { auto res = ParseKeyEnd(in, ctx); if (!res) return {}; @@ -2058,7 +2058,7 @@ inline NodeRef DecodeScript(I& in, I last, const Ctx& ctx) break; } // Public keys - if (in[0].second.size() == 33) { + if (in[0].second.size() == 33 || in[0].second.size() == 32) { auto key = ctx.FromPKBytes(in[0].second.begin(), in[0].second.end()); if (!key) return {}; ++in; diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp index c1334849658..1268e01e98a 100644 --- a/src/test/fuzz/miniscript.cpp +++ b/src/test/fuzz/miniscript.cpp @@ -796,7 +796,8 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) { // Update predicted resource limits. Since every leaf Miniscript node is at least one // byte long, we move one byte from each child to their parent. A similar technique is // used in the miniscript::internal::Parse function to prevent runaway string parsing. - scriptsize += miniscript::internal::ComputeScriptLen(node_info->fragment, ""_mst, node_info->subtypes.size(), node_info->k, node_info->subtypes.size(), node_info->keys.size()) - 1; + scriptsize += miniscript::internal::ComputeScriptLen(node_info->fragment, ""_mst, node_info->subtypes.size(), node_info->k, node_info->subtypes.size(), + node_info->keys.size(), miniscript::MiniscriptContext::P2WSH) - 1; if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {}; switch (node_info->fragment) { case Fragment::MULTI_A: