Bitcoin Core  25.99.0
P2P Digital Currency
miniscript_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-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 <stdint.h>
6 #include <string>
7 #include <vector>
8 
9 #include <test/util/random.h>
10 #include <test/util/setup_common.h>
11 #include <boost/test/unit_test.hpp>
12 
13 #include <addresstype.h>
14 #include <core_io.h>
15 #include <hash.h>
16 #include <pubkey.h>
17 #include <uint256.h>
18 #include <crypto/ripemd160.h>
19 #include <crypto/sha256.h>
20 #include <script/interpreter.h>
21 #include <script/miniscript.h>
22 #include <script/script_error.h>
23 
24 namespace {
25 
27 struct TestData {
29  std::vector<CPubKey> pubkeys;
31  std::map<CPubKey, CKeyID> pkhashes;
32  std::map<CKeyID, CPubKey> pkmap;
33  std::map<CPubKey, std::vector<unsigned char>> signatures;
34 
35  // Various precomputed hashes
36  std::vector<std::vector<unsigned char>> sha256;
37  std::vector<std::vector<unsigned char>> ripemd160;
38  std::vector<std::vector<unsigned char>> hash256;
39  std::vector<std::vector<unsigned char>> hash160;
40  std::map<std::vector<unsigned char>, std::vector<unsigned char>> sha256_preimages;
41  std::map<std::vector<unsigned char>, std::vector<unsigned char>> ripemd160_preimages;
42  std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash256_preimages;
43  std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash160_preimages;
44 
45  TestData()
46  {
47  // All our signatures sign (and are required to sign) this constant message.
48  auto const MESSAGE_HASH = uint256S("f5cd94e18b6fe77dd7aca9e35c2b0c9cbd86356c80a71065");
49  // We generate 255 public keys and 255 hashes of each type.
50  for (int i = 1; i <= 255; ++i) {
51  // This 32-byte array functions as both private key data and hash preimage (31 zero bytes plus any nonzero byte).
52  unsigned char keydata[32] = {0};
53  keydata[31] = i;
54 
55  // Compute CPubkey and CKeyID
56  CKey key;
57  key.Set(keydata, keydata + 32, true);
58  CPubKey pubkey = key.GetPubKey();
59  CKeyID keyid = pubkey.GetID();
60  pubkeys.push_back(pubkey);
61  pkhashes.emplace(pubkey, keyid);
62  pkmap.emplace(keyid, pubkey);
63 
64  // Compute ECDSA signatures on MESSAGE_HASH with the private keys.
65  std::vector<unsigned char> sig;
66  BOOST_CHECK(key.Sign(MESSAGE_HASH, sig));
67  sig.push_back(1); // sighash byte
68  signatures.emplace(pubkey, sig);
69 
70  // Compute various hashes
71  std::vector<unsigned char> hash;
72  hash.resize(32);
73  CSHA256().Write(keydata, 32).Finalize(hash.data());
74  sha256.push_back(hash);
75  sha256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
76  CHash256().Write(keydata).Finalize(hash);
77  hash256.push_back(hash);
78  hash256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
79  hash.resize(20);
80  CRIPEMD160().Write(keydata, 32).Finalize(hash.data());
81  ripemd160.push_back(hash);
82  ripemd160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
83  CHash160().Write(keydata).Finalize(hash);
84  hash160.push_back(hash);
85  hash160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
86  }
87  }
88 };
89 
91 std::unique_ptr<const TestData> g_testdata;
92 
94 enum class ChallengeType {
95  SHA256,
96  RIPEMD160,
97  HASH256,
98  HASH160,
99  OLDER,
100  AFTER,
101  PK
102 };
103 
104 /* With each leaf condition we associate a challenge number.
105  * For hashes it's just the first 4 bytes of the hash. For pubkeys, it's the last 4 bytes.
106  */
107 uint32_t ChallengeNumber(const CPubKey& pubkey) { return ReadLE32(pubkey.data() + 29); }
108 uint32_t ChallengeNumber(const std::vector<unsigned char>& hash) { return ReadLE32(hash.data()); }
109 
111 typedef std::pair<ChallengeType, uint32_t> Challenge;
112 
114 struct KeyConverter {
115  typedef CPubKey Key;
116 
117  bool KeyCompare(const Key& a, const Key& b) const {
118  return a < b;
119  }
120 
122  std::vector<unsigned char> ToPKBytes(const CPubKey& key) const { return {key.begin(), key.end()}; }
123 
125  std::vector<unsigned char> ToPKHBytes(const CPubKey& key) const
126  {
127  auto it = g_testdata->pkhashes.find(key);
128  assert(it != g_testdata->pkhashes.end());
129  return {it->second.begin(), it->second.end()};
130  }
131 
133  template<typename I>
134  std::optional<Key> FromString(I first, I last) const {
135  auto bytes = ParseHex(std::string(first, last));
136  Key key{bytes.begin(), bytes.end()};
137  if (key.IsValid()) return key;
138  return {};
139  }
140 
141  template<typename I>
142  std::optional<Key> FromPKBytes(I first, I last) const {
143  Key key{first, last};
144  if (key.IsValid()) return key;
145  return {};
146  }
147 
148  template<typename I>
149  std::optional<Key> FromPKHBytes(I first, I last) const {
150  assert(last - first == 20);
151  CKeyID keyid;
152  std::copy(first, last, keyid.begin());
153  auto it = g_testdata->pkmap.find(keyid);
154  assert(it != g_testdata->pkmap.end());
155  return it->second;
156  }
157 
158  std::optional<std::string> ToString(const Key& key) const {
159  return HexStr(ToPKBytes(key));
160  }
161 };
162 
164 struct Satisfier : public KeyConverter {
166  std::set<Challenge> supported;
167 
169  bool CheckAfter(uint32_t value) const {
170  return supported.count(Challenge(ChallengeType::AFTER, value));
171  }
172 
174  bool CheckOlder(uint32_t value) const {
175  return supported.count(Challenge(ChallengeType::OLDER, value));
176  }
177 
179  miniscript::Availability Sign(const CPubKey& key, std::vector<unsigned char>& sig) const {
180  if (supported.count(Challenge(ChallengeType::PK, ChallengeNumber(key)))) {
181  auto it = g_testdata->signatures.find(key);
182  if (it == g_testdata->signatures.end()) return miniscript::Availability::NO;
183  sig = it->second;
185  }
187  }
188 
190  miniscript::Availability SatHash(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage, ChallengeType chtype) const {
191  if (!supported.count(Challenge(chtype, ChallengeNumber(hash)))) return miniscript::Availability::NO;
192  const auto& m =
193  chtype == ChallengeType::SHA256 ? g_testdata->sha256_preimages :
194  chtype == ChallengeType::HASH256 ? g_testdata->hash256_preimages :
195  chtype == ChallengeType::RIPEMD160 ? g_testdata->ripemd160_preimages :
196  g_testdata->hash160_preimages;
197  auto it = m.find(hash);
198  if (it == m.end()) return miniscript::Availability::NO;
199  preimage = it->second;
201  }
202 
203  // Functions that produce the preimage for hashes of various types.
204  miniscript::Availability SatSHA256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::SHA256); }
205  miniscript::Availability SatRIPEMD160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::RIPEMD160); }
206  miniscript::Availability SatHASH256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::HASH256); }
207  miniscript::Availability SatHASH160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::HASH160); }
208 };
209 
214 class TestSignatureChecker : public BaseSignatureChecker {
215  const Satisfier& ctx;
216 
217 public:
218  TestSignatureChecker(const Satisfier& in_ctx LIFETIMEBOUND) : ctx(in_ctx) {}
219 
220  bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& pubkey, const CScript& scriptcode, SigVersion sigversion) const override {
221  CPubKey pk(pubkey);
222  if (!pk.IsValid()) return false;
223  // Instead of actually running signature validation, check if the signature matches the precomputed one for this key.
224  auto it = g_testdata->signatures.find(pk);
225  if (it == g_testdata->signatures.end()) return false;
226  return sig == it->second;
227  }
228 
229  bool CheckLockTime(const CScriptNum& locktime) const override {
230  // Delegate to Satisfier.
231  return ctx.CheckAfter(locktime.GetInt64());
232  }
233 
234  bool CheckSequence(const CScriptNum& sequence) const override {
235  // Delegate to Satisfier.
236  return ctx.CheckOlder(sequence.GetInt64());
237  }
238 };
239 
241 const KeyConverter CONVERTER{};
242 
245 using miniscript::operator"" _mst;
246 using Node = miniscript::Node<CPubKey>;
247 
249 std::set<Challenge> FindChallenges(const NodeRef& ref) {
250  std::set<Challenge> chal;
251  for (const auto& key : ref->keys) {
252  chal.emplace(ChallengeType::PK, ChallengeNumber(key));
253  }
254  if (ref->fragment == miniscript::Fragment::OLDER) {
255  chal.emplace(ChallengeType::OLDER, ref->k);
256  } else if (ref->fragment == miniscript::Fragment::AFTER) {
257  chal.emplace(ChallengeType::AFTER, ref->k);
258  } else if (ref->fragment == miniscript::Fragment::SHA256) {
259  chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data));
260  } else if (ref->fragment == miniscript::Fragment::RIPEMD160) {
261  chal.emplace(ChallengeType::RIPEMD160, ChallengeNumber(ref->data));
262  } else if (ref->fragment == miniscript::Fragment::HASH256) {
263  chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data));
264  } else if (ref->fragment == miniscript::Fragment::HASH160) {
265  chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data));
266  }
267  for (const auto& sub : ref->subs) {
268  auto sub_chal = FindChallenges(sub);
269  chal.insert(sub_chal.begin(), sub_chal.end());
270  }
271  return chal;
272 }
273 
275 void TestSatisfy(const std::string& testcase, const NodeRef& node) {
276  auto script = node->ToScript(CONVERTER);
277  auto challenges = FindChallenges(node); // Find all challenges in the generated miniscript.
278  std::vector<Challenge> challist(challenges.begin(), challenges.end());
279  for (int iter = 0; iter < 3; ++iter) {
280  Shuffle(challist.begin(), challist.end(), g_insecure_rand_ctx);
281  Satisfier satisfier;
282  TestSignatureChecker checker(satisfier);
283  bool prev_mal_success = false, prev_nonmal_success = false;
284  // Go over all challenges involved in this miniscript in random order.
285  for (int add = -1; add < (int)challist.size(); ++add) {
286  if (add >= 0) satisfier.supported.insert(challist[add]); // The first iteration does not add anything
287 
288  // Run malleable satisfaction algorithm.
289  const CScript script_pubkey = CScript() << OP_0 << WitnessV0ScriptHash(script);
290  CScriptWitness witness_mal;
291  const bool mal_success = node->Satisfy(satisfier, witness_mal.stack, false) == miniscript::Availability::YES;
292  witness_mal.stack.push_back(std::vector<unsigned char>(script.begin(), script.end()));
293 
294  // Run non-malleable satisfaction algorithm.
295  CScriptWitness witness_nonmal;
296  const bool nonmal_success = node->Satisfy(satisfier, witness_nonmal.stack, true) == miniscript::Availability::YES;
297  witness_nonmal.stack.push_back(std::vector<unsigned char>(script.begin(), script.end()));
298 
299  if (nonmal_success) {
300  // Non-malleable satisfactions are bounded by GetStackSize().
301  BOOST_CHECK(witness_nonmal.stack.size() <= *node->GetStackSize() + 1);
302  // If a non-malleable satisfaction exists, the malleable one must also exist, and be identical to it.
303  BOOST_CHECK(mal_success);
304  BOOST_CHECK(witness_nonmal.stack == witness_mal.stack);
305 
306  // Test non-malleable satisfaction.
307  ScriptError serror;
308  bool res = VerifyScript(CScript(), script_pubkey, &witness_nonmal, STANDARD_SCRIPT_VERIFY_FLAGS, checker, &serror);
309  // Non-malleable satisfactions are guaranteed to be valid if ValidSatisfactions().
310  if (node->ValidSatisfactions()) BOOST_CHECK(res);
311  // More detailed: non-malleable satisfactions must be valid, or could fail with ops count error (if CheckOpsLimit failed),
312  // or with a stack size error (if CheckStackSize check fails).
313  BOOST_CHECK(res ||
314  (!node->CheckOpsLimit() && serror == ScriptError::SCRIPT_ERR_OP_COUNT) ||
315  (!node->CheckStackSize() && serror == ScriptError::SCRIPT_ERR_STACK_SIZE));
316  }
317 
318  if (mal_success && (!nonmal_success || witness_mal.stack != witness_nonmal.stack)) {
319  // Test malleable satisfaction only if it's different from the non-malleable one.
320  ScriptError serror;
321  bool res = VerifyScript(CScript(), script_pubkey, &witness_mal, STANDARD_SCRIPT_VERIFY_FLAGS, checker, &serror);
322  // Malleable satisfactions are not guaranteed to be valid under any conditions, but they can only
323  // fail due to stack or ops limits.
325  }
326 
327  if (node->IsSane()) {
328  // For sane nodes, the two algorithms behave identically.
329  BOOST_CHECK_EQUAL(mal_success, nonmal_success);
330  }
331 
332  // Adding more satisfied conditions can never remove our ability to produce a satisfaction.
333  BOOST_CHECK(mal_success >= prev_mal_success);
334  // For nonmalleable solutions this is only true if the added condition is PK;
335  // for other conditions, adding one may make an valid satisfaction become malleable. If the script
336  // is sane, this cannot happen however.
337  if (node->IsSane() || add < 0 || challist[add].first == ChallengeType::PK) {
338  BOOST_CHECK(nonmal_success >= prev_nonmal_success);
339  }
340  // Remember results for the next added challenge.
341  prev_mal_success = mal_success;
342  prev_nonmal_success = nonmal_success;
343  }
344 
345  bool satisfiable = node->IsSatisfiable([](const Node&) { return true; });
346  // If the miniscript was satisfiable at all, a satisfaction must be found after all conditions are added.
347  BOOST_CHECK_EQUAL(prev_mal_success, satisfiable);
348  // If the miniscript is sane and satisfiable, a nonmalleable satisfaction must eventually be found.
349  if (node->IsSane()) BOOST_CHECK_EQUAL(prev_nonmal_success, satisfiable);
350  }
351 }
352 
353 enum TestMode : int {
354  TESTMODE_INVALID = 0,
355  TESTMODE_VALID = 1,
356  TESTMODE_NONMAL = 2,
357  TESTMODE_NEEDSIG = 4,
358  TESTMODE_TIMELOCKMIX = 8
359 };
360 
361 void Test(const std::string& ms, const std::string& hexscript, int mode, int opslimit = -1, int stacklimit = -1, std::optional<uint32_t> max_wit_size = std::nullopt)
362 {
363  auto node = miniscript::FromString(ms, CONVERTER);
364  if (mode == TESTMODE_INVALID) {
365  BOOST_CHECK_MESSAGE(!node || !node->IsValid(), "Unexpectedly valid: " + ms);
366  } else {
367  BOOST_CHECK_MESSAGE(node, "Unparseable: " + ms);
368  BOOST_CHECK_MESSAGE(node->IsValid(), "Invalid: " + ms);
369  BOOST_CHECK_MESSAGE(node->IsValidTopLevel(), "Invalid top level: " + ms);
370  auto computed_script = node->ToScript(CONVERTER);
371  BOOST_CHECK_MESSAGE(node->ScriptSize() == computed_script.size(), "Script size mismatch: " + ms);
372  if (hexscript != "?") BOOST_CHECK_MESSAGE(HexStr(computed_script) == hexscript, "Script mismatch: " + ms + " (" + HexStr(computed_script) + " vs " + hexscript + ")");
373  BOOST_CHECK_MESSAGE(node->IsNonMalleable() == !!(mode & TESTMODE_NONMAL), "Malleability mismatch: " + ms);
374  BOOST_CHECK_MESSAGE(node->NeedsSignature() == !!(mode & TESTMODE_NEEDSIG), "Signature necessity mismatch: " + ms);
375  BOOST_CHECK_MESSAGE((node->GetType() << "k"_mst) == !(mode & TESTMODE_TIMELOCKMIX), "Timelock mix mismatch: " + ms);
376  auto inferred_miniscript = miniscript::FromScript(computed_script, CONVERTER);
377  BOOST_CHECK_MESSAGE(inferred_miniscript, "Cannot infer miniscript from script: " + ms);
378  BOOST_CHECK_MESSAGE(inferred_miniscript->ToScript(CONVERTER) == computed_script, "Roundtrip failure: miniscript->script != miniscript->script->miniscript->script: " + ms);
379  if (opslimit != -1) BOOST_CHECK_MESSAGE((int)*node->GetOps() == opslimit, "Ops limit mismatch: " << ms << " (" << *node->GetOps() << " vs " << opslimit << ")");
380  if (stacklimit != -1) BOOST_CHECK_MESSAGE((int)*node->GetStackSize() == stacklimit, "Stack limit mismatch: " << ms << " (" << *node->GetStackSize() << " vs " << stacklimit << ")");
381  if (max_wit_size) BOOST_CHECK_MESSAGE(*node->GetWitnessSize() == *max_wit_size, "Witness size limit mismatch: " << ms << " (" << *node->GetWitnessSize() << " vs " << *max_wit_size << ")");
382  TestSatisfy(ms, node);
383  }
384 }
385 } // namespace
386 
387 BOOST_FIXTURE_TEST_SUITE(miniscript_tests, BasicTestingSetup)
388 
390 {
391  g_testdata.reset(new TestData());
392 
393  // Validity rules
394  Test("l:older(1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // older(1): valid
395  Test("l:older(0)", "?", TESTMODE_INVALID); // older(0): k must be at least 1
396  Test("l:older(2147483647)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // older(2147483647): valid
397  Test("l:older(2147483648)", "?", TESTMODE_INVALID); // older(2147483648): k must be below 2^31
398  Test("u:after(1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // after(1): valid
399  Test("u:after(0)", "?", TESTMODE_INVALID); // after(0): k must be at least 1
400  Test("u:after(2147483647)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // after(2147483647): valid
401  Test("u:after(2147483648)", "?", TESTMODE_INVALID); // after(2147483648): k must be below 2^31
402  Test("andor(0,1,1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // andor(Bdu,B,B): valid
403  Test("andor(a:0,1,1)", "?", TESTMODE_INVALID); // andor(Wdu,B,B): X must be B
404  Test("andor(0,a:1,a:1)", "?", TESTMODE_INVALID); // andor(Bdu,W,W): Y and Z must be B/V/K
405  Test("andor(1,1,1)", "?", TESTMODE_INVALID); // andor(Bu,B,B): X must be d
406  Test("andor(n:or_i(0,after(1)),1,1)", "?", TESTMODE_VALID); // andor(Bdu,B,B): valid
407  Test("andor(or_i(0,after(1)),1,1)", "?", TESTMODE_INVALID); // andor(Bd,B,B): X must be u
408  Test("c:andor(0,pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // andor(Bdu,K,K): valid
409  Test("t:andor(0,v:1,v:1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // andor(Bdu,V,V): valid
410  Test("and_v(v:1,1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // and_v(V,B): valid
411  Test("t:and_v(v:1,v:1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // and_v(V,V): valid
412  Test("c:and_v(v:1,pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // and_v(V,K): valid
413  Test("and_v(1,1)", "?", TESTMODE_INVALID); // and_v(B,B): X must be V
414  Test("and_v(pk_k(02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),1)", "?", TESTMODE_INVALID); // and_v(K,B): X must be V
415  Test("and_v(v:1,a:1)", "?", TESTMODE_INVALID); // and_v(K,W): Y must be B/V/K
416  Test("and_b(1,a:1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // and_b(B,W): valid
417  Test("and_b(1,1)", "?", TESTMODE_INVALID); // and_b(B,B): Y must W
418  Test("and_b(v:1,a:1)", "?", TESTMODE_INVALID); // and_b(V,W): X must be B
419  Test("and_b(a:1,a:1)", "?", TESTMODE_INVALID); // and_b(W,W): X must be B
420  Test("and_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:1)", "?", TESTMODE_INVALID); // and_b(K,W): X must be B
421  Test("or_b(0,a:0)", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // or_b(Bd,Wd): valid
422  Test("or_b(1,a:0)", "?", TESTMODE_INVALID); // or_b(B,Wd): X must be d
423  Test("or_b(0,a:1)", "?", TESTMODE_INVALID); // or_b(Bd,W): Y must be d
424  Test("or_b(0,0)", "?", TESTMODE_INVALID); // or_b(Bd,Bd): Y must W
425  Test("or_b(v:0,a:0)", "?", TESTMODE_INVALID); // or_b(V,Wd): X must be B
426  Test("or_b(a:0,a:0)", "?", TESTMODE_INVALID); // or_b(Wd,Wd): X must be B
427  Test("or_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:0)", "?", TESTMODE_INVALID); // or_b(Kd,Wd): X must be B
428  Test("t:or_c(0,v:1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // or_c(Bdu,V): valid
429  Test("t:or_c(a:0,v:1)", "?", TESTMODE_INVALID); // or_c(Wdu,V): X must be B
430  Test("t:or_c(1,v:1)", "?", TESTMODE_INVALID); // or_c(Bu,V): X must be d
431  Test("t:or_c(n:or_i(0,after(1)),v:1)", "?", TESTMODE_VALID); // or_c(Bdu,V): valid
432  Test("t:or_c(or_i(0,after(1)),v:1)", "?", TESTMODE_INVALID); // or_c(Bd,V): X must be u
433  Test("t:or_c(0,1)", "?", TESTMODE_INVALID); // or_c(Bdu,B): Y must be V
434  Test("or_d(0,1)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // or_d(Bdu,B): valid
435  Test("or_d(a:0,1)", "?", TESTMODE_INVALID); // or_d(Wdu,B): X must be B
436  Test("or_d(1,1)", "?", TESTMODE_INVALID); // or_d(Bu,B): X must be d
437  Test("or_d(n:or_i(0,after(1)),1)", "?", TESTMODE_VALID); // or_d(Bdu,B): valid
438  Test("or_d(or_i(0,after(1)),1)", "?", TESTMODE_INVALID); // or_d(Bd,B): X must be u
439  Test("or_d(0,v:1)", "?", TESTMODE_INVALID); // or_d(Bdu,V): Y must be B
440  Test("or_i(1,1)", "?", TESTMODE_VALID); // or_i(B,B): valid
441  Test("t:or_i(v:1,v:1)", "?", TESTMODE_VALID); // or_i(V,V): valid
442  Test("c:or_i(pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // or_i(K,K): valid
443  Test("or_i(a:1,a:1)", "?", TESTMODE_INVALID); // or_i(W,W): X and Y must be B/V/K
444  Test("or_b(l:after(100),al:after(1000000000))", "?", TESTMODE_VALID); // or_b(timelock, heighlock) valid
445  Test("and_b(after(100),a:after(1000000000))", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX); // and_b(timelock, heighlock) invalid
446  Test("pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // alias to c:pk_k
447  Test("pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", "76a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // alias to c:pk_h
448 
449 
450  // Randomly generated test set that covers the majority of type and node type combinations
451  Test("lltvln:after(1231488000)", "6300676300676300670400046749b1926869516868", TESTMODE_VALID | TESTMODE_NONMAL, 12, 3, 3);
452  Test("uuj:and_v(v:multi(2,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),after(1231488000))", "6363829263522103d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a21025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc52af0400046749b168670068670068", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 14, 5, 2 + 2 + 1 + 2 * 73);
453  Test("or_b(un:multi(2,03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),al:older(16))", "63522103daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee872921024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c9752ae926700686b63006760b2686c9b", TESTMODE_VALID, 14, 5, 2 + 1 + 2 * 73 + 2);
454  Test("j:and_v(vdv:after(1567547623),older(2016))", "829263766304e7e06e5db169686902e007b268", TESTMODE_VALID | TESTMODE_NONMAL, 11, 1, 2);
455  Test("t:and_v(vu:hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),v:sha256(ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5))", "6382012088aa20131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b876700686982012088a820ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc58851", TESTMODE_VALID | TESTMODE_NONMAL, 12, 3, 2 + 33 + 33);
456  Test("t:andor(multi(3,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13),v:older(4194305),v:sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2))", "532102d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a14602975562102e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd1353ae6482012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2886703010040b2696851", TESTMODE_VALID | TESTMODE_NONMAL, 13, 5, 1 + 3 * 73);
457  Test("or_d(multi(1,02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9),or_b(multi(3,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,032fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a),su:after(500000)))", "512102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f951ae73645321022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a0121032fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f2103d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a53ae7c630320a107b16700689b68", TESTMODE_VALID | TESTMODE_NONMAL, 15, 7, 2 + 1 + 3 * 73 + 1);
458  Test("or_d(sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6),and_n(un:after(499999999),older(4194305)))", "82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868", TESTMODE_VALID, 16, 1, 33);
459  Test("and_v(or_i(v:multi(2,02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb),v:multi(2,03e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)),sha256(d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68))", "63522102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee52103774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb52af67522103e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a21025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc52af6882012088a820d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c6887", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 11, 5, 2 + 1 + 2 * 73 + 33);
460  Test("j:and_b(multi(2,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),s:or_i(older(1),older(4252898)))", "82926352210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c9752ae7c6351b26703e2e440b2689a68", TESTMODE_VALID | TESTMODE_NEEDSIG, 14, 4, 1 + 2 * 73 + 2);
461  Test("and_b(older(16),s:or_d(sha256(e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f),n:after(1567547623)))", "60b27c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87736404e7e06e5db192689a", TESTMODE_VALID, 12, 1, 33);
462  Test("j:and_v(v:hash160(20195b5a3d650c17f0f29f91c33f8f6335193d07),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))", "82926382012088a91420195b5a3d650c17f0f29f91c33f8f6335193d078882012088a82096de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c4787736460b26868", TESTMODE_VALID, 16, 2, 33 + 33);
463  Test("and_b(hash256(32ba476771d01e37807990ead8719f08af494723de1d228f2c2c07cc0aa40bac),a:and_b(hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),a:older(1)))", "82012088aa2032ba476771d01e37807990ead8719f08af494723de1d228f2c2c07cc0aa40bac876b82012088aa20131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b876b51b26c9a6c9a", TESTMODE_VALID | TESTMODE_NONMAL, 15, 2, 33 + 33);
464  Test("thresh(2,multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),a:multi(1,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),ac:pk_k(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01))", "522103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c721036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a0052ae6b5121036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a0051ae6c936b21022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01ac6c935287", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 13, 6, 1 + 2 * 73 + 1 + 73 + 1);
465  Test("and_n(sha256(d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68),t:or_i(v:older(4252898),v:older(144)))", "82012088a820d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68876400676303e2e440b26967029000b269685168", TESTMODE_VALID, 14, 2, 33 + 2);
466  Test("or_d(nd:and_v(v:older(4252898),v:older(4252898)),sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6))", "766303e2e440b26903e2e440b2696892736482012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68768", TESTMODE_VALID, 15, 2, 1 + 33);
467  Test("c:and_v(or_c(sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2),v:multi(1,02c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db)),pk_k(03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))", "82012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed28764512102c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db51af682103acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbeac", TESTMODE_VALID | TESTMODE_NEEDSIG, 8, 2, 33 + 73);
468  Test("c:and_v(or_c(multi(2,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00,02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),v:ripemd160(1b0f3c404d12075c68c938f9f60ebea4f74941a0)),pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "5221036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a002102352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d552ae6482012088a6141b0f3c404d12075c68c938f9f60ebea4f74941a088682103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 10, 5, 1 + 2 * 73 + 73);
469  Test("and_v(andor(hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),v:hash256(939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735),v:older(50000)),after(499999999))", "82012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b2587640350c300b2696782012088aa20939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735886804ff64cd1db1", TESTMODE_VALID, 14, 2, 33 + 33);
470  Test("andor(hash256(5f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040),j:and_v(v:hash160(3a2bff0da9d96868e66abc4427bea4691cf61ccd),older(4194305)),ripemd160(44d90e2d3714c8663b632fcf0f9d5f22192cc4c8))", "82012088aa205f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040876482012088a61444d90e2d3714c8663b632fcf0f9d5f22192cc4c8876782926382012088a9143a2bff0da9d96868e66abc4427bea4691cf61ccd8803010040b26868", TESTMODE_VALID, 20, 2, 33 + 33);
471  Test("or_i(c:and_v(v:after(500000),pk_k(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)),sha256(d9147961436944f43cd99d28b2bbddbf452ef872b30c8279e255e7daafc7f946))", "630320a107b1692102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ac6782012088a820d9147961436944f43cd99d28b2bbddbf452ef872b30c8279e255e7daafc7f9468768", TESTMODE_VALID | TESTMODE_NONMAL, 10, 2, 2 + 73);
472  Test("thresh(2,c:pk_h(025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc),s:sha256(e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f),a:hash160(dd69735817e0e3f6f826a9238dc2e291184f0131))", "76a9145dedfbf9ea599dd4e3ca6a80b333c472fd0b3f6988ac7c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87936b82012088a914dd69735817e0e3f6f826a9238dc2e291184f0131876c935287", TESTMODE_VALID, 18, 4, 1 + 34 + 33 + 33);
473  Test("and_n(sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2),uc:and_v(v:older(144),pk_k(03fe72c435413d33d48ac09c9161ba8b09683215439d62b7940502bda8b202e6ce)))", "82012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed28764006763029000b2692103fe72c435413d33d48ac09c9161ba8b09683215439d62b7940502bda8b202e6ceac67006868", TESTMODE_VALID | TESTMODE_NEEDSIG, 13, 3, 33 + 2 + 73);
474  Test("and_n(c:pk_k(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),and_b(l:older(4252898),a:older(16)))", "2103daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729ac64006763006703e2e440b2686b60b26c9a68", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_TIMELOCKMIX, 12, 2, 73 + 1);
475  Test("c:or_i(and_v(v:older(16),pk_h(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)),pk_h(026a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4))", "6360b26976a9149fc5dbe5efdce10374a4dd4053c93af540211718886776a9142fbd32c8dd59ee7c17e66cb6ebea7e9846c3040f8868ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 12, 3, 2 + 34 + 73);
476  Test("or_d(c:pk_h(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13),andor(c:pk_k(024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),older(2016),after(1567547623)))", "76a914c42e7ef92fdb603af844d064faad95db9bcdfd3d88ac736421024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97ac6404e7e06e5db16702e007b26868", TESTMODE_VALID | TESTMODE_NONMAL, 13, 3, 1 + 34 + 73);
477  Test("c:andor(ripemd160(6ad07d21fd5dfc646f0b30577045ce201616b9ba),pk_h(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e),and_v(v:hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),pk_h(03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a)))", "82012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba876482012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b258876a914dd100be7d9aea5721158ebde6d6a1fd8fff93bb1886776a9149fc5dbe5efdce10374a4dd4053c93af5402117188868ac", TESTMODE_VALID | TESTMODE_NEEDSIG, 18, 3, 33 + 34 + 73);
478  Test("c:andor(u:ripemd160(6ad07d21fd5dfc646f0b30577045ce201616b9ba),pk_h(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),or_i(pk_h(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01),pk_h(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)))", "6382012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba87670068646376a9149652d86bedf43ad264362e6e6eba6eb764508127886776a914751e76e8199196d454941c45d1b3a323f1433bd688686776a91420d637c1a6404d2227f3561fdbaff5a680dba6488868ac", TESTMODE_VALID | TESTMODE_NEEDSIG, 23, 4, 2 + 33 + 34 + 73);
479  Test("c:or_i(andor(c:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk_h(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01),pk_h(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)),pk_k(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e))", "6376a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac6476a91406afd46bcdfd22ef94ac122aa11f241244a37ecc886776a9149652d86bedf43ad264362e6e6eba6eb7645081278868672102d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e68ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 17, 5, 2 + 34 + 73 + 34 + 73);
480  Test("thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(1000000000),altv:after(100))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670400ca9a3bb16951686c936b6300670164b16951686c935187", TESTMODE_VALID, 18, 3, 73 + 2 + 2);
481  Test("thresh(2,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),ac:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),altv:after(1000000000),altv:after(100))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac6c936b6300670400ca9a3bb16951686c936b6300670164b16951686c935287", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX, 22, 4, 73 + 73 + 2 + 2);
482 
483  // Misc unit tests
484  // A Script with a non minimal push is invalid
485  std::vector<unsigned char> nonminpush = ParseHex("0000210232780000feff00ffffffffffff21ff005f00ae21ae00000000060602060406564c2102320000060900fe00005f00ae21ae00100000060606060606000000000000000000000000000000000000000000000000000000000000000000");
486  const CScript nonminpush_script(nonminpush.begin(), nonminpush.end());
487  BOOST_CHECK(miniscript::FromScript(nonminpush_script, CONVERTER) == nullptr);
488  // A non-minimal VERIFY (<key> CHECKSIG VERIFY 1)
489  std::vector<unsigned char> nonminverify = ParseHex("2103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ac6951");
490  const CScript nonminverify_script(nonminverify.begin(), nonminverify.end());
491  BOOST_CHECK(miniscript::FromScript(nonminverify_script, CONVERTER) == nullptr);
492  // A threshold as large as the number of subs is valid.
493  Test("thresh(2,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(100))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
494  // A threshold of 1 is valid.
495  Test("thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
496  // A threshold with a k larger than the number of subs is invalid
497  Test("thresh(3,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", TESTMODE_INVALID);
498  // A threshold with a k null is invalid
499  Test("thresh(0,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", TESTMODE_INVALID);
500  // For CHECKMULTISIG the OP cost is the number of keys, but the stack size is the number of sigs (+1)
501  const auto ms_multi = miniscript::FromString("multi(1,03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", CONVERTER);
502  BOOST_CHECK(ms_multi);
503  BOOST_CHECK_EQUAL(*ms_multi->GetOps(), 4); // 3 pubkeys + CMS
504  BOOST_CHECK_EQUAL(*ms_multi->GetStackSize(), 2); // 1 sig + dummy elem
505  // The 'd:' wrapper leaves on the stack what was DUP'ed at the beginning of its execution.
506  // Since it contains an OP_IF just after on the same element, we can make sure that the element
507  // in question must be OP_1 if OP_IF enforces that its argument must only be OP_1 or the empty
508  // vector (since otherwise the execution would immediately fail). This is the MINIMALIF rule.
509  // Unfortunately, this rule is consensus for Taproot but only policy for P2WSH. Therefore we can't
510  // (for now) have 'd:' be 'u'. This tests we can't use a 'd:' wrapper for a thresh, which requires
511  // its subs to all be 'u' (taken from https://github.com/rust-bitcoin/rust-miniscript/discussions/341).
512  const auto ms_minimalif = miniscript::FromString("thresh(3,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),sc:pk_k(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798),sdv:older(32))", CONVERTER);
513  BOOST_CHECK(ms_minimalif && !ms_minimalif->IsValid());
514  // A Miniscript with duplicate keys is not sane
515  const auto ms_dup1 = miniscript::FromString("and_v(v:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", CONVERTER);
516  BOOST_CHECK(ms_dup1);
517  BOOST_CHECK(!ms_dup1->IsSane() && !ms_dup1->CheckDuplicateKey());
518  // Same with a disjunction, and different key nodes (pk and pkh)
519  const auto ms_dup2 = miniscript::FromString("or_b(c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),ac:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", CONVERTER);
520  BOOST_CHECK(ms_dup2 && !ms_dup2->IsSane() && !ms_dup2->CheckDuplicateKey());
521  // Same when the duplicates are leaves or a larger tree
522  const auto ms_dup3 = miniscript::FromString("or_i(and_b(pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556)),and_b(older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", CONVERTER);
523  BOOST_CHECK(ms_dup3 && !ms_dup3->IsSane() && !ms_dup3->CheckDuplicateKey());
524  // Same when the duplicates are on different levels in the tree
525  const auto ms_dup4 = miniscript::FromString("thresh(2,pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),a:and_b(dv:older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", CONVERTER);
526  BOOST_CHECK(ms_dup4 && !ms_dup4->IsSane() && !ms_dup4->CheckDuplicateKey());
527  // Sanity check the opposite is true, too. An otherwise sane Miniscript with no duplicate keys is sane.
528  const auto ms_nondup = miniscript::FromString("pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", CONVERTER);
529  BOOST_CHECK(ms_nondup && ms_nondup->CheckDuplicateKey() && ms_nondup->IsSane());
530  // Test we find the first insane sub closer to be a leaf node. This fragment is insane for two reasons:
531  // 1. It can be spent without a signature
532  // 2. It contains timelock mixes
533  // We'll report the timelock mix error, as it's "deeper" (closer to be a leaf node) than the "no 's' property"
534  // error is.
535  const auto ms_ins = miniscript::FromString("or_i(and_b(after(1),a:after(1000000000)),pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204))", CONVERTER);
536  BOOST_CHECK(ms_ins && ms_ins->IsValid() && !ms_ins->IsSane());
537  const auto insane_sub = ms_ins->FindInsaneSub();
538  BOOST_CHECK(insane_sub && *insane_sub->ToString(CONVERTER) == "and_b(after(1),a:after(1000000000))");
539 
540  // Timelock tests
541  Test("after(100)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // only heightlock
542  Test("after(1000000000)", "?", TESTMODE_VALID | TESTMODE_NONMAL); // only timelock
543  Test("or_b(l:after(100),al:after(1000000000))", "?", TESTMODE_VALID); // or_b(timelock, heighlock) valid
544  Test("and_b(after(100),a:after(1000000000))", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX); // and_b(timelock, heighlock) invalid
545  /* This is correctly detected as non-malleable but for the wrong reason. The type system assumes that branches 1 and 2
546  can be spent together to create a non-malleble witness, but because of mixing of timelocks they cannot be spent together.
547  But since exactly one of the two after's can be satisfied, the witness involving the key cannot be malleated.
548  */
549  Test("thresh(2,ltv:after(1000000000),altv:after(100),a:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", "?", TESTMODE_VALID | TESTMODE_TIMELOCKMIX | TESTMODE_NONMAL); // thresh with k = 2
550  // This is actually non-malleable in practice, but we cannot detect it in type system. See above rationale
551  Test("thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(1000000000),altv:after(100))", "?", TESTMODE_VALID); // thresh with k = 1
552 
553 
554  g_testdata.reset();
555 }
556 
#define LIFETIMEBOUND
Definition: attributes.h:16
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:99
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:24
An encapsulated public key.
Definition: pubkey.h:34
const unsigned char * end() const
Definition: pubkey.h:115
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:164
bool IsValid() const
Definition: pubkey.h:189
const unsigned char * begin() const
Definition: pubkey.h:114
const unsigned char * data() const
Definition: pubkey.h:113
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
constexpr unsigned char * begin()
Definition: uint256.h:68
static uint32_t ReadLE32(const unsigned char *ptr)
Definition: common.h:24
static void SHA256(benchmark::Bench &bench)
Definition: crypto_hash.cpp:39
BOOST_AUTO_TEST_SUITE_END()
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition: hash.h:240
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
SigVersion
Definition: interpreter.h:189
uint64_t sequence
BOOST_AUTO_TEST_CASE(fixed_tests)
std::shared_ptr< const Node< Key > > NodeRef
Definition: miniscript.h:186
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
@ RIPEMD160
OP_SIZE 32 OP_EQUALVERIFY OP_RIPEMD160 [hash] OP_EQUAL.
@ HASH160
OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 [hash] OP_EQUAL.
@ HASH256
OP_SIZE 32 OP_EQUALVERIFY OP_HASH256 [hash] OP_EQUAL.
@ OLDER
[n] OP_CHECKSEQUENCEVERIFY
@ SHA256
OP_SIZE 32 OP_EQUALVERIFY OP_SHA256 [hash] OP_EQUAL.
@ AFTER
[n] OP_CHECKLOCKTIMEVERIFY
Definition: init.h:25
Internal RIPEMD-160 implementation.
Definition: ripemd160.cpp:16
Internal SHA-256 implementation.
Definition: sha256.cpp:67
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Definition: policy.h:103
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:264
@ OP_0
Definition: script.h:74
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
Basic testing setup.
Definition: setup_common.h:49
std::vector< std::vector< unsigned char > > stack
Definition: script.h:568
miniscript::Availability SatHASH256(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Definition: sign.cpp:463
miniscript::Availability SatSHA256(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Hash preimage satisfactions.
Definition: sign.cpp:457
bool CheckOlder(uint32_t value) const
Definition: sign.cpp:453
miniscript::Availability SatHASH160(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Definition: sign.cpp:466
miniscript::Availability Sign(const CPubKey &key, std::vector< unsigned char > &sig) const
Satisfy a signature check.
Definition: sign.cpp:444
Satisfier(const SigningProvider &provider LIFETIMEBOUND, SignatureData &sig_data LIFETIMEBOUND, const BaseSignatureCreator &creator LIFETIMEBOUND, const CScript &witscript LIFETIMEBOUND)
Definition: sign.cpp:408
bool CheckAfter(uint32_t value) const
Time lock satisfactions.
Definition: sign.cpp:452
miniscript::Availability SatRIPEMD160(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Definition: sign.cpp:460
A node in a miniscript expression.
Definition: miniscript.h:355
FastRandomContext g_insecure_rand_ctx
This global and the helpers that use it are not thread-safe.
Definition: random.cpp:14
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())