Skip to content

Commit ce8845f

Browse files
committed
miniscript: account for keys as being 32 bytes under Taproot context
1 parent f4f978d commit ce8845f

File tree

3 files changed

+10
-8
lines changed

3 files changed

+10
-8
lines changed

src/script/miniscript.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,12 @@ Type ComputeType(Fragment fragment, Type x, Type y, Type z, const std::vector<Ty
258258
assert(false);
259259
}
260260

261-
size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys) {
261+
size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs,
262+
size_t n_keys, MiniscriptContext ms_ctx) {
262263
switch (fragment) {
263264
case Fragment::JUST_1:
264265
case Fragment::JUST_0: return 1;
265-
case Fragment::PK_K: return 34;
266+
case Fragment::PK_K: return IsTapscript(ms_ctx) ? 33 : 34;
266267
case Fragment::PK_H: return 3 + 21;
267268
case Fragment::OLDER:
268269
case Fragment::AFTER: return 1 + BuildScript(k).size();

src/script/miniscript.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ constexpr uint32_t MaxScriptSize(MiniscriptContext ms_ctx)
280280
Type ComputeType(Fragment fragment, Type x, Type y, Type z, const std::vector<Type>& sub_types, uint32_t k, size_t data_size, size_t n_subs, size_t n_keys, MiniscriptContext ms_ctx);
281281

282282
//! Helper function for Node::CalcScriptLen.
283-
size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys);
283+
size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys, MiniscriptContext ms_ctx);
284284

285285
//! A helper sanitizer/checker for the output of CalcType.
286286
Type SanitizeType(Type x);
@@ -437,7 +437,7 @@ struct Node {
437437
subsize += sub->ScriptSize();
438438
}
439439
Type sub0type = subs.size() > 0 ? subs[0]->GetType() : ""_mst;
440-
return internal::ComputeScriptLen(fragment, sub0type, subsize, k, subs.size(), keys.size());
440+
return internal::ComputeScriptLen(fragment, sub0type, subsize, k, subs.size(), keys.size(), m_script_ctx);
441441
}
442442

443443
/* Apply a recursive algorithm to a Miniscript tree, without actual recursive calls.
@@ -1698,7 +1698,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
16981698
auto& [key, key_size] = *res;
16991699
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_C, Vector(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key))))));
17001700
in = in.subspan(key_size + 1);
1701-
script_size += 34;
1701+
script_size += IsTapscript(ctx.MsContext()) ? 33 : 34;
17021702
} else if (Const("pkh(", in)) {
17031703
auto res = ParseKeyEnd<Key>(in, ctx);
17041704
if (!res) return {};
@@ -1712,7 +1712,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
17121712
auto& [key, key_size] = *res;
17131713
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key))));
17141714
in = in.subspan(key_size + 1);
1715-
script_size += 33;
1715+
script_size += IsTapscript(ctx.MsContext()) ? 32 : 33;
17161716
} else if (Const("pk_h(", in)) {
17171717
auto res = ParseKeyEnd<Key>(in, ctx);
17181718
if (!res) return {};
@@ -2058,7 +2058,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
20582058
break;
20592059
}
20602060
// Public keys
2061-
if (in[0].second.size() == 33) {
2061+
if (in[0].second.size() == 33 || in[0].second.size() == 32) {
20622062
auto key = ctx.FromPKBytes(in[0].second.begin(), in[0].second.end());
20632063
if (!key) return {};
20642064
++in;

src/test/fuzz/miniscript.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,8 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
796796
// Update predicted resource limits. Since every leaf Miniscript node is at least one
797797
// byte long, we move one byte from each child to their parent. A similar technique is
798798
// used in the miniscript::internal::Parse function to prevent runaway string parsing.
799-
scriptsize += miniscript::internal::ComputeScriptLen(node_info->fragment, ""_mst, node_info->subtypes.size(), node_info->k, node_info->subtypes.size(), node_info->keys.size()) - 1;
799+
scriptsize += miniscript::internal::ComputeScriptLen(node_info->fragment, ""_mst, node_info->subtypes.size(), node_info->k, node_info->subtypes.size(),
800+
node_info->keys.size(), miniscript::MiniscriptContext::P2WSH) - 1;
800801
if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
801802
switch (node_info->fragment) {
802803
case Fragment::MULTI_A:

0 commit comments

Comments
 (0)