@@ -67,12 +67,11 @@ struct TestData {
6767 if (i & 1 ) hash160_preimages[hash] = std::vector<unsigned char >(keydata, keydata + 32 );
6868 }
6969 }
70- };
70+ } TEST_DATA ;
7171
7272// ! Context to parse a Miniscript node to and from Script or text representation.
7373struct ParserContext {
7474 typedef CPubKey Key;
75- TestData *test_data;
7675
7776 bool ToString (const Key& key, std::string& ret) const { ret = HexStr (key); return true ; }
7877
@@ -101,12 +100,12 @@ struct ParserContext {
101100 assert (last - first == 20 );
102101 CKeyID keyid;
103102 std::copy (first, last, keyid.begin ());
104- const auto it = test_data-> dummy_keys_map .find (keyid);
105- if (it == test_data-> dummy_keys_map .end ()) return false ;
103+ const auto it = TEST_DATA. dummy_keys_map .find (keyid);
104+ if (it == TEST_DATA. dummy_keys_map .end ()) return false ;
106105 key = it->second ;
107106 return true ;
108107 }
109- };
108+ } PARSER_CTX ;
110109
111110// ! Context to produce a satisfaction for a Miniscript node using the pre-computed data.
112111struct SatisfierContext : ParserContext {
@@ -117,8 +116,8 @@ struct SatisfierContext: ParserContext {
117116
118117 // Signature challenges fulfilled with a dummy signature, if it was one of our dummy keys.
119118 miniscript::Availability Sign (const CPubKey& key, std::vector<unsigned char >& sig) const {
120- const auto it = test_data-> dummy_sigs .find (key);
121- if (it == test_data-> dummy_sigs .end ()) return miniscript::Availability::NO;
119+ const auto it = TEST_DATA. dummy_sigs .find (key);
120+ if (it == TEST_DATA. dummy_sigs .end ()) return miniscript::Availability::NO;
122121 if (it->second .second ) {
123122 // Key is "available"
124123 sig = it->second .first ;
@@ -138,18 +137,18 @@ struct SatisfierContext: ParserContext {
138137 return miniscript::Availability::YES;
139138 }
140139 miniscript::Availability SatSHA256 (const std::vector<unsigned char >& hash, std::vector<unsigned char >& preimage) const {
141- return LookupHash (hash, preimage, test_data-> sha256_preimages );
140+ return LookupHash (hash, preimage, TEST_DATA. sha256_preimages );
142141 }
143142 miniscript::Availability SatRIPEMD160 (const std::vector<unsigned char >& hash, std::vector<unsigned char >& preimage) const {
144- return LookupHash (hash, preimage, test_data-> ripemd160_preimages );
143+ return LookupHash (hash, preimage, TEST_DATA. ripemd160_preimages );
145144 }
146145 miniscript::Availability SatHASH256 (const std::vector<unsigned char >& hash, std::vector<unsigned char >& preimage) const {
147- return LookupHash (hash, preimage, test_data-> hash256_preimages );
146+ return LookupHash (hash, preimage, TEST_DATA. hash256_preimages );
148147 }
149148 miniscript::Availability SatHASH160 (const std::vector<unsigned char >& hash, std::vector<unsigned char >& preimage) const {
150- return LookupHash (hash, preimage, test_data-> hash160_preimages );
149+ return LookupHash (hash, preimage, TEST_DATA. hash160_preimages );
151150 }
152- };
151+ } SATISFIER_CTX ;
153152
154153// ! Context to check a satisfaction against the pre-computed data.
155154struct CheckerContext : BaseSignatureChecker {
@@ -160,19 +159,14 @@ struct CheckerContext: BaseSignatureChecker {
160159 const CScript& scriptCode, SigVersion sigversion) const override
161160 {
162161 const CPubKey key{vchPubKey};
163- const auto it = test_data-> dummy_sigs .find (key);
164- if (it == test_data-> dummy_sigs .end ()) return false ;
162+ const auto it = TEST_DATA. dummy_sigs .find (key);
163+ if (it == TEST_DATA. dummy_sigs .end ()) return false ;
165164 return it->second .first == sig;
166165 }
167166 bool CheckLockTime (const CScriptNum& nLockTime) const override { return nLockTime.GetInt64 () & 1 ; }
168167 bool CheckSequence (const CScriptNum& nSequence) const override { return nSequence.GetInt64 () & 1 ; }
169- };
168+ } CHECKER_CTX ;
170169
171- // The various contexts
172- TestData TEST_DATA;
173- ParserContext PARSER_CTX;
174- SatisfierContext SATISFIER_CTX;
175- CheckerContext CHECKER_CTX;
176170// A dummy scriptsig to pass to VerifyScript (we always use Segwit v0).
177171const CScript DUMMY_SCRIPTSIG;
178172
@@ -323,7 +317,7 @@ struct SmartInfo
323317 using recipe = std::pair<Fragment, std::vector<Type>>;
324318 std::map<Type, std::vector<recipe>> table;
325319
326- SmartInfo ()
320+ void Init ()
327321 {
328322 /* Construct a set of interesting type requirements to reason with (sections of BKVWzondu). */
329323 std::vector<Type> types;
@@ -550,7 +544,7 @@ struct SmartInfo
550544 );
551545 }
552546 }
553- };
547+ } SMARTINFO ;
554548
555549/* *
556550 * Consume a Miniscript node from the fuzzer's output.
@@ -563,11 +557,9 @@ struct SmartInfo
563557 * everything).
564558 */
565559std::optional<NodeInfo> ConsumeNodeSmart (FuzzedDataProvider& provider, Type type_needed) {
566- /* * Precompute table once, but only when this function is invoked (it can take ~seconds). */
567- static const SmartInfo g_smartinfo;
568560 /* * Table entry for the requested type. */
569- auto recipes_it = g_smartinfo .table .find (type_needed);
570- assert (recipes_it != g_smartinfo .table .end ());
561+ auto recipes_it = SMARTINFO .table .find (type_needed);
562+ assert (recipes_it != SMARTINFO .table .end ());
571563 /* * Pick one recipe from the available ones for that type. */
572564 const auto & [frag, subt] = PickValue (provider, recipes_it->second );
573565
@@ -695,15 +687,6 @@ NodeRef GenNode(F ConsumeNode, Type root_type = ""_mst, bool strict_valid = fals
695687 return std::move (stack[0 ]);
696688}
697689
698- // ! Pre-compute the test data and point the various contexts to it.
699- void initialize_miniscript_random () {
700- ECC_Start ();
701- TEST_DATA.Init ();
702- PARSER_CTX.test_data = &TEST_DATA;
703- SATISFIER_CTX.test_data = &TEST_DATA;
704- CHECKER_CTX.test_data = &TEST_DATA;
705- }
706-
707690/* * Perform various applicable tests on a miniscript Node. */
708691void TestNode (const NodeRef& node, FuzzedDataProvider& provider)
709692{
@@ -839,10 +822,22 @@ void TestNode(const NodeRef& node, FuzzedDataProvider& provider)
839822 assert (mal_success == satisfiable);
840823}
841824
825+ void FuzzInit ()
826+ {
827+ ECC_Start ();
828+ TEST_DATA.Init ();
829+ }
830+
831+ void FuzzInitSmart ()
832+ {
833+ FuzzInit ();
834+ SMARTINFO.Init ();
835+ }
836+
842837} // namespace
843838
844839/* * Fuzz target that runs TestNode on nodes generated using ConsumeNodeStable. */
845- FUZZ_TARGET_INIT (miniscript_random_stable, initialize_miniscript_random )
840+ FUZZ_TARGET_INIT (miniscript_random_stable, FuzzInit )
846841{
847842 FuzzedDataProvider provider (buffer.data (), buffer.size ());
848843 TestNode (GenNode ([&](Type) {
@@ -851,7 +846,7 @@ FUZZ_TARGET_INIT(miniscript_random_stable, initialize_miniscript_random)
851846}
852847
853848/* * Fuzz target that runs TestNode on nodes generated using ConsumeNodeSmart. */
854- FUZZ_TARGET_INIT (miniscript_random_smart, initialize_miniscript_random )
849+ FUZZ_TARGET_INIT (miniscript_random_smart, FuzzInitSmart )
855850{
856851 /* * The set of types we aim to construct nodes for. Together they cover all. */
857852 static constexpr std::array<Type, 4 > BASE_TYPES{" B" _mst, " V" _mst, " K" _mst, " W" _mst};
0 commit comments