miniscript: account for keys as being 32 bytes under Taproot context
This commit is contained in:
3 files changed
+10
-8
No files matched your search
@@ -258,11 +258,12 @@ Type ComputeType(Fragment fragment, Type x, Type y, Type z, const std::vector<Ty
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
switch (fragment) {
|
switch (fragment) {
|
||||||
case Fragment::JUST_1:
|
case Fragment::JUST_1:
|
||||||
case Fragment::JUST_0: return 1;
|
case Fragment::JUST_0: return 1;
|
||||||
case Fragment::PK_K: return 34;
|
case Fragment::PK_K: return IsTapscript(ms_ctx) ? 33 : 34;
|
||||||
case Fragment::PK_H: return 3 + 21;
|
case Fragment::PK_H: return 3 + 21;
|
||||||
case Fragment::OLDER:
|
case Fragment::OLDER:
|
||||||
case Fragment::AFTER: return 1 + BuildScript(k).size();
|
case Fragment::AFTER: return 1 + BuildScript(k).size();
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ constexpr uint32_t MaxScriptSize(MiniscriptContext ms_ctx)
|
|||||||
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);
|
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);
|
||||||
|
|
||||||
//! Helper function for Node::CalcScriptLen.
|
//! 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.
|
//! A helper sanitizer/checker for the output of CalcType.
|
||||||
Type SanitizeType(Type x);
|
Type SanitizeType(Type x);
|
||||||
@@ -437,7 +437,7 @@ private:
|
|||||||
subsize += sub->ScriptSize();
|
subsize += sub->ScriptSize();
|
||||||
}
|
}
|
||||||
Type sub0type = subs.size() > 0 ? subs[0]->GetType() : ""_mst;
|
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.
|
/* 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)
|
|||||||
auto& [key, key_size] = *res;
|
auto& [key, key_size] = *res;
|
||||||
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))))));
|
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))))));
|
||||||
in = in.subspan(key_size + 1);
|
in = in.subspan(key_size + 1);
|
||||||
script_size += 34;
|
script_size += IsTapscript(ctx.MsContext()) ? 33 : 34;
|
||||||
} else if (Const("pkh(", in)) {
|
} else if (Const("pkh(", in)) {
|
||||||
auto res = ParseKeyEnd<Key>(in, ctx);
|
auto res = ParseKeyEnd<Key>(in, ctx);
|
||||||
if (!res) return {};
|
if (!res) return {};
|
||||||
@@ -1712,7 +1712,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
|
|||||||
auto& [key, key_size] = *res;
|
auto& [key, key_size] = *res;
|
||||||
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key))));
|
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key))));
|
||||||
in = in.subspan(key_size + 1);
|
in = in.subspan(key_size + 1);
|
||||||
script_size += 33;
|
script_size += IsTapscript(ctx.MsContext()) ? 32 : 33;
|
||||||
} else if (Const("pk_h(", in)) {
|
} else if (Const("pk_h(", in)) {
|
||||||
auto res = ParseKeyEnd<Key>(in, ctx);
|
auto res = ParseKeyEnd<Key>(in, ctx);
|
||||||
if (!res) return {};
|
if (!res) return {};
|
||||||
@@ -2058,7 +2058,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Public keys
|
// 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());
|
auto key = ctx.FromPKBytes(in[0].second.begin(), in[0].second.end());
|
||||||
if (!key) return {};
|
if (!key) return {};
|
||||||
++in;
|
++in;
|
||||||
|
|||||||
@@ -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
|
// 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
|
// 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.
|
// 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 {};
|
if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
|
||||||
switch (node_info->fragment) {
|
switch (node_info->fragment) {
|
||||||
case Fragment::MULTI_A:
|
case Fragment::MULTI_A:
|
||||||
|
|||||||
Reference in new issue
Block a user