Skip to content

Commit b4c84ba

Browse files
committed
Simplify miniscript_random initialization
1 parent 5f10e1a commit b4c84ba

File tree

1 file changed

+32
-37
lines changed

1 file changed

+32
-37
lines changed

bitcoin/test/fuzz/miniscript_random.cpp

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
7373
struct 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.
112111
struct 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.
155154
struct 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).
177171
const 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
*/
565559
std::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. */
708691
void 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

Comments
 (0)