Bitcoin Core  25.99.0
P2P Digital Currency
miniscript.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021-2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <core_io.h>
6 #include <hash.h>
7 #include <key.h>
8 #include <script/miniscript.h>
9 #include <script/script.h>
11 #include <test/fuzz/fuzz.h>
12 #include <test/fuzz/util.h>
13 #include <util/strencodings.h>
14 
15 namespace {
16 
18 struct TestData {
19  typedef CPubKey Key;
20 
21  // Precomputed public keys, and a dummy signature for each of them.
22  std::vector<Key> dummy_keys;
23  std::map<Key, int> dummy_key_idx_map;
24  std::map<CKeyID, Key> dummy_keys_map;
25  std::map<Key, std::pair<std::vector<unsigned char>, bool>> dummy_sigs;
26 
27  // Precomputed hashes of each kind.
28  std::vector<std::vector<unsigned char>> sha256;
29  std::vector<std::vector<unsigned char>> ripemd160;
30  std::vector<std::vector<unsigned char>> hash256;
31  std::vector<std::vector<unsigned char>> hash160;
32  std::map<std::vector<unsigned char>, std::vector<unsigned char>> sha256_preimages;
33  std::map<std::vector<unsigned char>, std::vector<unsigned char>> ripemd160_preimages;
34  std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash256_preimages;
35  std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash160_preimages;
36 
38  void Init() {
39  unsigned char keydata[32] = {1};
40  for (size_t i = 0; i < 256; i++) {
41  keydata[31] = i;
42  CKey privkey;
43  privkey.Set(keydata, keydata + 32, true);
44  const Key pubkey = privkey.GetPubKey();
45 
46  dummy_keys.push_back(pubkey);
47  dummy_key_idx_map.emplace(pubkey, i);
48  dummy_keys_map.insert({pubkey.GetID(), pubkey});
49 
50  std::vector<unsigned char> sig;
51  privkey.Sign(uint256S(""), sig);
52  sig.push_back(1); // SIGHASH_ALL
53  dummy_sigs.insert({pubkey, {sig, i & 1}});
54 
55  std::vector<unsigned char> hash;
56  hash.resize(32);
57  CSHA256().Write(keydata, 32).Finalize(hash.data());
58  sha256.push_back(hash);
59  if (i & 1) sha256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
60  CHash256().Write(keydata).Finalize(hash);
61  hash256.push_back(hash);
62  if (i & 1) hash256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
63  hash.resize(20);
64  CRIPEMD160().Write(keydata, 32).Finalize(hash.data());
65  assert(hash.size() == 20);
66  ripemd160.push_back(hash);
67  if (i & 1) ripemd160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
68  CHash160().Write(keydata).Finalize(hash);
69  hash160.push_back(hash);
70  if (i & 1) hash160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
71  }
72  }
73 } TEST_DATA;
74 
80 struct ParserContext {
81  typedef CPubKey Key;
82 
83  bool KeyCompare(const Key& a, const Key& b) const {
84  return a < b;
85  }
86 
87  std::optional<std::string> ToString(const Key& key) const
88  {
89  auto it = TEST_DATA.dummy_key_idx_map.find(key);
90  if (it == TEST_DATA.dummy_key_idx_map.end()) return {};
91  uint8_t idx = it->second;
92  return HexStr(Span{&idx, 1});
93  }
94 
95  std::vector<unsigned char> ToPKBytes(const Key& key) const
96  {
97  return {key.begin(), key.end()};
98  }
99 
100  std::vector<unsigned char> ToPKHBytes(const Key& key) const
101  {
102  const auto h = Hash160(key);
103  return {h.begin(), h.end()};
104  }
105 
106  template<typename I>
107  std::optional<Key> FromString(I first, I last) const {
108  if (last - first != 2) return {};
109  auto idx = ParseHex(std::string(first, last));
110  if (idx.size() != 1) return {};
111  return TEST_DATA.dummy_keys[idx[0]];
112  }
113 
114  template<typename I>
115  std::optional<Key> FromPKBytes(I first, I last) const {
116  CPubKey key;
117  key.Set(first, last);
118  if (!key.IsValid()) return {};
119  return key;
120  }
121 
122  template<typename I>
123  std::optional<Key> FromPKHBytes(I first, I last) const {
124  assert(last - first == 20);
125  CKeyID keyid;
126  std::copy(first, last, keyid.begin());
127  const auto it = TEST_DATA.dummy_keys_map.find(keyid);
128  if (it == TEST_DATA.dummy_keys_map.end()) return {};
129  return it->second;
130  }
131 } PARSER_CTX;
132 
134 struct ScriptParserContext {
136  struct Key {
137  bool is_hash;
138  std::vector<unsigned char> data;
139  };
140 
141  bool KeyCompare(const Key& a, const Key& b) const {
142  return a.data < b.data;
143  }
144 
145  const std::vector<unsigned char>& ToPKBytes(const Key& key) const
146  {
147  assert(!key.is_hash);
148  return key.data;
149  }
150 
151  std::vector<unsigned char> ToPKHBytes(const Key& key) const
152  {
153  if (key.is_hash) return key.data;
154  const auto h = Hash160(key.data);
155  return {h.begin(), h.end()};
156  }
157 
158  template<typename I>
159  std::optional<Key> FromPKBytes(I first, I last) const
160  {
161  Key key;
162  key.data.assign(first, last);
163  key.is_hash = false;
164  return key;
165  }
166 
167  template<typename I>
168  std::optional<Key> FromPKHBytes(I first, I last) const
169  {
170  Key key;
171  key.data.assign(first, last);
172  key.is_hash = true;
173  return key;
174  }
175 } SCRIPT_PARSER_CONTEXT;
176 
178 struct SatisfierContext: ParserContext {
179  // Timelock challenges satisfaction. Make the value (deterministically) vary to explore different
180  // paths.
181  bool CheckAfter(uint32_t value) const { return value % 2; }
182  bool CheckOlder(uint32_t value) const { return value % 2; }
183 
184  // Signature challenges fulfilled with a dummy signature, if it was one of our dummy keys.
185  miniscript::Availability Sign(const CPubKey& key, std::vector<unsigned char>& sig) const {
186  const auto it = TEST_DATA.dummy_sigs.find(key);
187  if (it == TEST_DATA.dummy_sigs.end()) return miniscript::Availability::NO;
188  if (it->second.second) {
189  // Key is "available"
190  sig = it->second.first;
192  } else {
194  }
195  }
196 
198  miniscript::Availability LookupHash(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage,
199  const std::map<std::vector<unsigned char>, std::vector<unsigned char>>& map) const
200  {
201  const auto it = map.find(hash);
202  if (it == map.end()) return miniscript::Availability::NO;
203  preimage = it->second;
205  }
206  miniscript::Availability SatSHA256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
207  return LookupHash(hash, preimage, TEST_DATA.sha256_preimages);
208  }
209  miniscript::Availability SatRIPEMD160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
210  return LookupHash(hash, preimage, TEST_DATA.ripemd160_preimages);
211  }
212  miniscript::Availability SatHASH256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
213  return LookupHash(hash, preimage, TEST_DATA.hash256_preimages);
214  }
215  miniscript::Availability SatHASH160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
216  return LookupHash(hash, preimage, TEST_DATA.hash160_preimages);
217  }
218 } SATISFIER_CTX;
219 
221 struct CheckerContext: BaseSignatureChecker {
222  TestData *test_data;
223 
224  // Signature checker methods. Checks the right dummy signature is used.
225  bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& vchPubKey,
226  const CScript& scriptCode, SigVersion sigversion) const override
227  {
228  const CPubKey key{vchPubKey};
229  const auto it = TEST_DATA.dummy_sigs.find(key);
230  if (it == TEST_DATA.dummy_sigs.end()) return false;
231  return it->second.first == sig;
232  }
233  bool CheckLockTime(const CScriptNum& nLockTime) const override { return nLockTime.GetInt64() & 1; }
234  bool CheckSequence(const CScriptNum& nSequence) const override { return nSequence.GetInt64() & 1; }
235 } CHECKER_CTX;
236 
238 struct KeyComparator {
239  bool KeyCompare(const CPubKey& a, const CPubKey& b) const {
240  return a < b;
241  }
242 } KEY_COMP;
243 
244 // A dummy scriptsig to pass to VerifyScript (we always use Segwit v0).
245 const CScript DUMMY_SCRIPTSIG;
246 
249 using Node = miniscript::Node<CPubKey>;
250 using Type = miniscript::Type;
251 using miniscript::operator"" _mst;
252 
254 template<typename... Args> NodeRef MakeNodeRef(Args&&... args) {
255  return miniscript::MakeNodeRef<CPubKey>(miniscript::internal::NoDupCheck{}, std::forward<Args>(args)...);
256 }
257 
259 struct NodeInfo {
261  Fragment fragment;
263  uint32_t k;
265  std::vector<CPubKey> keys;
267  std::vector<unsigned char> hash;
269  std::vector<Type> subtypes;
270 
271  NodeInfo(Fragment frag): fragment(frag), k(0) {}
272  NodeInfo(Fragment frag, CPubKey key): fragment(frag), k(0), keys({key}) {}
273  NodeInfo(Fragment frag, uint32_t _k): fragment(frag), k(_k) {}
274  NodeInfo(Fragment frag, std::vector<unsigned char> h): fragment(frag), k(0), hash(std::move(h)) {}
275  NodeInfo(std::vector<Type> subt, Fragment frag): fragment(frag), k(0), subtypes(std::move(subt)) {}
276  NodeInfo(std::vector<Type> subt, Fragment frag, uint32_t _k): fragment(frag), k(_k), subtypes(std::move(subt)) {}
277  NodeInfo(Fragment frag, uint32_t _k, std::vector<CPubKey> _keys): fragment(frag), k(_k), keys(std::move(_keys)) {}
278 };
279 
281 template<typename T, typename A>
282 T ConsumeIndex(FuzzedDataProvider& provider, A& col) {
283  const uint8_t i = provider.ConsumeIntegral<uint8_t>();
284  return col[i];
285 }
286 
287 CPubKey ConsumePubKey(FuzzedDataProvider& provider) {
288  return ConsumeIndex<CPubKey>(provider, TEST_DATA.dummy_keys);
289 }
290 
291 std::vector<unsigned char> ConsumeSha256(FuzzedDataProvider& provider) {
292  return ConsumeIndex<std::vector<unsigned char>>(provider, TEST_DATA.sha256);
293 }
294 
295 std::vector<unsigned char> ConsumeHash256(FuzzedDataProvider& provider) {
296  return ConsumeIndex<std::vector<unsigned char>>(provider, TEST_DATA.hash256);
297 }
298 
299 std::vector<unsigned char> ConsumeRipemd160(FuzzedDataProvider& provider) {
300  return ConsumeIndex<std::vector<unsigned char>>(provider, TEST_DATA.ripemd160);
301 }
302 
303 std::vector<unsigned char> ConsumeHash160(FuzzedDataProvider& provider) {
304  return ConsumeIndex<std::vector<unsigned char>>(provider, TEST_DATA.hash160);
305 }
306 
307 std::optional<uint32_t> ConsumeTimeLock(FuzzedDataProvider& provider) {
308  const uint32_t k = provider.ConsumeIntegral<uint32_t>();
309  if (k == 0 || k >= 0x80000000) return {};
310  return k;
311 }
312 
326 std::optional<NodeInfo> ConsumeNodeStable(FuzzedDataProvider& provider, Type type_needed) {
327  bool allow_B = (type_needed == ""_mst) || (type_needed << "B"_mst);
328  bool allow_K = (type_needed == ""_mst) || (type_needed << "K"_mst);
329  bool allow_V = (type_needed == ""_mst) || (type_needed << "V"_mst);
330  bool allow_W = (type_needed == ""_mst) || (type_needed << "W"_mst);
331 
332  switch (provider.ConsumeIntegral<uint8_t>()) {
333  case 0:
334  if (!allow_B) return {};
335  return {{Fragment::JUST_0}};
336  case 1:
337  if (!allow_B) return {};
338  return {{Fragment::JUST_1}};
339  case 2:
340  if (!allow_K) return {};
341  return {{Fragment::PK_K, ConsumePubKey(provider)}};
342  case 3:
343  if (!allow_K) return {};
344  return {{Fragment::PK_H, ConsumePubKey(provider)}};
345  case 4: {
346  if (!allow_B) return {};
347  const auto k = ConsumeTimeLock(provider);
348  if (!k) return {};
349  return {{Fragment::OLDER, *k}};
350  }
351  case 5: {
352  if (!allow_B) return {};
353  const auto k = ConsumeTimeLock(provider);
354  if (!k) return {};
355  return {{Fragment::AFTER, *k}};
356  }
357  case 6:
358  if (!allow_B) return {};
359  return {{Fragment::SHA256, ConsumeSha256(provider)}};
360  case 7:
361  if (!allow_B) return {};
362  return {{Fragment::HASH256, ConsumeHash256(provider)}};
363  case 8:
364  if (!allow_B) return {};
365  return {{Fragment::RIPEMD160, ConsumeRipemd160(provider)}};
366  case 9:
367  if (!allow_B) return {};
368  return {{Fragment::HASH160, ConsumeHash160(provider)}};
369  case 10: {
370  if (!allow_B) return {};
371  const auto k = provider.ConsumeIntegral<uint8_t>();
372  const auto n_keys = provider.ConsumeIntegral<uint8_t>();
373  if (n_keys > 20 || k == 0 || k > n_keys) return {};
374  std::vector<CPubKey> keys{n_keys};
375  for (auto& key: keys) key = ConsumePubKey(provider);
376  return {{Fragment::MULTI, k, std::move(keys)}};
377  }
378  case 11:
379  if (!(allow_B || allow_K || allow_V)) return {};
380  return {{{"B"_mst, type_needed, type_needed}, Fragment::ANDOR}};
381  case 12:
382  if (!(allow_B || allow_K || allow_V)) return {};
383  return {{{"V"_mst, type_needed}, Fragment::AND_V}};
384  case 13:
385  if (!allow_B) return {};
386  return {{{"B"_mst, "W"_mst}, Fragment::AND_B}};
387  case 15:
388  if (!allow_B) return {};
389  return {{{"B"_mst, "W"_mst}, Fragment::OR_B}};
390  case 16:
391  if (!allow_V) return {};
392  return {{{"B"_mst, "V"_mst}, Fragment::OR_C}};
393  case 17:
394  if (!allow_B) return {};
395  return {{{"B"_mst, "B"_mst}, Fragment::OR_D}};
396  case 18:
397  if (!(allow_B || allow_K || allow_V)) return {};
398  return {{{type_needed, type_needed}, Fragment::OR_I}};
399  case 19: {
400  if (!allow_B) return {};
401  auto k = provider.ConsumeIntegral<uint8_t>();
402  auto n_subs = provider.ConsumeIntegral<uint8_t>();
403  if (k == 0 || k > n_subs) return {};
404  std::vector<Type> subtypes;
405  subtypes.reserve(n_subs);
406  subtypes.emplace_back("B"_mst);
407  for (size_t i = 1; i < n_subs; ++i) subtypes.emplace_back("W"_mst);
408  return {{std::move(subtypes), Fragment::THRESH, k}};
409  }
410  case 20:
411  if (!allow_W) return {};
412  return {{{"B"_mst}, Fragment::WRAP_A}};
413  case 21:
414  if (!allow_W) return {};
415  return {{{"B"_mst}, Fragment::WRAP_S}};
416  case 22:
417  if (!allow_B) return {};
418  return {{{"K"_mst}, Fragment::WRAP_C}};
419  case 23:
420  if (!allow_B) return {};
421  return {{{"V"_mst}, Fragment::WRAP_D}};
422  case 24:
423  if (!allow_V) return {};
424  return {{{"B"_mst}, Fragment::WRAP_V}};
425  case 25:
426  if (!allow_B) return {};
427  return {{{"B"_mst}, Fragment::WRAP_J}};
428  case 26:
429  if (!allow_B) return {};
430  return {{{"B"_mst}, Fragment::WRAP_N}};
431  default:
432  break;
433  }
434  return {};
435 }
436 
437 /* This structure contains a table which for each "target" Type a list of recipes
438  * to construct it, automatically inferred from the behavior of ComputeType.
439  * Note that the Types here are not the final types of the constructed Nodes, but
440  * just the subset that are required. For example, a recipe for the "Bo" type
441  * might construct a "Bondu" sha256() NodeInfo, but cannot construct a "Bz" older().
442  * Each recipe is a Fragment together with a list of required types for its subnodes.
443  */
444 struct SmartInfo
445 {
446  using recipe = std::pair<Fragment, std::vector<Type>>;
447  std::map<Type, std::vector<recipe>> table;
448 
449  void Init()
450  {
451  /* Construct a set of interesting type requirements to reason with (sections of BKVWzondu). */
452  std::vector<Type> types;
453  for (int base = 0; base < 4; ++base) { /* select from B,K,V,W */
454  Type type_base = base == 0 ? "B"_mst : base == 1 ? "K"_mst : base == 2 ? "V"_mst : "W"_mst;
455  for (int zo = 0; zo < 3; ++zo) { /* select from z,o,(none) */
456  Type type_zo = zo == 0 ? "z"_mst : zo == 1 ? "o"_mst : ""_mst;
457  for (int n = 0; n < 2; ++n) { /* select from (none),n */
458  if (zo == 0 && n == 1) continue; /* z conflicts with n */
459  if (base == 3 && n == 1) continue; /* W conflicts with n */
460  Type type_n = n == 0 ? ""_mst : "n"_mst;
461  for (int d = 0; d < 2; ++d) { /* select from (none),d */
462  if (base == 2 && d == 1) continue; /* V conflicts with d */
463  Type type_d = d == 0 ? ""_mst : "d"_mst;
464  for (int u = 0; u < 2; ++u) { /* select from (none),u */
465  if (base == 2 && u == 1) continue; /* V conflicts with u */
466  Type type_u = u == 0 ? ""_mst : "u"_mst;
467  Type type = type_base | type_zo | type_n | type_d | type_u;
468  types.push_back(type);
469  }
470  }
471  }
472  }
473  }
474 
475  /* We define a recipe a to be a super-recipe of recipe b if they use the same
476  * fragment, the same number of subexpressions, and each of a's subexpression
477  * types is a supertype of the corresponding subexpression type of b.
478  * Within the set of recipes for the construction of a given type requirement,
479  * no recipe should be a super-recipe of another (as the super-recipe is
480  * applicable in every place the sub-recipe is, the sub-recipe is redundant). */
481  auto is_super_of = [](const recipe& a, const recipe& b) {
482  if (a.first != b.first) return false;
483  if (a.second.size() != b.second.size()) return false;
484  for (size_t i = 0; i < a.second.size(); ++i) {
485  if (!(b.second[i] << a.second[i])) return false;
486  }
487  return true;
488  };
489 
490  /* Sort the type requirements. Subtypes will always sort later (e.g. Bondu will
491  * sort after Bo or Bu). As we'll be constructing recipes using these types, in
492  * order, in what follows, we'll construct super-recipes before sub-recipes.
493  * That means we never need to go back and delete a sub-recipe because a
494  * super-recipe got added. */
495  std::sort(types.begin(), types.end());
496 
497  // Iterate over all possible fragments.
498  for (int fragidx = 0; fragidx <= int(Fragment::MULTI); ++fragidx) {
499  int sub_count = 0;
500  int sub_range = 1;
501  size_t data_size = 0;
502  size_t n_keys = 0;
503  uint32_t k = 0;
504  Fragment frag{fragidx};
505 
506  // Based on the fragment, determine #subs/data/k/keys to pass to ComputeType. */
507  switch (frag) {
508  case Fragment::PK_K:
509  case Fragment::PK_H:
510  n_keys = 1;
511  break;
512  case Fragment::MULTI:
513  n_keys = 1;
514  k = 1;
515  break;
516  case Fragment::OLDER:
517  case Fragment::AFTER:
518  k = 1;
519  break;
520  case Fragment::SHA256:
521  case Fragment::HASH256:
522  data_size = 32;
523  break;
524  case Fragment::RIPEMD160:
525  case Fragment::HASH160:
526  data_size = 20;
527  break;
528  case Fragment::JUST_0:
529  case Fragment::JUST_1:
530  break;
531  case Fragment::WRAP_A:
532  case Fragment::WRAP_S:
533  case Fragment::WRAP_C:
534  case Fragment::WRAP_D:
535  case Fragment::WRAP_V:
536  case Fragment::WRAP_J:
537  case Fragment::WRAP_N:
538  sub_count = 1;
539  break;
540  case Fragment::AND_V:
541  case Fragment::AND_B:
542  case Fragment::OR_B:
543  case Fragment::OR_C:
544  case Fragment::OR_D:
545  case Fragment::OR_I:
546  sub_count = 2;
547  break;
548  case Fragment::ANDOR:
549  sub_count = 3;
550  break;
551  case Fragment::THRESH:
552  // Thresh logic is executed for 1 and 2 arguments. Larger numbers use ad-hoc code to extend.
553  sub_count = 1;
554  sub_range = 2;
555  k = 1;
556  break;
557  }
558 
559  // Iterate over the number of subnodes (sub_count...sub_count+sub_range-1).
560  std::vector<Type> subt;
561  for (int subs = sub_count; subs < sub_count + sub_range; ++subs) {
562  // Iterate over the possible subnode types (at most 3).
563  for (Type x : types) {
564  for (Type y : types) {
565  for (Type z : types) {
566  // Compute the resulting type of a node with the selected fragment / subnode types.
567  subt.clear();
568  if (subs > 0) subt.push_back(x);
569  if (subs > 1) subt.push_back(y);
570  if (subs > 2) subt.push_back(z);
571  Type res = miniscript::internal::ComputeType(frag, x, y, z, subt, k, data_size, subs, n_keys);
572  // Continue if the result is not a valid node.
573  if ((res << "K"_mst) + (res << "V"_mst) + (res << "B"_mst) + (res << "W"_mst) != 1) continue;
574 
575  recipe entry{frag, subt};
576  auto super_of_entry = [&](const recipe& rec) { return is_super_of(rec, entry); };
577  // Iterate over all supertypes of res (because if e.g. our selected fragment/subnodes result
578  // in a Bondu, they can form a recipe that is also applicable for constructing a B, Bou, Bdu, ...).
579  for (Type s : types) {
580  if ((res & "BKVWzondu"_mst) << s) {
581  auto& recipes = table[s];
582  // If we don't already have a super-recipe to the new one, add it.
583  if (!std::any_of(recipes.begin(), recipes.end(), super_of_entry)) {
584  recipes.push_back(entry);
585  }
586  }
587  }
588 
589  if (subs <= 2) break;
590  }
591  if (subs <= 1) break;
592  }
593  if (subs <= 0) break;
594  }
595  }
596  }
597 
598  /* Find which types are useful. The fuzzer logic only cares about constructing
599  * B,V,K,W nodes, so any type that isn't needed in any recipe (directly or
600  * indirectly) for the construction of those is uninteresting. */
601  std::set<Type> useful_types{"B"_mst, "V"_mst, "K"_mst, "W"_mst};
602  // Find the transitive closure by adding types until the set of types does not change.
603  while (true) {
604  size_t set_size = useful_types.size();
605  for (const auto& [type, recipes] : table) {
606  if (useful_types.count(type) != 0) {
607  for (const auto& [_, subtypes] : recipes) {
608  for (auto subtype : subtypes) useful_types.insert(subtype);
609  }
610  }
611  }
612  if (useful_types.size() == set_size) break;
613  }
614  // Remove all rules that construct uninteresting types.
615  for (auto type_it = table.begin(); type_it != table.end();) {
616  if (useful_types.count(type_it->first) == 0) {
617  type_it = table.erase(type_it);
618  } else {
619  ++type_it;
620  }
621  }
622 
623  /* Find which types are constructible. A type is constructible if there is a leaf
624  * node recipe for constructing it, or a recipe whose subnodes are all constructible.
625  * Types can be non-constructible because they have no recipes to begin with,
626  * because they can only be constructed using recipes that involve otherwise
627  * non-constructible types, or because they require infinite recursion. */
628  std::set<Type> constructible_types{};
629  auto known_constructible = [&](Type type) { return constructible_types.count(type) != 0; };
630  // Find the transitive closure by adding types until the set of types does not change.
631  while (true) {
632  size_t set_size = constructible_types.size();
633  // Iterate over all types we have recipes for.
634  for (const auto& [type, recipes] : table) {
635  if (!known_constructible(type)) {
636  // For not (yet known to be) constructible types, iterate over their recipes.
637  for (const auto& [_, subt] : recipes) {
638  // If any recipe involves only (already known to be) constructible types,
639  // add the recipe's type to the set.
640  if (std::all_of(subt.begin(), subt.end(), known_constructible)) {
641  constructible_types.insert(type);
642  break;
643  }
644  }
645  }
646  }
647  if (constructible_types.size() == set_size) break;
648  }
649  for (auto type_it = table.begin(); type_it != table.end();) {
650  // Remove all recipes which involve non-constructible types.
651  type_it->second.erase(std::remove_if(type_it->second.begin(), type_it->second.end(),
652  [&](const recipe& rec) {
653  return !std::all_of(rec.second.begin(), rec.second.end(), known_constructible);
654  }), type_it->second.end());
655  // Delete types entirely which have no recipes left.
656  if (type_it->second.empty()) {
657  type_it = table.erase(type_it);
658  } else {
659  ++type_it;
660  }
661  }
662 
663  for (auto& [type, recipes] : table) {
664  // Sort recipes for determinism, and place those using fewer subnodes first.
665  // This avoids runaway expansion (when reaching the end of the fuzz input,
666  // all zeroes are read, resulting in the first available recipe being picked).
667  std::sort(recipes.begin(), recipes.end(),
668  [](const recipe& a, const recipe& b) {
669  if (a.second.size() < b.second.size()) return true;
670  if (a.second.size() > b.second.size()) return false;
671  return a < b;
672  }
673  );
674  }
675  }
676 } SMARTINFO;
677 
688 std::optional<NodeInfo> ConsumeNodeSmart(FuzzedDataProvider& provider, Type type_needed) {
690  auto recipes_it = SMARTINFO.table.find(type_needed);
691  assert(recipes_it != SMARTINFO.table.end());
693  const auto& [frag, subt] = PickValue(provider, recipes_it->second);
694 
695  // Based on the fragment the recipe uses, fill in other data (k, keys, data).
696  switch (frag) {
697  case Fragment::PK_K:
698  case Fragment::PK_H:
699  return {{frag, ConsumePubKey(provider)}};
700  case Fragment::MULTI: {
701  const auto n_keys = provider.ConsumeIntegralInRange<uint8_t>(1, 20);
702  const auto k = provider.ConsumeIntegralInRange<uint8_t>(1, n_keys);
703  std::vector<CPubKey> keys{n_keys};
704  for (auto& key: keys) key = ConsumePubKey(provider);
705  return {{frag, k, std::move(keys)}};
706  }
707  case Fragment::OLDER:
708  case Fragment::AFTER:
709  return {{frag, provider.ConsumeIntegralInRange<uint32_t>(1, 0x7FFFFFF)}};
710  case Fragment::SHA256:
711  return {{frag, PickValue(provider, TEST_DATA.sha256)}};
712  case Fragment::HASH256:
713  return {{frag, PickValue(provider, TEST_DATA.hash256)}};
714  case Fragment::RIPEMD160:
715  return {{frag, PickValue(provider, TEST_DATA.ripemd160)}};
716  case Fragment::HASH160:
717  return {{frag, PickValue(provider, TEST_DATA.hash160)}};
718  case Fragment::JUST_0:
719  case Fragment::JUST_1:
720  case Fragment::WRAP_A:
721  case Fragment::WRAP_S:
722  case Fragment::WRAP_C:
723  case Fragment::WRAP_D:
724  case Fragment::WRAP_V:
725  case Fragment::WRAP_J:
726  case Fragment::WRAP_N:
727  case Fragment::AND_V:
728  case Fragment::AND_B:
729  case Fragment::OR_B:
730  case Fragment::OR_C:
731  case Fragment::OR_D:
732  case Fragment::OR_I:
733  case Fragment::ANDOR:
734  return {{subt, frag}};
735  case Fragment::THRESH: {
736  uint32_t children;
737  if (subt.size() < 2) {
738  children = subt.size();
739  } else {
740  // If we hit a thresh with 2 subnodes, artificially extend it to any number
741  // (2 or larger) by replicating the type of the last subnode.
742  children = provider.ConsumeIntegralInRange<uint32_t>(2, MAX_OPS_PER_SCRIPT / 2);
743  }
744  auto k = provider.ConsumeIntegralInRange<uint32_t>(1, children);
745  std::vector<Type> subs = subt;
746  while (subs.size() < children) subs.push_back(subs.back());
747  return {{std::move(subs), frag, k}};
748  }
749  }
750 
751  assert(false);
752 }
753 
762 template<typename F>
763 NodeRef GenNode(F ConsumeNode, Type root_type, bool strict_valid = false) {
765  std::vector<NodeRef> stack;
767  std::vector<std::pair<Type, std::optional<NodeInfo>>> todo{{root_type, {}}};
769  uint32_t ops{0};
772  uint32_t scriptsize{1};
773 
774  while (!todo.empty()) {
775  // The expected type we have to construct.
776  auto type_needed = todo.back().first;
777  if (!todo.back().second) {
778  // Fragment/children have not been decided yet. Decide them.
779  auto node_info = ConsumeNode(type_needed);
780  if (!node_info) return {};
781  // Update predicted resource limits. Since every leaf Miniscript node is at least one
782  // byte long, we move one byte from each child to their parent. A similar technique is
783  // used in the miniscript::internal::Parse function to prevent runaway string parsing.
784  scriptsize += miniscript::internal::ComputeScriptLen(node_info->fragment, ""_mst, node_info->subtypes.size(), node_info->k, node_info->subtypes.size(), node_info->keys.size()) - 1;
785  if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
786  switch (node_info->fragment) {
787  case Fragment::JUST_0:
788  case Fragment::JUST_1:
789  break;
790  case Fragment::PK_K:
791  break;
792  case Fragment::PK_H:
793  ops += 3;
794  break;
795  case Fragment::OLDER:
796  case Fragment::AFTER:
797  ops += 1;
798  break;
799  case Fragment::RIPEMD160:
800  case Fragment::SHA256:
801  case Fragment::HASH160:
802  case Fragment::HASH256:
803  ops += 4;
804  break;
805  case Fragment::ANDOR:
806  ops += 3;
807  break;
808  case Fragment::AND_V:
809  break;
810  case Fragment::AND_B:
811  case Fragment::OR_B:
812  ops += 1;
813  break;
814  case Fragment::OR_C:
815  ops += 2;
816  break;
817  case Fragment::OR_D:
818  ops += 3;
819  break;
820  case Fragment::OR_I:
821  ops += 3;
822  break;
823  case Fragment::THRESH:
824  ops += node_info->subtypes.size();
825  break;
826  case Fragment::MULTI:
827  ops += 1;
828  break;
829  case Fragment::WRAP_A:
830  ops += 2;
831  break;
832  case Fragment::WRAP_S:
833  ops += 1;
834  break;
835  case Fragment::WRAP_C:
836  ops += 1;
837  break;
838  case Fragment::WRAP_D:
839  ops += 3;
840  break;
841  case Fragment::WRAP_V:
842  // We don't account for OP_VERIFY here; that will be corrected for when the actual
843  // node is constructed below.
844  break;
845  case Fragment::WRAP_J:
846  ops += 4;
847  break;
848  case Fragment::WRAP_N:
849  ops += 1;
850  break;
851  }
852  if (ops > MAX_OPS_PER_SCRIPT) return {};
853  auto subtypes = node_info->subtypes;
854  todo.back().second = std::move(node_info);
855  todo.reserve(todo.size() + subtypes.size());
856  // As elements on the todo stack are processed back to front, construct
857  // them in reverse order (so that the first subnode is generated first).
858  for (size_t i = 0; i < subtypes.size(); ++i) {
859  todo.emplace_back(*(subtypes.rbegin() + i), std::nullopt);
860  }
861  } else {
862  // The back of todo has fragment and number of children decided, and
863  // those children have been constructed at the back of stack. Pop
864  // that entry off todo, and use it to construct a new NodeRef on
865  // stack.
866  NodeInfo& info = *todo.back().second;
867  // Gather children from the back of stack.
868  std::vector<NodeRef> sub;
869  sub.reserve(info.subtypes.size());
870  for (size_t i = 0; i < info.subtypes.size(); ++i) {
871  sub.push_back(std::move(*(stack.end() - info.subtypes.size() + i)));
872  }
873  stack.erase(stack.end() - info.subtypes.size(), stack.end());
874  // Construct new NodeRef.
875  NodeRef node;
876  if (info.keys.empty()) {
877  node = MakeNodeRef(info.fragment, std::move(sub), std::move(info.hash), info.k);
878  } else {
879  assert(sub.empty());
880  assert(info.hash.empty());
881  node = MakeNodeRef(info.fragment, std::move(info.keys), info.k);
882  }
883  // Verify acceptability.
884  if (!node || (node->GetType() & "KVWB"_mst) == ""_mst) {
885  assert(!strict_valid);
886  return {};
887  }
888  if (!(type_needed == ""_mst)) {
889  assert(node->GetType() << type_needed);
890  }
891  if (!node->IsValid()) return {};
892  // Update resource predictions.
893  if (node->fragment == Fragment::WRAP_V && node->subs[0]->GetType() << "x"_mst) {
894  ops += 1;
895  scriptsize += 1;
896  }
897  if (ops > MAX_OPS_PER_SCRIPT) return {};
898  if (scriptsize > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
899  // Move it to the stack.
900  stack.push_back(std::move(node));
901  todo.pop_back();
902  }
903  }
904  assert(stack.size() == 1);
905  assert(stack[0]->GetStaticOps() == ops);
906  assert(stack[0]->ScriptSize() == scriptsize);
907  stack[0]->DuplicateKeyCheck(KEY_COMP);
908  return std::move(stack[0]);
909 }
910 
912 void TestNode(const NodeRef& node, FuzzedDataProvider& provider)
913 {
914  if (!node) return;
915 
916  // Check that it roundtrips to text representation
917  std::optional<std::string> str{node->ToString(PARSER_CTX)};
918  assert(str);
919  auto parsed = miniscript::FromString(*str, PARSER_CTX);
920  assert(parsed);
921  assert(*parsed == *node);
922 
923  // Check consistency between script size estimation and real size.
924  auto script = node->ToScript(PARSER_CTX);
925  assert(node->ScriptSize() == script.size());
926 
927  // Check consistency of "x" property with the script (type K is excluded, because it can end
928  // with a push of a key, which could match these opcodes).
929  if (!(node->GetType() << "K"_mst)) {
930  bool ends_in_verify = !(node->GetType() << "x"_mst);
931  assert(ends_in_verify == (script.back() == OP_CHECKSIG || script.back() == OP_CHECKMULTISIG || script.back() == OP_EQUAL));
932  }
933 
934  // The rest of the checks only apply when testing a valid top-level script.
935  if (!node->IsValidTopLevel()) return;
936 
937  // Check roundtrip to script
938  auto decoded = miniscript::FromScript(script, PARSER_CTX);
939  assert(decoded);
940  // Note we can't use *decoded == *node because the miniscript representation may differ, so we check that:
941  // - The script corresponding to that decoded form matches exactly
942  // - The type matches exactly
943  assert(decoded->ToScript(PARSER_CTX) == script);
944  assert(decoded->GetType() == node->GetType());
945 
946  const auto node_ops{node->GetOps()};
947  if (provider.ConsumeBool() && node_ops && *node_ops < MAX_OPS_PER_SCRIPT && node->ScriptSize() < MAX_STANDARD_P2WSH_SCRIPT_SIZE) {
948  // Optionally pad the script with OP_NOPs to max op the ops limit of the constructed script.
949  // This makes the script obviously not actually miniscript-compatible anymore, but the
950  // signatures constructed in this test don't commit to the script anyway, so the same
951  // miniscript satisfier will work. This increases the sensitivity of the test to the ops
952  // counting logic being too low, especially for simple scripts.
953  // Do this optionally because we're not solely interested in cases where the number of ops is
954  // maximal.
955  // Do not pad more than what would cause MAX_STANDARD_P2WSH_SCRIPT_SIZE to be reached, however,
956  // as that also invalidates scripts.
957  int add = std::min<int>(
958  MAX_OPS_PER_SCRIPT - *node_ops,
959  MAX_STANDARD_P2WSH_SCRIPT_SIZE - node->ScriptSize());
960  for (int i = 0; i < add; ++i) script.push_back(OP_NOP);
961  }
962 
963  // Run malleable satisfaction algorithm.
964  const CScript script_pubkey = CScript() << OP_0 << WitnessV0ScriptHash(script);
965  CScriptWitness witness_mal;
966  const bool mal_success = node->Satisfy(SATISFIER_CTX, witness_mal.stack, false) == miniscript::Availability::YES;
967  witness_mal.stack.push_back(std::vector<unsigned char>(script.begin(), script.end()));
968 
969  // Run non-malleable satisfaction algorithm.
970  CScriptWitness witness_nonmal;
971  const bool nonmal_success = node->Satisfy(SATISFIER_CTX, witness_nonmal.stack, true) == miniscript::Availability::YES;
972  witness_nonmal.stack.push_back(std::vector<unsigned char>(script.begin(), script.end()));
973 
974  if (nonmal_success) {
975  // Non-malleable satisfactions are bounded by GetStackSize().
976  assert(witness_nonmal.stack.size() <= *node->GetStackSize() + 1);
977  // If a non-malleable satisfaction exists, the malleable one must also exist, and be identical to it.
978  assert(mal_success);
979  assert(witness_nonmal.stack == witness_mal.stack);
980 
981  // Test non-malleable satisfaction.
982  ScriptError serror;
983  bool res = VerifyScript(DUMMY_SCRIPTSIG, script_pubkey, &witness_nonmal, STANDARD_SCRIPT_VERIFY_FLAGS, CHECKER_CTX, &serror);
984  // Non-malleable satisfactions are guaranteed to be valid if ValidSatisfactions().
985  if (node->ValidSatisfactions()) assert(res);
986  // More detailed: non-malleable satisfactions must be valid, or could fail with ops count error (if CheckOpsLimit failed),
987  // or with a stack size error (if CheckStackSize check failed).
988  assert(res ||
989  (!node->CheckOpsLimit() && serror == ScriptError::SCRIPT_ERR_OP_COUNT) ||
990  (!node->CheckStackSize() && serror == ScriptError::SCRIPT_ERR_STACK_SIZE));
991  }
992 
993  if (mal_success && (!nonmal_success || witness_mal.stack != witness_nonmal.stack)) {
994  // Test malleable satisfaction only if it's different from the non-malleable one.
995  ScriptError serror;
996  bool res = VerifyScript(DUMMY_SCRIPTSIG, script_pubkey, &witness_mal, STANDARD_SCRIPT_VERIFY_FLAGS, CHECKER_CTX, &serror);
997  // Malleable satisfactions are not guaranteed to be valid under any conditions, but they can only
998  // fail due to stack or ops limits.
1000  }
1001 
1002  if (node->IsSane()) {
1003  // For sane nodes, the two algorithms behave identically.
1004  assert(mal_success == nonmal_success);
1005  }
1006 
1007  // Verify that if a node is policy-satisfiable, the malleable satisfaction
1008  // algorithm succeeds. Given that under IsSane() both satisfactions
1009  // are identical, this implies that for such nodes, the non-malleable
1010  // satisfaction will also match the expected policy.
1011  bool satisfiable = node->IsSatisfiable([](const Node& node) -> bool {
1012  switch (node.fragment) {
1013  case Fragment::PK_K:
1014  case Fragment::PK_H: {
1015  auto it = TEST_DATA.dummy_sigs.find(node.keys[0]);
1016  assert(it != TEST_DATA.dummy_sigs.end());
1017  return it->second.second;
1018  }
1019  case Fragment::MULTI: {
1020  size_t sats = 0;
1021  for (const auto& key : node.keys) {
1022  auto it = TEST_DATA.dummy_sigs.find(key);
1023  assert(it != TEST_DATA.dummy_sigs.end());
1024  sats += it->second.second;
1025  }
1026  return sats >= node.k;
1027  }
1028  case Fragment::OLDER:
1029  case Fragment::AFTER:
1030  return node.k & 1;
1031  case Fragment::SHA256:
1032  return TEST_DATA.sha256_preimages.count(node.data);
1033  case Fragment::HASH256:
1034  return TEST_DATA.hash256_preimages.count(node.data);
1035  case Fragment::RIPEMD160:
1036  return TEST_DATA.ripemd160_preimages.count(node.data);
1037  case Fragment::HASH160:
1038  return TEST_DATA.hash160_preimages.count(node.data);
1039  default:
1040  assert(false);
1041  }
1042  return false;
1043  });
1044  assert(mal_success == satisfiable);
1045 }
1046 
1047 } // namespace
1048 
1049 void FuzzInit()
1050 {
1051  ECC_Start();
1052  TEST_DATA.Init();
1053 }
1054 
1056 {
1057  FuzzInit();
1058  SMARTINFO.Init();
1059 }
1060 
1062 FUZZ_TARGET(miniscript_stable, .init = FuzzInit)
1063 {
1064  FuzzedDataProvider provider(buffer.data(), buffer.size());
1065  TestNode(GenNode([&](Type needed_type) {
1066  return ConsumeNodeStable(provider, needed_type);
1067  }, ""_mst), provider);
1068 }
1069 
1071 FUZZ_TARGET(miniscript_smart, .init = FuzzInitSmart)
1072 {
1074  static constexpr std::array<Type, 4> BASE_TYPES{"B"_mst, "V"_mst, "K"_mst, "W"_mst};
1075 
1076  FuzzedDataProvider provider(buffer.data(), buffer.size());
1077  TestNode(GenNode([&](Type needed_type) {
1078  return ConsumeNodeSmart(provider, needed_type);
1079  }, PickValue(provider, BASE_TYPES), true), provider);
1080 }
1081 
1082 /* Fuzz tests that test parsing from a string, and roundtripping via string. */
1083 FUZZ_TARGET(miniscript_string, .init = FuzzInit)
1084 {
1085  FuzzedDataProvider provider(buffer.data(), buffer.size());
1086  auto str = provider.ConsumeRemainingBytesAsString();
1087  auto parsed = miniscript::FromString(str, PARSER_CTX);
1088  if (!parsed) return;
1089 
1090  const auto str2 = parsed->ToString(PARSER_CTX);
1091  assert(str2);
1092  auto parsed2 = miniscript::FromString(*str2, PARSER_CTX);
1093  assert(parsed2);
1094  assert(*parsed == *parsed2);
1095 }
1096 
1097 /* Fuzz tests that test parsing from a script, and roundtripping via script. */
1098 FUZZ_TARGET(miniscript_script)
1099 {
1100  FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
1101  const std::optional<CScript> script = ConsumeDeserializable<CScript>(fuzzed_data_provider);
1102  if (!script) return;
1103 
1104  const auto ms = miniscript::FromScript(*script, SCRIPT_PARSER_CONTEXT);
1105  if (!ms) return;
1106 
1107  assert(ms->ToScript(SCRIPT_PARSER_CONTEXT) == *script);
1108 }
ECC_Start()
Definition: key.cpp:428
ArgsManager & args
Definition: bitcoind.cpp:269
virtual bool CheckLockTime(const CScriptNum &nLockTime) const
Definition: interpreter.h:256
virtual bool CheckSequence(const CScriptNum &nSequence) const
Definition: interpreter.h:261
virtual bool CheckECDSASignature(const std::vector< unsigned char > &scriptSig, const std::vector< unsigned char > &vchPubKey, const CScript &scriptCode, SigVersion sigversion) const
Definition: interpreter.h:246
A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160).
Definition: hash.h:50
void Finalize(Span< unsigned char > output)
Definition: hash.h:56
CHash160 & Write(Span< const unsigned char > input)
Definition: hash.h:63
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
Definition: hash.h:25
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:38
void Finalize(Span< unsigned char > output)
Definition: hash.h:31
An encapsulated private key.
Definition: key.h:33
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:214
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:79
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:24
An encapsulated public key.
Definition: pubkey.h:34
bool IsValid() const
Definition: pubkey.h:189
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:89
A hasher class for RIPEMD-160.
Definition: ripemd160.h:13
CRIPEMD160 & Write(const unsigned char *data, size_t len)
Definition: ripemd160.cpp:247
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: ripemd160.cpp:273
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:707
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:681
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:413
int64_t GetInt64() const
Definition: script.h:340
T ConsumeIntegralInRange(T min, T max)
std::string ConsumeRemainingBytesAsString()
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:97
constexpr unsigned char * begin()
Definition: uint256.h:68
This type encapsulates the miniscript type system properties.
Definition: miniscript.h:121
static void SHA256(benchmark::Bench &bench)
Definition: crypto_hash.cpp:39
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:93
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition: hash.h:251
#define T(expected, seed, data)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
SigVersion
Definition: interpreter.h:189
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)
Helper function for Node::CalcType.
Definition: miniscript.cpp:35
size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys)
Helper function for Node::CalcScriptLen.
Definition: miniscript.cpp:249
std::shared_ptr< const Node< Key > > NodeRef
Definition: miniscript.h:186
NodeRef< Key > MakeNodeRef(Args &&... args)
Construct a miniscript node as a shared_ptr.
Definition: miniscript.h:190
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
Definition: miniscript.h:2252
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
Definition: miniscript.h:2247
Fragment
The different node types in miniscript.
Definition: miniscript.h:193
Definition: init.h:25
Internal RIPEMD-160 implementation.
Definition: ripemd160.cpp:16
Internal SHA-256 implementation.
Definition: sha256.cpp:67
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Definition: policy.h:103
static constexpr unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE
The maximum size in bytes of a standard witnessScript.
Definition: policy.h:47
@ OP_CHECKMULTISIG
Definition: script.h:190
@ OP_CHECKSIG
Definition: script.h:188
@ OP_EQUAL
Definition: script.h:144
@ OP_NOP
Definition: script.h:100
@ OP_0
Definition: script.h:74
static const int MAX_OPS_PER_SCRIPT
Definition: script.h:29
enum ScriptError_t ScriptError
@ SCRIPT_ERR_OP_COUNT
Definition: script_error.h:21
@ SCRIPT_ERR_STACK_SIZE
Definition: script_error.h:22
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h:65
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:109
std::vector< std::vector< unsigned char > > stack
Definition: script.h:568
A node in a miniscript expression.
Definition: miniscript.h:355
FUZZ_TARGET(miniscript_stable,.init=FuzzInit)
Fuzz target that runs TestNode on nodes generated using ConsumeNodeStable.
void FuzzInit()
void FuzzInitSmart()
auto ConsumeNode(FuzzedDataProvider &fuzzed_data_provider, const std::optional< NodeId > &node_id_in=std::nullopt) noexcept
Definition: net.h:101
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
Definition: util.h:48
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:74
uint256 uint256S(const char *str)
Definition: uint256.h:119
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
assert(!tx.IsCoinBase())