Skip to content

Commit 7ed2b2d

Browse files
committed
test: remove mutable global contexts in miniscript fuzzer/test
1 parent 78b7e95 commit 7ed2b2d

File tree

2 files changed

+62
-57
lines changed

2 files changed

+62
-57
lines changed

src/test/fuzz/miniscript.cpp

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ struct TestData {
113113
struct ParserContext {
114114
typedef CPubKey Key;
115115

116-
MsCtx script_ctx{MsCtx::P2WSH};
116+
const MsCtx script_ctx;
117+
118+
constexpr ParserContext(MsCtx ctx) noexcept : script_ctx(ctx) {}
117119

118120
bool KeyCompare(const Key& a, const Key& b) const {
119121
return a < b;
@@ -178,11 +180,13 @@ struct ParserContext {
178180
MsCtx MsContext() const {
179181
return script_ctx;
180182
}
181-
} PARSER_CTX;
183+
};
182184

183185
//! Context that implements naive conversion from/to script only, for roundtrip testing.
184186
struct ScriptParserContext {
185-
MsCtx script_ctx{MsCtx::P2WSH};
187+
const MsCtx script_ctx;
188+
189+
constexpr ScriptParserContext(MsCtx ctx) noexcept : script_ctx(ctx) {}
186190

187191
//! For Script roundtrip we never need the key from a key hash.
188192
struct Key {
@@ -228,10 +232,13 @@ struct ScriptParserContext {
228232
MsCtx MsContext() const {
229233
return script_ctx;
230234
}
231-
} SCRIPT_PARSER_CONTEXT;
235+
};
232236

233237
//! Context to produce a satisfaction for a Miniscript node using the pre-computed data.
234-
struct SatisfierContext: ParserContext {
238+
struct SatisfierContext : ParserContext {
239+
240+
constexpr SatisfierContext(MsCtx ctx) noexcept : ParserContext(ctx) {}
241+
235242
// Timelock challenges satisfaction. Make the value (deterministically) vary to explore different
236243
// paths.
237244
bool CheckAfter(uint32_t value) const { return value % 2; }
@@ -267,12 +274,10 @@ struct SatisfierContext: ParserContext {
267274
miniscript::Availability SatHASH160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
268275
return LookupHash(hash, preimage, TEST_DATA.hash160_preimages);
269276
}
270-
} SATISFIER_CTX;
277+
};
271278

272279
//! Context to check a satisfaction against the pre-computed data.
273-
struct CheckerContext: BaseSignatureChecker {
274-
TestData *test_data;
275-
280+
const struct CheckerContext: BaseSignatureChecker {
276281
// Signature checker methods. Checks the right dummy signature is used.
277282
bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& vchPubKey,
278283
const CScript& scriptCode, SigVersion sigversion) const override
@@ -294,7 +299,7 @@ struct CheckerContext: BaseSignatureChecker {
294299
} CHECKER_CTX;
295300

296301
//! Context to check for duplicates when instancing a Node.
297-
struct KeyComparator {
302+
const struct KeyComparator {
298303
bool KeyCompare(const CPubKey& a, const CPubKey& b) const {
299304
return a < b;
300305
}
@@ -1027,15 +1032,15 @@ void TestNode(const MsCtx script_ctx, const NodeRef& node, FuzzedDataProvider& p
10271032
if (!node) return;
10281033

10291034
// Check that it roundtrips to text representation
1030-
PARSER_CTX.script_ctx = script_ctx;
1031-
std::optional<std::string> str{node->ToString(PARSER_CTX)};
1035+
const ParserContext parser_ctx{script_ctx};
1036+
std::optional<std::string> str{node->ToString(parser_ctx)};
10321037
assert(str);
1033-
auto parsed = miniscript::FromString(*str, PARSER_CTX);
1038+
auto parsed = miniscript::FromString(*str, parser_ctx);
10341039
assert(parsed);
10351040
assert(*parsed == *node);
10361041

10371042
// Check consistency between script size estimation and real size.
1038-
auto script = node->ToScript(PARSER_CTX);
1043+
auto script = node->ToScript(parser_ctx);
10391044
assert(node->ScriptSize() == script.size());
10401045

10411046
// Check consistency of "x" property with the script (type K is excluded, because it can end
@@ -1049,12 +1054,12 @@ void TestNode(const MsCtx script_ctx, const NodeRef& node, FuzzedDataProvider& p
10491054
if (!node->IsValidTopLevel()) return;
10501055

10511056
// Check roundtrip to script
1052-
auto decoded = miniscript::FromScript(script, PARSER_CTX);
1057+
auto decoded = miniscript::FromScript(script, parser_ctx);
10531058
assert(decoded);
10541059
// Note we can't use *decoded == *node because the miniscript representation may differ, so we check that:
10551060
// - The script corresponding to that decoded form matches exactly
10561061
// - The type matches exactly
1057-
assert(decoded->ToScript(PARSER_CTX) == script);
1062+
assert(decoded->ToScript(parser_ctx) == script);
10581063
assert(decoded->GetType() == node->GetType());
10591064

10601065
// Optionally pad the script or the witness in order to increase the sensitivity of the tests of
@@ -1091,19 +1096,19 @@ void TestNode(const MsCtx script_ctx, const NodeRef& node, FuzzedDataProvider& p
10911096
}
10921097
}
10931098

1094-
SATISFIER_CTX.script_ctx = script_ctx;
1099+
const SatisfierContext satisfier_ctx{script_ctx};
10951100

10961101
// Get the ScriptPubKey for this script, filling spend data if it's Taproot.
10971102
TaprootBuilder builder;
10981103
const CScript script_pubkey{ScriptPubKey(script_ctx, script, builder)};
10991104

11001105
// Run malleable satisfaction algorithm.
11011106
std::vector<std::vector<unsigned char>> stack_mal;
1102-
const bool mal_success = node->Satisfy(SATISFIER_CTX, stack_mal, false) == miniscript::Availability::YES;
1107+
const bool mal_success = node->Satisfy(satisfier_ctx, stack_mal, false) == miniscript::Availability::YES;
11031108

11041109
// Run non-malleable satisfaction algorithm.
11051110
std::vector<std::vector<unsigned char>> stack_nonmal;
1106-
const bool nonmal_success = node->Satisfy(SATISFIER_CTX, stack_nonmal, true) == miniscript::Availability::YES;
1111+
const bool nonmal_success = node->Satisfy(satisfier_ctx, stack_nonmal, true) == miniscript::Availability::YES;
11071112

11081113
if (nonmal_success) {
11091114
// Non-malleable satisfactions are bounded by the satisfaction size plus:
@@ -1229,13 +1234,13 @@ FUZZ_TARGET(miniscript_string, .init = FuzzInit)
12291234
if (buffer.empty()) return;
12301235
FuzzedDataProvider provider(buffer.data(), buffer.size());
12311236
auto str = provider.ConsumeBytesAsString(provider.remaining_bytes() - 1);
1232-
PARSER_CTX.script_ctx = (MsCtx)provider.ConsumeBool();
1233-
auto parsed = miniscript::FromString(str, PARSER_CTX);
1237+
const ParserContext parser_ctx{(MsCtx)provider.ConsumeBool()};
1238+
auto parsed = miniscript::FromString(str, parser_ctx);
12341239
if (!parsed) return;
12351240

1236-
const auto str2 = parsed->ToString(PARSER_CTX);
1241+
const auto str2 = parsed->ToString(parser_ctx);
12371242
assert(str2);
1238-
auto parsed2 = miniscript::FromString(*str2, PARSER_CTX);
1243+
auto parsed2 = miniscript::FromString(*str2, parser_ctx);
12391244
assert(parsed2);
12401245
assert(*parsed == *parsed2);
12411246
}
@@ -1247,9 +1252,9 @@ FUZZ_TARGET(miniscript_script)
12471252
const std::optional<CScript> script = ConsumeDeserializable<CScript>(fuzzed_data_provider);
12481253
if (!script) return;
12491254

1250-
SCRIPT_PARSER_CONTEXT.script_ctx = (MsCtx)fuzzed_data_provider.ConsumeBool();
1251-
const auto ms = miniscript::FromScript(*script, SCRIPT_PARSER_CONTEXT);
1255+
const ScriptParserContext script_parser_ctx{(MsCtx)fuzzed_data_provider.ConsumeBool()};
1256+
const auto ms = miniscript::FromScript(*script, script_parser_ctx);
12521257
if (!ms) return;
12531258

1254-
assert(ms->ToScript(SCRIPT_PARSER_CONTEXT) == *script);
1259+
assert(ms->ToScript(script_parser_ctx) == *script);
12551260
}

0 commit comments

Comments
 (0)