Bitcoin Core 31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
miniscript_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2019-present 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 <test/util/random.h>
7#include <boost/test/unit_test.hpp>
8
9#include <addresstype.h>
10#include <core_io.h>
11#include <hash.h>
12#include <pubkey.h>
13#include <uint256.h>
14#include <crypto/ripemd160.h>
15#include <crypto/sha256.h>
16#include <script/interpreter.h>
17#include <script/miniscript.h>
18#include <script/script_error.h>
20
21#include <algorithm>
22#include <cstdint>
23#include <string>
24#include <vector>
25
26using namespace util::hex_literals;
27
28namespace {
29
31struct TestData {
33 std::vector<CPubKey> pubkeys;
35 std::map<CPubKey, CKeyID> pkhashes;
36 std::map<CKeyID, CPubKey> pkmap;
37 std::map<XOnlyPubKey, CKeyID> xonly_pkhashes;
38 std::map<CPubKey, std::vector<unsigned char>> signatures;
39 std::map<XOnlyPubKey, std::vector<unsigned char>> schnorr_signatures;
40
41 // Various precomputed hashes
42 std::vector<std::vector<unsigned char>> sha256;
43 std::vector<std::vector<unsigned char>> ripemd160;
44 std::vector<std::vector<unsigned char>> hash256;
45 std::vector<std::vector<unsigned char>> hash160;
46 std::map<std::vector<unsigned char>, std::vector<unsigned char>> sha256_preimages;
47 std::map<std::vector<unsigned char>, std::vector<unsigned char>> ripemd160_preimages;
48 std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash256_preimages;
49 std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash160_preimages;
50
51 TestData()
52 {
53 // All our signatures sign (and are required to sign) this constant message.
54 constexpr uint256 MESSAGE_HASH{"0000000000000000f5cd94e18b6fe77dd7aca9e35c2b0c9cbd86356c80a71065"};
55 // We don't pass additional randomness when creating a schnorr signature.
56 const auto EMPTY_AUX{uint256::ZERO};
57
58 // We generate 255 public keys and 255 hashes of each type.
59 for (int i = 1; i <= 255; ++i) {
60 // This 32-byte array functions as both private key data and hash preimage (31 zero bytes plus any nonzero byte).
61 unsigned char keydata[32] = {0};
62 keydata[31] = i;
63
64 // Compute CPubkey and CKeyID
65 CKey key;
66 key.Set(keydata, keydata + 32, true);
67 CPubKey pubkey = key.GetPubKey();
68 CKeyID keyid = pubkey.GetID();
69 pubkeys.push_back(pubkey);
70 pkhashes.emplace(pubkey, keyid);
71 pkmap.emplace(keyid, pubkey);
74 xonly_pkhashes.emplace(xonly_pubkey, xonly_hash);
75 pkmap.emplace(xonly_hash, pubkey);
76
77 // Compute ECDSA signatures on MESSAGE_HASH with the private keys.
78 std::vector<unsigned char> sig, schnorr_sig(64);
79 BOOST_CHECK(key.Sign(MESSAGE_HASH, sig));
80 sig.push_back(1); // sighash byte
81 signatures.emplace(pubkey, sig);
83 schnorr_sig.push_back(1); // Maximally sized Schnorr sigs have a sighash byte.
84 schnorr_signatures.emplace(XOnlyPubKey{pubkey}, schnorr_sig);
85
86 // Compute various hashes
87 std::vector<unsigned char> hash;
88 hash.resize(32);
89 CSHA256().Write(keydata, 32).Finalize(hash.data());
90 sha256.push_back(hash);
91 sha256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
92 CHash256().Write(keydata).Finalize(hash);
93 hash256.push_back(hash);
94 hash256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
95 hash.resize(20);
96 CRIPEMD160().Write(keydata, 32).Finalize(hash.data());
97 ripemd160.push_back(hash);
98 ripemd160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
99 CHash160().Write(keydata).Finalize(hash);
100 hash160.push_back(hash);
101 hash160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
102 }
103 }
104};
105
107std::unique_ptr<const TestData> g_testdata;
108
110enum class ChallengeType {
111 SHA256,
112 RIPEMD160,
113 HASH256,
114 HASH160,
115 OLDER,
116 AFTER,
117 PK
118};
119
120/* With each leaf condition we associate a challenge number.
121 * For hashes it's just the first 4 bytes of the hash. For pubkeys, it's the last 4 bytes.
122 */
123uint32_t ChallengeNumber(const CPubKey& pubkey) { return ReadLE32(pubkey.data() + 29); }
124uint32_t ChallengeNumber(const std::vector<unsigned char>& hash) { return ReadLE32(hash.data()); }
125
127typedef std::pair<ChallengeType, uint32_t> Challenge;
128
130struct KeyConverter {
131 typedef CPubKey Key;
132
133 const miniscript::MiniscriptContext m_script_ctx;
134
135 constexpr KeyConverter(miniscript::MiniscriptContext ctx) noexcept : m_script_ctx{ctx} {}
136
137 bool KeyCompare(const Key& a, const Key& b) const {
138 return a < b;
139 }
140
142 std::vector<unsigned char> ToPKBytes(const CPubKey& key) const {
143 if (!miniscript::IsTapscript(m_script_ctx)) {
144 return {key.begin(), key.end()};
145 }
146 const XOnlyPubKey xonly_pubkey{key};
147 return {xonly_pubkey.begin(), xonly_pubkey.end()};
148 }
149
151 std::vector<unsigned char> ToPKHBytes(const CPubKey& key) const {
152 if (!miniscript::IsTapscript(m_script_ctx)) {
153 auto hash = g_testdata->pkhashes.at(key);
154 return {hash.begin(), hash.end()};
155 }
156 const XOnlyPubKey xonly_key{key};
157 auto hash = g_testdata->xonly_pkhashes.at(xonly_key);
158 return {hash.begin(), hash.end()};
159 }
160
162 std::optional<Key> FromString(std::span<const char>& in) const {
163 auto bytes = ParseHex(std::string(in.begin(), in.end()));
164 Key key{bytes.begin(), bytes.end()};
165 if (key.IsValid()) return key;
166 return {};
167 }
168
169 template<typename I>
170 std::optional<Key> FromPKBytes(I first, I last) const {
171 if (!miniscript::IsTapscript(m_script_ctx)) {
172 Key key{first, last};
173 if (key.IsValid()) return key;
174 return {};
175 }
176 if (last - first != 32) return {};
178 std::copy(first, last, xonly_pubkey.begin());
179 return xonly_pubkey.GetEvenCorrespondingCPubKey();
180 }
181
182 template<typename I>
183 std::optional<Key> FromPKHBytes(I first, I last) const {
184 assert(last - first == 20);
186 std::copy(first, last, keyid.begin());
187 return g_testdata->pkmap.at(keyid);
188 }
189
190 std::optional<std::string> ToString(const Key& key, bool&) const {
191 return HexStr(ToPKBytes(key));
192 }
193
194 miniscript::MiniscriptContext MsContext() const {
195 return m_script_ctx;
196 }
197};
198
200struct Satisfier : public KeyConverter {
201
202 Satisfier(miniscript::MiniscriptContext ctx) noexcept : KeyConverter{ctx} {}
203
205 std::set<Challenge> supported;
206
208 bool CheckAfter(uint32_t value) const {
209 return supported.contains(Challenge(ChallengeType::AFTER, value));
210 }
211
213 bool CheckOlder(uint32_t value) const {
214 return supported.contains(Challenge(ChallengeType::OLDER, value));
215 }
216
218 miniscript::Availability Sign(const CPubKey& key, std::vector<unsigned char>& sig) const {
219 if (supported.contains(Challenge(ChallengeType::PK, ChallengeNumber(key)))) {
221 auto it = g_testdata->signatures.find(key);
222 if (it == g_testdata->signatures.end()) return miniscript::Availability::NO;
223 sig = it->second;
224 } else {
225 auto it = g_testdata->schnorr_signatures.find(XOnlyPubKey{key});
226 if (it == g_testdata->schnorr_signatures.end()) return miniscript::Availability::NO;
227 sig = it->second;
228 }
230 }
232 }
233
235 miniscript::Availability SatHash(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage, ChallengeType chtype) const {
236 if (!supported.contains(Challenge(chtype, ChallengeNumber(hash)))) return miniscript::Availability::NO;
237 const auto& m =
238 chtype == ChallengeType::SHA256 ? g_testdata->sha256_preimages :
239 chtype == ChallengeType::HASH256 ? g_testdata->hash256_preimages :
240 chtype == ChallengeType::RIPEMD160 ? g_testdata->ripemd160_preimages :
241 g_testdata->hash160_preimages;
242 auto it = m.find(hash);
243 if (it == m.end()) return miniscript::Availability::NO;
244 preimage = it->second;
246 }
247
248 // Functions that produce the preimage for hashes of various types.
249 miniscript::Availability SatSHA256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::SHA256); }
250 miniscript::Availability SatRIPEMD160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::RIPEMD160); }
251 miniscript::Availability SatHASH256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::HASH256); }
252 miniscript::Availability SatHASH160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return SatHash(hash, preimage, ChallengeType::HASH160); }
253};
254
259class TestSignatureChecker : public BaseSignatureChecker {
260 const Satisfier& ctx;
261
262public:
263 TestSignatureChecker(const Satisfier& in_ctx LIFETIMEBOUND) : ctx(in_ctx) {}
264
265 bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& pubkey, const CScript& scriptcode, SigVersion sigversion) const override {
266 CPubKey pk(pubkey);
267 if (!pk.IsValid()) return false;
268 // Instead of actually running signature validation, check if the signature matches the precomputed one for this key.
269 auto it = g_testdata->signatures.find(pk);
270 if (it == g_testdata->signatures.end()) return false;
271 return sig == it->second;
272 }
273
274 bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion,
275 ScriptExecutionData&, ScriptError*) const override {
276 XOnlyPubKey pk{pubkey};
277 auto it = g_testdata->schnorr_signatures.find(pk);
278 if (it == g_testdata->schnorr_signatures.end()) return false;
279 return std::ranges::equal(sig, it->second);
280 }
281
282 bool CheckLockTime(const CScriptNum& locktime) const override {
283 // Delegate to Satisfier.
284 return ctx.CheckAfter(locktime.GetInt64());
285 }
286
287 bool CheckSequence(const CScriptNum& sequence) const override {
288 // Delegate to Satisfier.
289 return ctx.CheckOlder(sequence.GetInt64());
290 }
291};
292
294using miniscript::operator""_mst;
295using Node = miniscript::Node<CPubKey>;
296
298std::set<Challenge> FindChallenges(const Node& root)
299{
300 std::set<Challenge> chal;
301
302 for (std::vector stack{&root}; !stack.empty();) {
303 const auto* ref{stack.back()};
304 stack.pop_back();
305
306 for (const auto& key : ref->Keys()) {
307 chal.emplace(ChallengeType::PK, ChallengeNumber(key));
308 }
309 switch (ref->Fragment()) {
310 case Fragment::OLDER: chal.emplace(ChallengeType::OLDER, ref->K()); break;
311 case Fragment::AFTER: chal.emplace(ChallengeType::AFTER, ref->K()); break;
312 case Fragment::SHA256: chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->Data())); break;
313 case Fragment::RIPEMD160: chal.emplace(ChallengeType::RIPEMD160, ChallengeNumber(ref->Data())); break;
314 case Fragment::HASH256: chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->Data())); break;
315 case Fragment::HASH160: chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->Data())); break;
316 default: break;
317 }
318 for (const auto& sub : ref->Subs()) {
319 stack.push_back(&sub);
320 }
321 }
322 return chal;
323}
324
327{
329
330 // For Taproot outputs we always use a tree with a single script and a dummy internal key.
333 return GetScriptForDestination(builder.GetOutput());
334}
335
338 // For P2WSH, it's only the witness script.
339 witness.stack.emplace_back(script.begin(), script.end());
340 if (!miniscript::IsTapscript(ctx)) return;
341 // For Tapscript we also need the control block.
342 witness.stack.push_back(*builder.GetSpendData().scripts.begin()->second.begin());
343}
344
345struct MiniScriptTest : BasicTestingSetup {
347void TestSatisfy(const KeyConverter& converter, const Node& node)
348{
349 auto script = node.ToScript(converter);
350 const auto challenges{FindChallenges(node)}; // Find all challenges in the generated miniscript.
351 std::vector<Challenge> challist(challenges.begin(), challenges.end());
352 for (int iter = 0; iter < 3; ++iter) {
353 std::shuffle(challist.begin(), challist.end(), m_rng);
354 Satisfier satisfier(converter.MsContext());
355 TestSignatureChecker checker(satisfier);
356 bool prev_mal_success = false, prev_nonmal_success = false;
357 // Go over all challenges involved in this miniscript in random order.
358 for (int add = -1; add < (int)challist.size(); ++add) {
359 if (add >= 0) satisfier.supported.insert(challist[add]); // The first iteration does not add anything
360
361 // Get the ScriptPubKey for this script, filling spend data if it's Taproot.
364
365 // Run malleable satisfaction algorithm.
367 const bool mal_success = node.Satisfy(satisfier, witness_mal.stack, false) == miniscript::Availability::YES;
369
370 // Run non-malleable satisfaction algorithm.
372 const bool nonmal_success = node.Satisfy(satisfier, witness_nonmal.stack, true) == miniscript::Availability::YES;
373 // Compute witness size (excluding script push, control block, and witness count encoding).
376
377 if (nonmal_success) {
378 // Non-malleable satisfactions are bounded by the satisfaction size plus:
379 // - For P2WSH spends, the witness script
380 // - For Tapscript spends, both the witness script and the control block
381 const size_t max_stack_size{*node.GetStackSize() + 1 + miniscript::IsTapscript(converter.MsContext())};
383 // If a non-malleable satisfaction exists, the malleable one must also exist, and be identical to it.
385 BOOST_CHECK(witness_nonmal.stack == witness_mal.stack);
386 assert(wit_size <= *node.GetWitnessSize());
387
388 // Test non-malleable satisfaction.
391 // Non-malleable satisfactions are guaranteed to be valid if ValidSatisfactions().
392 if (node.ValidSatisfactions()) BOOST_CHECK(res);
393 // More detailed: non-malleable satisfactions must be valid, or could fail with ops count error (if CheckOpsLimit failed),
394 // or with a stack size error (if CheckStackSize check fails).
396 (!node.CheckOpsLimit() && serror == ScriptError::SCRIPT_ERR_OP_COUNT) ||
397 (!node.CheckStackSize() && serror == ScriptError::SCRIPT_ERR_STACK_SIZE));
398 }
399
400 if (mal_success && (!nonmal_success || witness_mal.stack != witness_nonmal.stack)) {
401 // Test malleable satisfaction only if it's different from the non-malleable one.
404 // Malleable satisfactions are not guaranteed to be valid under any conditions, but they can only
405 // fail due to stack or ops limits.
406 BOOST_CHECK(res || serror == ScriptError::SCRIPT_ERR_OP_COUNT || serror == ScriptError::SCRIPT_ERR_STACK_SIZE);
407 }
408
409 if (node.IsSane()) {
410 // For sane nodes, the two algorithms behave identically.
412 }
413
414 // Adding more satisfied conditions can never remove our ability to produce a satisfaction.
416 // For nonmalleable solutions this is only true if the added condition is PK;
417 // for other conditions, adding one may make an valid satisfaction become malleable. If the script
418 // is sane, this cannot happen however.
419 if (node.IsSane() || add < 0 || challist[add].first == ChallengeType::PK) {
421 }
422 // Remember results for the next added challenge.
425 }
426
427 bool satisfiable = node.IsSatisfiable([](const Node&) { return true; });
428 // If the miniscript was satisfiable at all, a satisfaction must be found after all conditions are added.
430 // If the miniscript is sane and satisfiable, a nonmalleable satisfaction must eventually be found.
432 }
433}
434
435enum TestMode : int {
437 TESTMODE_INVALID = 0,
439 TESTMODE_VALID = 1,
440 TESTMODE_NONMAL = 2,
441 TESTMODE_NEEDSIG = 4,
442 TESTMODE_TIMELOCKMIX = 8,
444 TESTMODE_P2WSH_INVALID = 16,
446 TESTMODE_TAPSCRIPT_INVALID = 32,
447};
448
449void Test(const std::string& ms, const std::string& hexscript, int mode, const KeyConverter& converter,
450 int opslimit = -1, int stacklimit = -1, std::optional<uint32_t> max_wit_size = std::nullopt,
451 std::optional<uint32_t> stack_exec = {})
452{
454 const bool is_tapscript{miniscript::IsTapscript(converter.MsContext())};
455 if (mode == TESTMODE_INVALID || ((mode & TESTMODE_P2WSH_INVALID) && !is_tapscript) || ((mode & TESTMODE_TAPSCRIPT_INVALID) && is_tapscript)) {
456 BOOST_CHECK_MESSAGE(!node || !node->IsValid(), "Unexpectedly valid: " + ms);
457 } else {
458 BOOST_CHECK_MESSAGE(node, "Unparseable: " + ms);
459 BOOST_CHECK_MESSAGE(node->IsValid(), "Invalid: " + ms);
460 BOOST_CHECK_MESSAGE(node->IsValidTopLevel(), "Invalid top level: " + ms);
461 auto computed_script = node->ToScript(converter);
462 BOOST_CHECK_MESSAGE(node->ScriptSize() == computed_script.size(), "Script size mismatch: " + ms);
463 if (hexscript != "?") BOOST_CHECK_MESSAGE(HexStr(computed_script) == hexscript, "Script mismatch: " + ms + " (" + HexStr(computed_script) + " vs " + hexscript + ")");
464 BOOST_CHECK_MESSAGE(node->IsNonMalleable() == !!(mode & TESTMODE_NONMAL), "Malleability mismatch: " + ms);
465 BOOST_CHECK_MESSAGE(node->NeedsSignature() == !!(mode & TESTMODE_NEEDSIG), "Signature necessity mismatch: " + ms);
466 BOOST_CHECK_MESSAGE((node->GetType() << "k"_mst) == !(mode & TESTMODE_TIMELOCKMIX), "Timelock mix mismatch: " + ms);
468 BOOST_CHECK_MESSAGE(inferred_miniscript, "Cannot infer miniscript from script: " + ms);
469 BOOST_CHECK_MESSAGE(inferred_miniscript->ToScript(converter) == computed_script, "Roundtrip failure: miniscript->script != miniscript->script->miniscript->script: " + ms);
470 if (opslimit != -1) BOOST_CHECK_MESSAGE((int)*node->GetOps() == opslimit, "Ops limit mismatch: " << ms << " (" << *node->GetOps() << " vs " << opslimit << ")");
471 if (stacklimit != -1) BOOST_CHECK_MESSAGE((int)*node->GetStackSize() == stacklimit, "Stack limit mismatch: " << ms << " (" << *node->GetStackSize() << " vs " << stacklimit << ")");
472 if (max_wit_size) BOOST_CHECK_MESSAGE(*node->GetWitnessSize() == *max_wit_size, "Witness size limit mismatch: " << ms << " (" << *node->GetWitnessSize() << " vs " << *max_wit_size << ")");
473 if (stack_exec) BOOST_CHECK_MESSAGE(*node->GetExecStackSize() == *stack_exec, "Stack execution limit mismatch: " << ms << " (" << *node->GetExecStackSize() << " vs " << *stack_exec << ")");
475 }
476}
477
478void Test(const std::string& ms, const std::string& hexscript, const std::string& hextapscript, int mode,
479 int opslimit, int stacklimit, std::optional<uint32_t> max_wit_size,
480 std::optional<uint32_t> max_tap_wit_size,
481 std::optional<uint32_t> stack_exec)
482{
487}
488
489void Test(const std::string& ms, const std::string& hexscript, const std::string& hextapscript, int mode)
490{
492 /*opslimit=*/-1, /*stacklimit=*/-1,
493 /*max_wit_size=*/std::nullopt, /*max_tap_wit_size=*/std::nullopt, /*stack_exec=*/std::nullopt);
494}
495}; // struct MiniScriptTest
496
497} // namespace
498
500
502{
503 g_testdata.reset(new TestData());
504
505 // Validity rules
506 Test("l:older(1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // older(1): valid
507 Test("l:older(0)", "?", "?", TESTMODE_INVALID); // older(0): k must be at least 1
508 Test("l:older(2147483647)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // older(2147483647): valid
509 Test("l:older(2147483648)", "?", "?", TESTMODE_INVALID); // older(2147483648): k must be below 2^31
510 Test("u:after(1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // after(1): valid
511 Test("u:after(0)", "?", "?", TESTMODE_INVALID); // after(0): k must be at least 1
512 Test("u:after(2147483647)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // after(2147483647): valid
513 Test("u:after(2147483648)", "?", "?", TESTMODE_INVALID); // after(2147483648): k must be below 2^31
514 Test("andor(0,1,1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // andor(Bdu,B,B): valid
515 Test("andor(a:0,1,1)", "?", "?", TESTMODE_INVALID); // andor(Wdu,B,B): X must be B
516 Test("andor(0,a:1,a:1)", "?", "?", TESTMODE_INVALID); // andor(Bdu,W,W): Y and Z must be B/V/K
517 Test("andor(1,1,1)", "?", "?", TESTMODE_INVALID); // andor(Bu,B,B): X must be d
518 Test("andor(n:or_i(0,after(1)),1,1)", "?", "?", TESTMODE_VALID); // andor(Bdu,B,B): valid
519 Test("andor(or_i(0,after(1)),1,1)", "?", "?", TESTMODE_INVALID); // andor(Bd,B,B): X must be u
520 Test("c:andor(0,pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // andor(Bdu,K,K): valid
521 Test("t:andor(0,v:1,v:1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // andor(Bdu,V,V): valid
522 Test("and_v(v:1,1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // and_v(V,B): valid
523 Test("t:and_v(v:1,v:1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // and_v(V,V): valid
524 Test("c:and_v(v:1,pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // and_v(V,K): valid
525 Test("and_v(1,1)", "?", "?", TESTMODE_INVALID); // and_v(B,B): X must be V
526 Test("and_v(pk_k(02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),1)", "?", "?", TESTMODE_INVALID); // and_v(K,B): X must be V
527 Test("and_v(v:1,a:1)", "?", "?", TESTMODE_INVALID); // and_v(K,W): Y must be B/V/K
528 Test("and_b(1,a:1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // and_b(B,W): valid
529 Test("and_b(1,1)", "?", "?", TESTMODE_INVALID); // and_b(B,B): Y must W
530 Test("and_b(v:1,a:1)", "?", "?", TESTMODE_INVALID); // and_b(V,W): X must be B
531 Test("and_b(a:1,a:1)", "?", "?", TESTMODE_INVALID); // and_b(W,W): X must be B
532 Test("and_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:1)", "?", "?", TESTMODE_INVALID); // and_b(K,W): X must be B
533 Test("or_b(0,a:0)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // or_b(Bd,Wd): valid
534 Test("or_b(1,a:0)", "?", "?", TESTMODE_INVALID); // or_b(B,Wd): X must be d
535 Test("or_b(0,a:1)", "?", "?", TESTMODE_INVALID); // or_b(Bd,W): Y must be d
536 Test("or_b(0,0)", "?", "?", TESTMODE_INVALID); // or_b(Bd,Bd): Y must W
537 Test("or_b(v:0,a:0)", "?", "?", TESTMODE_INVALID); // or_b(V,Wd): X must be B
538 Test("or_b(a:0,a:0)", "?", "?", TESTMODE_INVALID); // or_b(Wd,Wd): X must be B
539 Test("or_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:0)", "?", "?", TESTMODE_INVALID); // or_b(Kd,Wd): X must be B
540 Test("t:or_c(0,v:1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // or_c(Bdu,V): valid
541 Test("t:or_c(a:0,v:1)", "?", "?", TESTMODE_INVALID); // or_c(Wdu,V): X must be B
542 Test("t:or_c(1,v:1)", "?", "?", TESTMODE_INVALID); // or_c(Bu,V): X must be d
543 Test("t:or_c(n:or_i(0,after(1)),v:1)", "?", "?", TESTMODE_VALID); // or_c(Bdu,V): valid
544 Test("t:or_c(or_i(0,after(1)),v:1)", "?", "?", TESTMODE_INVALID); // or_c(Bd,V): X must be u
545 Test("t:or_c(0,1)", "?", "?", TESTMODE_INVALID); // or_c(Bdu,B): Y must be V
546 Test("or_d(0,1)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // or_d(Bdu,B): valid
547 Test("or_d(a:0,1)", "?", "?", TESTMODE_INVALID); // or_d(Wdu,B): X must be B
548 Test("or_d(1,1)", "?", "?", TESTMODE_INVALID); // or_d(Bu,B): X must be d
549 Test("or_d(n:or_i(0,after(1)),1)", "?", "?", TESTMODE_VALID); // or_d(Bdu,B): valid
550 Test("or_d(or_i(0,after(1)),1)", "?", "?", TESTMODE_INVALID); // or_d(Bd,B): X must be u
551 Test("or_d(0,v:1)", "?", "?", TESTMODE_INVALID); // or_d(Bdu,V): Y must be B
552 Test("or_i(1,1)", "?", "?", TESTMODE_VALID); // or_i(B,B): valid
553 Test("t:or_i(v:1,v:1)", "?", "?", TESTMODE_VALID); // or_i(V,V): valid
554 Test("c:or_i(pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // or_i(K,K): valid
555 Test("or_i(a:1,a:1)", "?", "?", TESTMODE_INVALID); // or_i(W,W): X and Y must be B/V/K
556 Test("or_b(l:after(100),al:after(1000000000))", "?", "?", TESTMODE_VALID); // or_b(timelock, heighlock) valid
557 Test("and_b(after(100),a:after(1000000000))", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX); // and_b(timelock, heighlock) invalid
558 Test("pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac", "20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // alias to c:pk_k
559 Test("pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", "76a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac", "76a914fd1690c37fa3b0f04395ddc9415b220ab1ccc59588ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG); // alias to c:pk_h
560
561 // Randomly generated test set that covers the majority of type and node type combinations
562 Test("lltvln:after(1231488000)", "6300676300676300670400046749b1926869516868", "=", TESTMODE_VALID | TESTMODE_NONMAL, 12, 3, 3, 3, 3);
563 Test("uuj:and_v(v:multi(2,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),after(1231488000))", "6363829263522103d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a21025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc52af0400046749b168670068670068", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_TAPSCRIPT_INVALID, 14, 5, 2 + 2 + 1 + 2 * 73, 0, 7);
564 Test("or_b(un:multi(2,03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),al:older(16))", "63522103daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee872921024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c9752ae926700686b63006760b2686c9b", "?", TESTMODE_VALID | TESTMODE_TAPSCRIPT_INVALID, 14, 5, 2 + 1 + 2 * 73 + 2, 0, 8);
565 Test("j:and_v(vdv:after(1567547623),older(2016))", "829263766304e7e06e5db169686902e007b268", "=", TESTMODE_VALID | TESTMODE_NONMAL, 11, 1, 2, 2, 2);
566 Test("t:and_v(vu:hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),v:sha256(ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5))", "6382012088aa20131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b876700686982012088a820ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc58851", "6382012088aa20131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b876700686982012088a820ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc58851", TESTMODE_VALID | TESTMODE_NONMAL, 12, 3, 2 + 33 + 33, 2 + 33 + 33, 4);
567 Test("t:andor(multi(3,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13),v:older(4194305),v:sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2))", "532102d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a14602975562102e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd1353ae6482012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2886703010040b2696851", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TAPSCRIPT_INVALID, 13, 5, 1 + 3 * 73, 0, 10);
568 Test("or_d(multi(1,02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9),or_b(multi(3,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,032fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a),su:after(500000)))", "512102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f951ae73645321022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a0121032fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f2103d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a53ae7c630320a107b16700689b68", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TAPSCRIPT_INVALID, 15, 7, 2 + 1 + 3 * 73 + 1, 0, 10);
569 Test("or_d(sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6),and_n(un:after(499999999),older(4194305)))", "82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868", "82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868", TESTMODE_VALID, 16, 1, 33, 33, 3);
570 Test("and_v(or_i(v:multi(2,02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb),v:multi(2,03e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)),sha256(d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68))", "63522102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee52103774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb52af67522103e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a21025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc52af6882012088a820d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c6887", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_TAPSCRIPT_INVALID, 11, 5, 2 + 1 + 2 * 73 + 33, 0, 8);
571 Test("j:and_b(multi(2,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),s:or_i(older(1),older(4252898)))", "82926352210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c9752ae7c6351b26703e2e440b2689a68", "?", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_TAPSCRIPT_INVALID, 14, 4, 1 + 2 * 73 + 2, 0, 8);
572 Test("and_b(older(16),s:or_d(sha256(e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f),n:after(1567547623)))", "60b27c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87736404e7e06e5db192689a", "=", TESTMODE_VALID, 12, 1, 33, 33, 4);
573 Test("j:and_v(v:hash160(20195b5a3d650c17f0f29f91c33f8f6335193d07),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))", "82926382012088a91420195b5a3d650c17f0f29f91c33f8f6335193d078882012088a82096de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c4787736460b26868", "=", TESTMODE_VALID, 16, 2, 33 + 33, 33 + 33, 4);
574 Test("and_b(hash256(32ba476771d01e37807990ead8719f08af494723de1d228f2c2c07cc0aa40bac),a:and_b(hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),a:older(1)))", "82012088aa2032ba476771d01e37807990ead8719f08af494723de1d228f2c2c07cc0aa40bac876b82012088aa20131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b876b51b26c9a6c9a", "=", TESTMODE_VALID | TESTMODE_NONMAL, 15, 2, 33 + 33, 33 + 33, 4);
575 Test("thresh(2,multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),a:multi(1,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),ac:pk_k(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01))", "522103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c721036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a0052ae6b5121036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a0051ae6c936b21022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01ac6c935287", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_TAPSCRIPT_INVALID, 13, 6, 1 + 2 * 73 + 1 + 73 + 1, 0, 10);
576 Test("and_n(sha256(d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68),t:or_i(v:older(4252898),v:older(144)))", "82012088a820d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68876400676303e2e440b26967029000b269685168", "=", TESTMODE_VALID, 14, 2, 33 + 2, 33 + 2, 4);
577 Test("or_d(nd:and_v(v:older(4252898),v:older(4252898)),sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6))", "766303e2e440b26903e2e440b2696892736482012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68768", "=", TESTMODE_VALID, 15, 2, 1 + 33, 1 + 33, 3);
578 Test("c:and_v(or_c(sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2),v:multi(1,02c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db)),pk_k(03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))", "82012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed28764512102c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db51af682103acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbeac", "?", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_TAPSCRIPT_INVALID, 8, 2, 33 + 73, 0, 4);
579 Test("c:and_v(or_c(multi(2,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00,02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),v:ripemd160(1b0f3c404d12075c68c938f9f60ebea4f74941a0)),pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "5221036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a002102352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d552ae6482012088a6141b0f3c404d12075c68c938f9f60ebea4f74941a088682103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_TAPSCRIPT_INVALID, 10, 5, 1 + 2 * 73 + 73, 0, 9);
580 Test("and_v(andor(hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),v:hash256(939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735),v:older(50000)),after(499999999))", "82012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b2587640350c300b2696782012088aa20939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735886804ff64cd1db1", "=", TESTMODE_VALID, 14, 2, 33 + 33, 33 + 33, 4);
581 Test("andor(hash256(5f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040),j:and_v(v:hash160(3a2bff0da9d96868e66abc4427bea4691cf61ccd),older(4194305)),ripemd160(44d90e2d3714c8663b632fcf0f9d5f22192cc4c8))", "82012088aa205f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040876482012088a61444d90e2d3714c8663b632fcf0f9d5f22192cc4c8876782926382012088a9143a2bff0da9d96868e66abc4427bea4691cf61ccd8803010040b26868", "=", TESTMODE_VALID, 20, 2, 33 + 33, 33 + 33, 4);
582 Test("or_i(c:and_v(v:after(500000),pk_k(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)),sha256(d9147961436944f43cd99d28b2bbddbf452ef872b30c8279e255e7daafc7f946))", "630320a107b1692102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ac6782012088a820d9147961436944f43cd99d28b2bbddbf452ef872b30c8279e255e7daafc7f9468768", "630320a107b16920c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ac6782012088a820d9147961436944f43cd99d28b2bbddbf452ef872b30c8279e255e7daafc7f9468768", TESTMODE_VALID | TESTMODE_NONMAL, 10, 2, 2 + 73, 2 + 66, 3);
583 Test("thresh(2,c:pk_h(025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc),s:sha256(e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f),a:hash160(dd69735817e0e3f6f826a9238dc2e291184f0131))", "76a9145dedfbf9ea599dd4e3ca6a80b333c472fd0b3f6988ac7c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87936b82012088a914dd69735817e0e3f6f826a9238dc2e291184f0131876c935287", "76a9141a7ac36cfa8431ab2395d701b0050045ae4a37d188ac7c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87936b82012088a914dd69735817e0e3f6f826a9238dc2e291184f0131876c935287", TESTMODE_VALID, 18, 4, 1 + 34 + 33 + 33, 1 + 33 + 33 + 33, 6);
584 Test("and_n(sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2),uc:and_v(v:older(144),pk_k(03fe72c435413d33d48ac09c9161ba8b09683215439d62b7940502bda8b202e6ce)))", "82012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed28764006763029000b2692103fe72c435413d33d48ac09c9161ba8b09683215439d62b7940502bda8b202e6ceac67006868", "82012088a8209267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed28764006763029000b26920fe72c435413d33d48ac09c9161ba8b09683215439d62b7940502bda8b202e6ceac67006868", TESTMODE_VALID | TESTMODE_NEEDSIG, 13, 3, 33 + 2 + 73, 33 + 2 + 66, 5);
585 Test("and_n(c:pk_k(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),and_b(l:older(4252898),a:older(16)))", "2103daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729ac64006763006703e2e440b2686b60b26c9a68", "20daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729ac64006763006703e2e440b2686b60b26c9a68", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_TIMELOCKMIX, 12, 2, 73 + 1, 66 + 1, 3);
586 Test("c:or_i(and_v(v:older(16),pk_h(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)),pk_h(026a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4))", "6360b26976a9149fc5dbe5efdce10374a4dd4053c93af540211718886776a9142fbd32c8dd59ee7c17e66cb6ebea7e9846c3040f8868ac", "6360b26976a9144d4421361c3289bdad06441ffaee8be8e786f1ad886776a91460d4a7bcbd08f58e58bd208d1069837d7adb16ae8868ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 12, 3, 2 + 34 + 73, 2 + 33 + 66, 4);
587 Test("or_d(c:pk_h(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13),andor(c:pk_k(024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),older(2016),after(1567547623)))", "76a914c42e7ef92fdb603af844d064faad95db9bcdfd3d88ac736421024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97ac6404e7e06e5db16702e007b26868", "76a91421ab1a140d0d305b8ff62bdb887d9fef82c9899e88ac7364204ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97ac6404e7e06e5db16702e007b26868", TESTMODE_VALID | TESTMODE_NONMAL, 13, 3, 1 + 34 + 73, 1 + 33 + 66, 5);
588 Test("c:andor(ripemd160(6ad07d21fd5dfc646f0b30577045ce201616b9ba),pk_h(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e),and_v(v:hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),pk_h(03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a)))", "82012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba876482012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b258876a914dd100be7d9aea5721158ebde6d6a1fd8fff93bb1886776a9149fc5dbe5efdce10374a4dd4053c93af5402117188868ac", "82012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba876482012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b258876a914a63d1e4d2ed109246c600ec8c19cce546b65b1cc886776a9144d4421361c3289bdad06441ffaee8be8e786f1ad8868ac", TESTMODE_VALID | TESTMODE_NEEDSIG, 18, 3, 33 + 34 + 73, 33 + 33 + 66, 5);
589 Test("c:andor(u:ripemd160(6ad07d21fd5dfc646f0b30577045ce201616b9ba),pk_h(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),or_i(pk_h(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01),pk_h(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)))", "6382012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba87670068646376a9149652d86bedf43ad264362e6e6eba6eb764508127886776a914751e76e8199196d454941c45d1b3a323f1433bd688686776a91420d637c1a6404d2227f3561fdbaff5a680dba6488868ac", "6382012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba87670068646376a914ceedcb44b38bdbcb614d872223964fd3dca8a434886776a914f678d9b79045452c8c64e9309d0f0046056e26c588686776a914a2a75e1819afa208f6c89ae0da43021116dfcb0c8868ac", TESTMODE_VALID | TESTMODE_NEEDSIG, 23, 4, 2 + 33 + 34 + 73, 2 + 33 + 33 + 66, 5);
590 Test("c:or_i(andor(c:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk_h(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01),pk_h(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)),pk_k(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e))", "6376a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac6476a91406afd46bcdfd22ef94ac122aa11f241244a37ecc886776a9149652d86bedf43ad264362e6e6eba6eb7645081278868672102d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e68ac", "6376a914fd1690c37fa3b0f04395ddc9415b220ab1ccc59588ac6476a9149b652a14674a506079f574d20ca7daef6f9a66bb886776a914ceedcb44b38bdbcb614d872223964fd3dca8a43488686720d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e68ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG, 17, 5, 2 + 34 + 73 + 34 + 73, 2 + 33 + 66 + 33 + 66, 6);
591 Test("thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(1000000000),altv:after(100))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670400ca9a3bb16951686c936b6300670164b16951686c935187", "20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670400ca9a3bb16951686c936b6300670164b16951686c935187", TESTMODE_VALID, 18, 3, 73 + 2 + 2, 66 + 2 + 2, 4);
592 Test("thresh(2,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),ac:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),altv:after(1000000000),altv:after(100))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac6c936b6300670400ca9a3bb16951686c936b6300670164b16951686c935287", "20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac6c936b6300670400ca9a3bb16951686c936b6300670164b16951686c935287", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX, 22, 4, 73 + 73 + 2 + 2, 66 + 66 + 2 + 2, 5);
593
594 // Additional Tapscript-related tests
595 // Edge cases when parsing multi_a from script:
596 // - no pubkey at all
597 // - no pubkey before a CHECKSIGADD
598 // - no pubkey before the CHECKSIG
601 const auto no_pubkey{"ac519c"_hex_u8};
602 BOOST_CHECK(miniscript::FromScript({no_pubkey.begin(), no_pubkey.end()}, tap_converter) == std::nullopt);
603 const auto incomplete_multi_a{"ba20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba519c"_hex_u8};
605 const auto incomplete_multi_a_2{"ac2079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba519c"_hex_u8};
607 // Can use multi_a under Tapscript but not P2WSH.
608 Test("and_v(v:multi_a(2,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),after(1231488000))", "?", "20d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85aac205601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7ccba529d0400046749b1", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4, 2, {}, {}, 3);
609 // Can use more than 20 keys in a multi_a.
610 std::string ms_str_multi_a{"multi_a(1,"};
611 for (size_t i = 0; i < 21; ++i) {
612 ms_str_multi_a += HexStr(g_testdata->pubkeys[i]);
613 if (i < 20) ms_str_multi_a += ",";
614 }
615 ms_str_multi_a += ")";
616 Test(ms_str_multi_a, "?", "2079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba20f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9ba20e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13ba202f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4ba20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ba205cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bcba202f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01ba20acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbeba20a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ba20774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cbba20d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85aba20f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8ba20499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4ba20d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080eba20e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0aba20defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34ba205601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7ccba202b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6cba204ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97ba20352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5ba519c", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 22, 21, {}, {}, 22);
617 // Since 'd:' is 'u' we can use it directly inside a thresh. But we can't under P2WSH.
618 Test("thresh(2,dv:older(42),s:pk(025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", "?", "7663012ab269687c205cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bcac937c20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac935287", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 12, 3, {}, {}, 4);
619 // We can have a script that has more than 201 ops (n = 99), that needs a stack size > 100 (n = 110), or has a
620 // script that is larger than 3600 bytes (n = 200). All that can't be under P2WSH.
621 for (const auto pk_count: {99, 110, 200}) {
622 std::string ms_str_large;
623 for (auto i = 0; i < pk_count - 1; ++i) {
624 ms_str_large += "and_b(pk(" + HexStr(g_testdata->pubkeys[i]) + "),a:";
625 }
626 ms_str_large += "pk(" + HexStr(g_testdata->pubkeys[pk_count - 1]) + ")";
627 ms_str_large.insert(ms_str_large.end(), pk_count - 1, ')');
628 Test(ms_str_large, "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, pk_count + (pk_count - 1) * 3, pk_count, {}, {}, pk_count + 1);
629 }
630 // We can have a script that reaches a stack size of 1000 during execution.
631 std::string ms_stack_limit;
632 auto count{998};
633 for (auto i = 0; i < count; ++i) {
634 ms_stack_limit += "and_b(older(1),a:";
635 }
636 ms_stack_limit += "pk(" + HexStr(g_testdata->pubkeys[0]) + ")";
637 ms_stack_limit.insert(ms_stack_limit.end(), count, ')');
639 BOOST_CHECK(ms_stack_ok && ms_stack_ok->CheckStackSize());
640 Test(ms_stack_limit, "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4 * count + 1, 1, {}, {}, 1 + count + 1);
641 // But one more element on the stack during execution will make it fail. And we'd detect that.
642 count++;
643 ms_stack_limit = "and_b(older(1),a:" + ms_stack_limit + ")";
645 BOOST_CHECK(ms_stack_nok && !ms_stack_nok->CheckStackSize());
646 Test(ms_stack_limit, "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4 * count + 1, 1, {}, {}, 1 + count + 1);
647
648 // Misc unit tests
649 // A Script with a non minimal push is invalid
650 constexpr auto nonminpush{"0000210232780000feff00ffffffffffff21ff005f00ae21ae00000000060602060406564c2102320000060900fe00005f00ae21ae00100000060606060606000000000000000000000000000000000000000000000000000000000000000000"_hex_u8};
651 const CScript nonminpush_script(nonminpush.begin(), nonminpush.end());
654 // A non-minimal VERIFY (<key> CHECKSIG VERIFY 1)
655 constexpr auto nonminverify{"2103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ac6951"_hex_u8};
659 // A threshold as large as the number of subs is valid.
660 Test("thresh(2,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(100))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287", "20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
661 // A threshold of 1 is valid.
662 Test("thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", "20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
663 // A threshold with a k larger than the number of subs is invalid
664 Test("thresh(3,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", "=", TESTMODE_INVALID);
665 // A threshold with a k null is invalid
666 Test("thresh(0,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))", "2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", "=", TESTMODE_INVALID);
667 // For CHECKMULTISIG the OP cost is the number of keys, but the stack size is the number of sigs (+1)
668 const auto ms_multi = miniscript::FromString("multi(1,03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", wsh_converter);
670 BOOST_CHECK_EQUAL(*ms_multi->GetOps(), 4); // 3 pubkeys + CMS
671 BOOST_CHECK_EQUAL(*ms_multi->GetStackSize(), 2); // 1 sig + dummy elem
672 // The 'd:' wrapper leaves on the stack what was DUP'ed at the beginning of its execution.
673 // Since it contains an OP_IF just after on the same element, we can make sure that the element
674 // in question must be OP_1 if OP_IF enforces that its argument must only be OP_1 or the empty
675 // vector (since otherwise the execution would immediately fail). This is the MINIMALIF rule.
676 // Unfortunately, this rule is consensus for Taproot but only policy for P2WSH. Therefore we can't
677 // (for now) have 'd:' be 'u'. This tests we can't use a 'd:' wrapper for a thresh, which requires
678 // its subs to all be 'u' (taken from https://github.com/rust-bitcoin/rust-miniscript/discussions/341).
679 const auto ms_minimalif = miniscript::FromString("thresh(3,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),sc:pk_k(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798),sdv:older(32))", wsh_converter);
680 BOOST_CHECK(ms_minimalif && !ms_minimalif->IsValid());
681 // A Miniscript with duplicate keys is not sane
682 const auto ms_dup1 = miniscript::FromString("and_v(v:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", wsh_converter);
684 BOOST_CHECK(!ms_dup1->IsSane() && !ms_dup1->CheckDuplicateKey());
685 // Same with a disjunction, and different key nodes (pk and pkh)
686 const auto ms_dup2 = miniscript::FromString("or_b(c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),ac:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", wsh_converter);
687 BOOST_CHECK(ms_dup2 && !ms_dup2->IsSane() && !ms_dup2->CheckDuplicateKey());
688 // Same when the duplicates are leaves or a larger tree
689 const auto ms_dup3 = miniscript::FromString("or_i(and_b(pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556)),and_b(older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", wsh_converter);
690 BOOST_CHECK(ms_dup3 && !ms_dup3->IsSane() && !ms_dup3->CheckDuplicateKey());
691 // Same when the duplicates are on different levels in the tree
692 const auto ms_dup4 = miniscript::FromString("thresh(2,pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),a:and_b(dv:older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", wsh_converter);
693 BOOST_CHECK(ms_dup4 && !ms_dup4->IsSane() && !ms_dup4->CheckDuplicateKey());
694 // Sanity check the opposite is true, too. An otherwise sane Miniscript with no duplicate keys is sane.
695 const auto ms_nondup = miniscript::FromString("pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", wsh_converter);
696 BOOST_CHECK(ms_nondup && ms_nondup->CheckDuplicateKey() && ms_nondup->IsSane());
697 // Test we find the first insane sub closer to be a leaf node. This fragment is insane for two reasons:
698 // 1. It can be spent without a signature
699 // 2. It contains timelock mixes
700 // We'll report the timelock mix error, as it's "deeper" (closer to be a leaf node) than the "no 's' property"
701 // error is.
702 const auto ms_ins = miniscript::FromString("or_i(and_b(after(1),a:after(1000000000)),pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204))", wsh_converter);
703 BOOST_CHECK(ms_ins && ms_ins->IsValid() && !ms_ins->IsSane());
704 const auto insane_sub = ms_ins->FindInsaneSub();
705 BOOST_CHECK(insane_sub && *insane_sub->ToString(wsh_converter) == "and_b(after(1),a:after(1000000000))");
706
707 // Numbers can't be prefixed by a sign.
710 BOOST_CHECK(!miniscript::FromString("thresh(-1,pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204))", wsh_converter));
711 BOOST_CHECK(!miniscript::FromString("multi(+1,03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204)", wsh_converter));
712
713 // Timelock tests
714 Test("after(100)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // only heightlock
715 Test("after(1000000000)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // only timelock
716 Test("or_b(l:after(100),al:after(1000000000))", "?", "?", TESTMODE_VALID); // or_b(timelock, heighlock) valid
717 Test("and_b(after(100),a:after(1000000000))", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX); // and_b(timelock, heighlock) invalid
718 /* This is correctly detected as non-malleable but for the wrong reason. The type system assumes that branches 1 and 2
719 can be spent together to create a non-malleble witness, but because of mixing of timelocks they cannot be spent together.
720 But since exactly one of the two after's can be satisfied, the witness involving the key cannot be malleated.
721 */
722 Test("thresh(2,ltv:after(1000000000),altv:after(100),a:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", "?", "?", TESTMODE_VALID | TESTMODE_TIMELOCKMIX | TESTMODE_NONMAL); // thresh with k = 2
723 // This is actually non-malleable in practice, but we cannot detect it in type system. See above rationale
724 Test("thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(1000000000),altv:after(100))", "?", "?", TESTMODE_VALID); // thresh with k = 1
725
726 g_testdata.reset();
727}
728
729// Confirm that ~Node(), Node::Clone() and operator=(Node&&) are stack-safe.
731{
735
736 constexpr auto ctx{miniscript::MiniscriptContext::P2WSH};
737
738 NodeU32 root{NoDupCheck{}, ctx, Fragment::JUST_1};
739 for (uint32_t i{0}; i < 200'000; ++i) {
740 root = NodeU32{NoDupCheck{}, ctx, Fragment::WRAP_S, Vector(std::move(root))};
741 }
742 BOOST_CHECK_EQUAL(root.ScriptSize(), 200'001);
743
744 auto clone{root.Clone()};
745 BOOST_CHECK_EQUAL(clone.ScriptSize(), root.ScriptSize());
746
747 clone = std::move(root);
748}
749
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
#define LIFETIMEBOUND
Definition attributes.h:16
A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160).
Definition hash.h:49
CHash160 & Write(std::span< const unsigned char > input)
Definition hash.h:62
void Finalize(std::span< unsigned char > output)
Definition hash.h:55
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
Definition hash.h:24
void Finalize(std::span< unsigned char > output)
Definition hash.h:30
CHash256 & Write(std::span< const unsigned char > input)
Definition hash.h:37
An encapsulated private key.
Definition key.h:36
bool SignSchnorr(const uint256 &hash, std::span< unsigned char > sig, const uint256 *merkle_root, const uint256 &aux) const
Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this, optionally tweaked b...
Definition key.cpp:273
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:209
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition key.cpp:183
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition key.h:104
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 * data() const
Definition pubkey.h:113
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition pubkey.h:160
bool IsValid() const
Definition pubkey.h:185
const unsigned char * end() const
Definition pubkey.h:115
const unsigned char * begin() const
Definition pubkey.h:114
A hasher class for RIPEMD-160.
Definition ripemd160.h:13
CRIPEMD160 & Write(const unsigned char *data, size_t len)
void Finalize(unsigned char hash[OUTPUT_SIZE])
A hasher class for SHA-256.
Definition sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition sha256.cpp:725
CSHA256 & Write(const unsigned char *data, size_t len)
Definition sha256.cpp:699
Serialized script, used inside transaction inputs and outputs.
Definition script.h:405
Utility class to construct Taproot outputs from internal key and script tree.
static const XOnlyPubKey NUMS_H
Nothing Up My Sleeve point H Used as an internal key for provably disabling the key path spend see BI...
Definition pubkey.h:195
A node in a miniscript expression.
Definition miniscript.h:533
160-bit opaque blob.
Definition uint256.h:183
256-bit opaque blob.
Definition uint256.h:195
static const uint256 ZERO
Definition uint256.h:203
uint32_t ReadLE32(const B *ptr)
Definition common.h:27
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition hash.h:92
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition hash.h:222
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition hex_base.cpp:30
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, script_verify_flags flags, const BaseSignatureChecker &checker, ScriptError *serror)
SigVersion
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
uint64_t sequence
BOOST_AUTO_TEST_CASE(fixed_tests)
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
Definition miniscript.h:257
std::optional< Node< typename Ctx::Key > > FromScript(const CScript &script, const Ctx &ctx)
std::optional< Node< typename Ctx::Key > > FromString(const std::string &str, const Ctx &ctx)
Fragment
The different node types in miniscript.
Definition miniscript.h:211
@ 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
Internal RIPEMD-160 implementation.
Definition ripemd160.cpp:16
Internal SHA-256 implementation.
Definition sha256.cpp:68
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:17
#define BOOST_CHECK(expr)
Definition object.cpp:16
static constexpr script_verify_flags STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Definition policy.h:118
@ OP_0
Definition script.h:76
enum ScriptError_t ScriptError
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition serialize.h:288
uint64_t GetSerializeSize(const T &t)
Definition serialize.h:1095
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Basic testing setup.
std::vector< std::vector< unsigned char > > stack
Definition script.h:580
Context for solving a Miniscript.
Definition sign.cpp:404
miniscript::Availability SatRIPEMD160(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Definition sign.cpp:450
bool CheckAfter(uint32_t value) const
Time lock satisfactions.
Definition sign.cpp:443
const miniscript::MiniscriptContext m_script_ctx
The context of the script we are satisfying (either P2WSH or Tapscript).
Definition sign.cpp:412
miniscript::Availability SatSHA256(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Hash preimage satisfactions.
Definition sign.cpp:447
miniscript::Availability SatHASH256(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Definition sign.cpp:453
Satisfier(const SigningProvider &provider LIFETIMEBOUND, SignatureData &sig_data LIFETIMEBOUND, const BaseSignatureCreator &creator LIFETIMEBOUND, const CScript &witscript LIFETIMEBOUND, miniscript::MiniscriptContext script_ctx)
Definition sign.cpp:414
miniscript::Availability SatHASH160(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Definition sign.cpp:456
bool CheckOlder(uint32_t value) const
Definition sign.cpp:444
static int count
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:73
assert(!tx.IsCoinBase())
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition vector.h:23