aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz/miniscript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz/miniscript.cpp')
-rw-r--r--src/test/fuzz/miniscript.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp
index 9597c289fa..f3a48daf2c 100644
--- a/src/test/fuzz/miniscript.cpp
+++ b/src/test/fuzz/miniscript.cpp
@@ -769,6 +769,9 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
std::vector<std::pair<Type, std::optional<NodeInfo>>> todo{{root_type, {}}};
/** Predict the number of (static) script ops. */
uint32_t ops{0};
+ /** Predict the total script size (every unexplored subnode is counted as one, as every leaf is
+ * at least one script byte). */
+ uint32_t scriptsize{1};
while (!todo.empty()) {
// The expected type we have to construct.
@@ -777,7 +780,11 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
// Fragment/children have not been decided yet. Decide them.
auto node_info = ConsumeNode(type_needed);
if (!node_info) return {};
- // Update predicted resource limits.
+ // 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;
+ if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
switch (node_info->fragment) {
case Fragment::JUST_0:
case Fragment::JUST_1:
@@ -834,6 +841,8 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
ops += 3;
break;
case Fragment::WRAP_V:
+ // We don't account for OP_VERIFY here; that will be corrected for when the actual
+ // node is constructed below.
break;
case Fragment::WRAP_J:
ops += 4;
@@ -885,8 +894,10 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
// Update resource predictions.
if (node->fragment == Fragment::WRAP_V && node->subs[0]->GetType() << "x"_mst) {
ops += 1;
+ scriptsize += 1;
}
if (ops > MAX_OPS_PER_SCRIPT) return {};
+ if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
// Move it to the stack.
stack.push_back(std::move(node));
todo.pop_back();
@@ -894,6 +905,7 @@ NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
}
assert(stack.size() == 1);
assert(stack[0]->GetStaticOps() == ops);
+ assert(stack[0]->ScriptSize() == scriptsize);
stack[0]->DuplicateKeyCheck(KEY_COMP);
return std::move(stack[0]);
}