11 #include <boost/test/unit_test.hpp>
30 std::vector<CPubKey> pubkeys;
32 std::map<CPubKey, CKeyID> pkhashes;
33 std::map<CKeyID, CPubKey> pkmap;
34 std::map<XOnlyPubKey, CKeyID> xonly_pkhashes;
35 std::map<CPubKey, std::vector<unsigned char>>
signatures;
36 std::map<XOnlyPubKey, std::vector<unsigned char>> schnorr_signatures;
39 std::vector<std::vector<unsigned char>>
sha256;
40 std::vector<std::vector<unsigned char>>
ripemd160;
41 std::vector<std::vector<unsigned char>> hash256;
42 std::vector<std::vector<unsigned char>> hash160;
43 std::map<std::vector<unsigned char>, std::vector<unsigned char>> sha256_preimages;
44 std::map<std::vector<unsigned char>, std::vector<unsigned char>> ripemd160_preimages;
45 std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash256_preimages;
46 std::map<std::vector<unsigned char>, std::vector<unsigned char>> hash160_preimages;
51 auto const MESSAGE_HASH =
uint256S(
"f5cd94e18b6fe77dd7aca9e35c2b0c9cbd86356c80a71065");
56 for (
int i = 1; i <= 255; ++i) {
58 unsigned char keydata[32] = {0};
63 key.
Set(keydata, keydata + 32,
true);
66 pubkeys.push_back(pubkey);
67 pkhashes.emplace(pubkey, keyid);
68 pkmap.emplace(keyid, pubkey);
71 xonly_pkhashes.emplace(xonly_pubkey, xonly_hash);
72 pkmap.emplace(xonly_hash, pubkey);
75 std::vector<unsigned char> sig, schnorr_sig(64);
80 schnorr_sig.push_back(1);
81 schnorr_signatures.emplace(
XOnlyPubKey{pubkey}, schnorr_sig);
84 std::vector<unsigned char> hash;
88 sha256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
90 hash256.push_back(hash);
91 hash256_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
95 ripemd160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
97 hash160.push_back(hash);
98 hash160_preimages[hash] = std::vector<unsigned char>(keydata, keydata + 32);
104 std::unique_ptr<const TestData> g_testdata;
107 enum class ChallengeType {
121 uint32_t ChallengeNumber(
const std::vector<unsigned char>& hash) {
return ReadLE32(hash.data()); }
124 typedef std::pair<ChallengeType, uint32_t> Challenge;
127 struct KeyConverter {
134 bool KeyCompare(
const Key& a,
const Key& b)
const {
139 std::vector<unsigned char> ToPKBytes(
const CPubKey& key)
const {
144 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
148 std::vector<unsigned char> ToPKHBytes(
const CPubKey& key)
const {
150 auto hash = g_testdata->pkhashes.at(key);
151 return {hash.begin(), hash.end()};
154 auto hash = g_testdata->xonly_pkhashes.at(xonly_key);
155 return {hash.
begin(), hash.end()};
160 std::optional<Key>
FromString(I first, I last)
const {
161 auto bytes =
ParseHex(std::string(first, last));
162 Key key{bytes.
begin(), bytes.end()};
168 std::optional<Key> FromPKBytes(I first, I last)
const {
170 Key key{first, last};
174 if (last - first != 32)
return {};
176 std::copy(first, last, xonly_pubkey.
begin());
181 std::optional<Key> FromPKHBytes(I first, I last)
const {
182 assert(last - first == 20);
184 std::copy(first, last, keyid.
begin());
185 return g_testdata->pkmap.at(keyid);
188 std::optional<std::string>
ToString(
const Key& key)
const {
189 return HexStr(ToPKBytes(key));
203 std::set<Challenge> supported;
207 return supported.count(Challenge(ChallengeType::AFTER, value));
212 return supported.count(Challenge(ChallengeType::OLDER, value));
217 if (supported.count(Challenge(ChallengeType::PK, ChallengeNumber(key)))) {
219 auto it = g_testdata->signatures.find(key);
223 auto it = g_testdata->schnorr_signatures.find(
XOnlyPubKey{key});
233 miniscript::Availability SatHash(
const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage, ChallengeType chtype)
const {
236 chtype == ChallengeType::SHA256 ? g_testdata->sha256_preimages :
237 chtype == ChallengeType::HASH256 ? g_testdata->hash256_preimages :
239 g_testdata->hash160_preimages;
240 auto it =
m.find(hash);
242 preimage = it->second;
247 miniscript::Availability SatSHA256(
const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage)
const {
return SatHash(hash, preimage, ChallengeType::SHA256); }
249 miniscript::Availability SatHASH256(
const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage)
const {
return SatHash(hash, preimage, ChallengeType::HASH256); }
250 miniscript::Availability SatHASH160(
const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage)
const {
return SatHash(hash, preimage, ChallengeType::HASH160); }
258 const Satisfier& ctx;
261 TestSignatureChecker(
const Satisfier& in_ctx
LIFETIMEBOUND) : ctx(in_ctx) {}
265 if (!
pk.IsValid())
return false;
267 auto it = g_testdata->signatures.find(
pk);
268 if (it == g_testdata->signatures.end())
return false;
269 return sig == it->second;
275 auto it = g_testdata->schnorr_signatures.find(
pk);
276 if (it == g_testdata->schnorr_signatures.end())
return false;
277 return sig == it->second;
282 return ctx.CheckAfter(locktime.
GetInt64());
287 return ctx.CheckOlder(
sequence.GetInt64());
292 const std::vector<unsigned char> NUMS_PK{
ParseHex(
"50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};
296 using miniscript::operator
"" _mst;
301 std::set<Challenge> FindChallenges(
const NodeRef& ref) {
302 std::set<Challenge> chal;
303 for (
const auto& key : ref->keys) {
304 chal.emplace(ChallengeType::PK, ChallengeNumber(key));
307 chal.emplace(ChallengeType::OLDER, ref->k);
309 chal.emplace(ChallengeType::AFTER, ref->k);
311 chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data));
315 chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data));
317 chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data));
319 for (
const auto& sub : ref->subs) {
320 auto sub_chal = FindChallenges(sub);
321 chal.insert(sub_chal.begin(), sub_chal.end());
347 void TestSatisfy(
const KeyConverter& converter,
const std::string& testcase,
const NodeRef&
node) {
348 auto script =
node->ToScript(converter);
349 auto challenges = FindChallenges(
node);
350 std::vector<Challenge> challist(challenges.begin(), challenges.end());
351 for (
int iter = 0; iter < 3; ++iter) {
353 Satisfier satisfier(converter.MsContext());
354 TestSignatureChecker checker(satisfier);
355 bool prev_mal_success =
false, prev_nonmal_success =
false;
357 for (
int add = -1; add < (int)challist.size(); ++add) {
358 if (add >= 0) satisfier.supported.insert(challist[add]);
362 const CScript script_pubkey{ScriptPubKey(converter.MsContext(), script, builder)};
367 SatisfactionToWitness(converter.MsContext(), witness_mal, script, builder);
374 SatisfactionToWitness(converter.MsContext(), witness_nonmal, script, builder);
376 if (nonmal_success) {
385 assert(wit_size <= *node->GetWitnessSize());
399 if (mal_success && (!nonmal_success || witness_mal.
stack != witness_nonmal.
stack)) {
408 if (
node->IsSane()) {
418 if (
node->IsSane() || add < 0 || challist[add].first == ChallengeType::PK) {
419 BOOST_CHECK(nonmal_success >= prev_nonmal_success);
422 prev_mal_success = mal_success;
423 prev_nonmal_success = nonmal_success;
426 bool satisfiable =
node->IsSatisfiable([](
const Node&) {
return true; });
434 enum TestMode :
int {
436 TESTMODE_INVALID = 0,
440 TESTMODE_NEEDSIG = 4,
441 TESTMODE_TIMELOCKMIX = 8,
443 TESTMODE_P2WSH_INVALID = 16,
445 TESTMODE_TAPSCRIPT_INVALID = 32,
448 void Test(
const std::string& ms,
const std::string& hexscript,
int mode,
const KeyConverter& converter,
449 int opslimit = -1,
int stacklimit = -1, std::optional<uint32_t> max_wit_size = std::nullopt,
450 std::optional<uint32_t> stack_exec = {})
454 if (mode == TESTMODE_INVALID || ((mode & TESTMODE_P2WSH_INVALID) && !is_tapscript) || ((mode & TESTMODE_TAPSCRIPT_INVALID) && is_tapscript)) {
455 BOOST_CHECK_MESSAGE(!
node || !
node->IsValid(),
"Unexpectedly valid: " + ms);
457 BOOST_CHECK_MESSAGE(
node,
"Unparseable: " + ms);
458 BOOST_CHECK_MESSAGE(
node->IsValid(),
"Invalid: " + ms);
459 BOOST_CHECK_MESSAGE(
node->IsValidTopLevel(),
"Invalid top level: " + ms);
460 auto computed_script =
node->ToScript(converter);
461 BOOST_CHECK_MESSAGE(
node->ScriptSize() == computed_script.size(),
"Script size mismatch: " + ms);
462 if (hexscript !=
"?") BOOST_CHECK_MESSAGE(
HexStr(computed_script) == hexscript,
"Script mismatch: " + ms +
" (" +
HexStr(computed_script) +
" vs " + hexscript +
")");
463 BOOST_CHECK_MESSAGE(
node->IsNonMalleable() == !!(mode & TESTMODE_NONMAL),
"Malleability mismatch: " + ms);
464 BOOST_CHECK_MESSAGE(
node->NeedsSignature() == !!(mode & TESTMODE_NEEDSIG),
"Signature necessity mismatch: " + ms);
465 BOOST_CHECK_MESSAGE((
node->GetType() <<
"k"_mst) == !(mode & TESTMODE_TIMELOCKMIX),
"Timelock mix mismatch: " + ms);
467 BOOST_CHECK_MESSAGE(inferred_miniscript,
"Cannot infer miniscript from script: " + ms);
468 BOOST_CHECK_MESSAGE(inferred_miniscript->ToScript(converter) == computed_script,
"Roundtrip failure: miniscript->script != miniscript->script->miniscript->script: " + ms);
469 if (opslimit != -1) BOOST_CHECK_MESSAGE((
int)*
node->GetOps() == opslimit,
"Ops limit mismatch: " << ms <<
" (" << *
node->GetOps() <<
" vs " << opslimit <<
")");
470 if (stacklimit != -1) BOOST_CHECK_MESSAGE((
int)*
node->GetStackSize() == stacklimit,
"Stack limit mismatch: " << ms <<
" (" << *
node->GetStackSize() <<
" vs " << stacklimit <<
")");
471 if (max_wit_size) BOOST_CHECK_MESSAGE(*
node->GetWitnessSize() == *max_wit_size,
"Witness size limit mismatch: " << ms <<
" (" << *
node->GetWitnessSize() <<
" vs " << *max_wit_size <<
")");
472 if (stack_exec) BOOST_CHECK_MESSAGE(*
node->GetExecStackSize() == *stack_exec,
"Stack execution limit mismatch: " << ms <<
" (" << *
node->GetExecStackSize() <<
" vs " << *stack_exec <<
")");
473 TestSatisfy(converter, ms,
node);
477 void Test(
const std::string& ms,
const std::string& hexscript,
const std::string& hextapscript,
int mode,
478 int opslimit,
int stacklimit, std::optional<uint32_t> max_wit_size,
479 std::optional<uint32_t> max_tap_wit_size,
480 std::optional<uint32_t> stack_exec)
483 Test(ms, hexscript, mode, wsh_converter, opslimit, stacklimit, max_wit_size, stack_exec);
485 Test(ms, hextapscript ==
"=" ? hexscript : hextapscript, mode, tap_converter, opslimit, stacklimit, max_tap_wit_size, stack_exec);
488 void Test(
const std::string& ms,
const std::string& hexscript,
const std::string& hextapscript,
int mode)
490 Test(ms, hexscript, hextapscript, mode,
492 std::nullopt, std::nullopt, std::nullopt);
501 g_testdata.reset(
new TestData());
504 Test(
"l:older(1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
505 Test(
"l:older(0)",
"?",
"?", TESTMODE_INVALID);
506 Test(
"l:older(2147483647)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
507 Test(
"l:older(2147483648)",
"?",
"?", TESTMODE_INVALID);
508 Test(
"u:after(1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
509 Test(
"u:after(0)",
"?",
"?", TESTMODE_INVALID);
510 Test(
"u:after(2147483647)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
511 Test(
"u:after(2147483648)",
"?",
"?", TESTMODE_INVALID);
512 Test(
"andor(0,1,1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
513 Test(
"andor(a:0,1,1)",
"?",
"?", TESTMODE_INVALID);
514 Test(
"andor(0,a:1,a:1)",
"?",
"?", TESTMODE_INVALID);
515 Test(
"andor(1,1,1)",
"?",
"?", TESTMODE_INVALID);
516 Test(
"andor(n:or_i(0,after(1)),1,1)",
"?",
"?", TESTMODE_VALID);
517 Test(
"andor(or_i(0,after(1)),1,1)",
"?",
"?", TESTMODE_INVALID);
518 Test(
"c:andor(0,pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
519 Test(
"t:andor(0,v:1,v:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
520 Test(
"and_v(v:1,1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
521 Test(
"t:and_v(v:1,v:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
522 Test(
"c:and_v(v:1,pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
523 Test(
"and_v(1,1)",
"?",
"?", TESTMODE_INVALID);
524 Test(
"and_v(pk_k(02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),1)",
"?",
"?", TESTMODE_INVALID);
525 Test(
"and_v(v:1,a:1)",
"?",
"?", TESTMODE_INVALID);
526 Test(
"and_b(1,a:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
527 Test(
"and_b(1,1)",
"?",
"?", TESTMODE_INVALID);
528 Test(
"and_b(v:1,a:1)",
"?",
"?", TESTMODE_INVALID);
529 Test(
"and_b(a:1,a:1)",
"?",
"?", TESTMODE_INVALID);
530 Test(
"and_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:1)",
"?",
"?", TESTMODE_INVALID);
531 Test(
"or_b(0,a:0)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
532 Test(
"or_b(1,a:0)",
"?",
"?", TESTMODE_INVALID);
533 Test(
"or_b(0,a:1)",
"?",
"?", TESTMODE_INVALID);
534 Test(
"or_b(0,0)",
"?",
"?", TESTMODE_INVALID);
535 Test(
"or_b(v:0,a:0)",
"?",
"?", TESTMODE_INVALID);
536 Test(
"or_b(a:0,a:0)",
"?",
"?", TESTMODE_INVALID);
537 Test(
"or_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:0)",
"?",
"?", TESTMODE_INVALID);
538 Test(
"t:or_c(0,v:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
539 Test(
"t:or_c(a:0,v:1)",
"?",
"?", TESTMODE_INVALID);
540 Test(
"t:or_c(1,v:1)",
"?",
"?", TESTMODE_INVALID);
541 Test(
"t:or_c(n:or_i(0,after(1)),v:1)",
"?",
"?", TESTMODE_VALID);
542 Test(
"t:or_c(or_i(0,after(1)),v:1)",
"?",
"?", TESTMODE_INVALID);
543 Test(
"t:or_c(0,1)",
"?",
"?", TESTMODE_INVALID);
544 Test(
"or_d(0,1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
545 Test(
"or_d(a:0,1)",
"?",
"?", TESTMODE_INVALID);
546 Test(
"or_d(1,1)",
"?",
"?", TESTMODE_INVALID);
547 Test(
"or_d(n:or_i(0,after(1)),1)",
"?",
"?", TESTMODE_VALID);
548 Test(
"or_d(or_i(0,after(1)),1)",
"?",
"?", TESTMODE_INVALID);
549 Test(
"or_d(0,v:1)",
"?",
"?", TESTMODE_INVALID);
550 Test(
"or_i(1,1)",
"?",
"?", TESTMODE_VALID);
551 Test(
"t:or_i(v:1,v:1)",
"?",
"?", TESTMODE_VALID);
552 Test(
"c:or_i(pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
553 Test(
"or_i(a:1,a:1)",
"?",
"?", TESTMODE_INVALID);
554 Test(
"or_b(l:after(100),al:after(1000000000))",
"?",
"?", TESTMODE_VALID);
555 Test(
"and_b(after(100),a:after(1000000000))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX);
556 Test(
"pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac",
"20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
557 Test(
"pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)",
"76a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac",
"76a914fd1690c37fa3b0f04395ddc9415b220ab1ccc59588ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
560 Test(
"lltvln:after(1231488000)",
"6300676300676300670400046749b1926869516868",
"=", TESTMODE_VALID | TESTMODE_NONMAL, 12, 3, 3, 3, 3);
561 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);
562 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);
563 Test(
"j:and_v(vdv:after(1567547623),older(2016))",
"829263766304e7e06e5db169686902e007b268",
"=", TESTMODE_VALID | TESTMODE_NONMAL, 11, 1, 2, 2, 2);
564 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);
565 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);
566 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);
567 Test(
"or_d(sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6),and_n(un:after(499999999),older(4194305)))",
"82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868",
"82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868", TESTMODE_VALID, 16, 1, 33, 33, 3);
568 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);
569 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);
570 Test(
"and_b(older(16),s:or_d(sha256(e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f),n:after(1567547623)))",
"60b27c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87736404e7e06e5db192689a",
"=", TESTMODE_VALID, 12, 1, 33, 33, 4);
571 Test(
"j:and_v(v:hash160(20195b5a3d650c17f0f29f91c33f8f6335193d07),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))",
"82926382012088a91420195b5a3d650c17f0f29f91c33f8f6335193d078882012088a82096de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c4787736460b26868",
"=", TESTMODE_VALID, 16, 2, 33 + 33, 33 + 33, 4);
572 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);
573 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);
574 Test(
"and_n(sha256(d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68),t:or_i(v:older(4252898),v:older(144)))",
"82012088a820d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68876400676303e2e440b26967029000b269685168",
"=", TESTMODE_VALID, 14, 2, 33 + 2, 33 + 2, 4);
575 Test(
"or_d(nd:and_v(v:older(4252898),v:older(4252898)),sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6))",
"766303e2e440b26903e2e440b2696892736482012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68768",
"=", TESTMODE_VALID, 15, 2, 1 + 33, 1 + 33, 3);
576 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);
577 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);
578 Test(
"and_v(andor(hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),v:hash256(939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735),v:older(50000)),after(499999999))",
"82012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b2587640350c300b2696782012088aa20939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735886804ff64cd1db1",
"=", TESTMODE_VALID, 14, 2, 33 + 33, 33 + 33, 4);
579 Test(
"andor(hash256(5f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040),j:and_v(v:hash160(3a2bff0da9d96868e66abc4427bea4691cf61ccd),older(4194305)),ripemd160(44d90e2d3714c8663b632fcf0f9d5f22192cc4c8))",
"82012088aa205f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040876482012088a61444d90e2d3714c8663b632fcf0f9d5f22192cc4c8876782926382012088a9143a2bff0da9d96868e66abc4427bea4691cf61ccd8803010040b26868",
"=", TESTMODE_VALID, 20, 2, 33 + 33, 33 + 33, 4);
580 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);
581 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);
582 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);
583 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);
584 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);
585 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);
586 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);
587 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);
588 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);
589 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);
590 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);
599 const auto no_pubkey{
ParseHex(
"ac519c")};
601 const auto incomplete_multi_a{
ParseHex(
"ba20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba519c")};
603 const auto incomplete_multi_a_2{
ParseHex(
"ac2079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba519c")};
606 Test(
"and_v(v:multi_a(2,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),after(1231488000))",
"?",
"20d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85aac205601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7ccba529d0400046749b1", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4, 2, {}, {}, 3);
608 std::string ms_str_multi_a{
"multi_a(1,"};
609 for (
size_t i = 0; i < 21; ++i) {
610 ms_str_multi_a +=
HexStr(g_testdata->pubkeys[i]);
611 if (i < 20) ms_str_multi_a +=
",";
613 ms_str_multi_a +=
")";
614 Test(ms_str_multi_a,
"?",
"2079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba20f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9ba20e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13ba202f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4ba20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ba205cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bcba202f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01ba20acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbeba20a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ba20774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cbba20d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85aba20f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8ba20499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4ba20d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080eba20e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0aba20defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34ba205601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7ccba202b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6cba204ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97ba20352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5ba519c", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 22, 21, {}, {}, 22);
616 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 for (
const auto pk_count: {99, 110, 200}) {
620 std::string ms_str_large;
621 for (
auto i = 0; i < pk_count - 1; ++i) {
622 ms_str_large +=
"and_b(pk(" +
HexStr(g_testdata->pubkeys[i]) +
"),a:";
624 ms_str_large +=
"pk(" +
HexStr(g_testdata->pubkeys[pk_count - 1]) +
")";
625 ms_str_large.insert(ms_str_large.end(), pk_count - 1,
')');
626 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 std::string ms_stack_limit;
631 for (
auto i = 0; i <
count; ++i) {
632 ms_stack_limit +=
"and_b(older(1),a:";
634 ms_stack_limit +=
"pk(" +
HexStr(g_testdata->pubkeys[0]) +
")";
635 ms_stack_limit.insert(ms_stack_limit.end(),
count,
')');
637 BOOST_CHECK(ms_stack_ok && ms_stack_ok->CheckStackSize());
638 Test(ms_stack_limit,
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4 *
count + 1, 1, {}, {}, 1 +
count + 1);
641 ms_stack_limit =
"and_b(older(1),a:" + ms_stack_limit +
")";
643 BOOST_CHECK(ms_stack_nok && !ms_stack_nok->CheckStackSize());
644 Test(ms_stack_limit,
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4 *
count + 1, 1, {}, {}, 1 +
count + 1);
648 std::vector<unsigned char> nonminpush =
ParseHex(
"0000210232780000feff00ffffffffffff21ff005f00ae21ae00000000060602060406564c2102320000060900fe00005f00ae21ae00100000060606060606000000000000000000000000000000000000000000000000000000000000000000");
649 const CScript nonminpush_script(nonminpush.begin(), nonminpush.end());
653 std::vector<unsigned char> nonminverify =
ParseHex(
"2103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ac6951");
654 const CScript nonminverify_script(nonminverify.begin(), nonminverify.end());
658 Test(
"thresh(2,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(100))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287",
"20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
660 Test(
"thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187",
"20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
662 Test(
"thresh(3,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187",
"=", TESTMODE_INVALID);
664 Test(
"thresh(0,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187",
"=", TESTMODE_INVALID);
666 const auto ms_multi =
miniscript::FromString(
"multi(1,03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", wsh_converter);
677 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);
678 BOOST_CHECK(ms_minimalif && !ms_minimalif->IsValid());
680 const auto ms_dup1 =
miniscript::FromString(
"and_v(v:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", wsh_converter);
682 BOOST_CHECK(!ms_dup1->IsSane() && !ms_dup1->CheckDuplicateKey());
684 const auto ms_dup2 =
miniscript::FromString(
"or_b(c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),ac:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", wsh_converter);
685 BOOST_CHECK(ms_dup2 && !ms_dup2->IsSane() && !ms_dup2->CheckDuplicateKey());
687 const auto ms_dup3 =
miniscript::FromString(
"or_i(and_b(pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556)),and_b(older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", wsh_converter);
688 BOOST_CHECK(ms_dup3 && !ms_dup3->IsSane() && !ms_dup3->CheckDuplicateKey());
690 const auto ms_dup4 =
miniscript::FromString(
"thresh(2,pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),a:and_b(dv:older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", wsh_converter);
691 BOOST_CHECK(ms_dup4 && !ms_dup4->IsSane() && !ms_dup4->CheckDuplicateKey());
693 const auto ms_nondup =
miniscript::FromString(
"pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", wsh_converter);
694 BOOST_CHECK(ms_nondup && ms_nondup->CheckDuplicateKey() && ms_nondup->IsSane());
700 const auto ms_ins =
miniscript::FromString(
"or_i(and_b(after(1),a:after(1000000000)),pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204))", wsh_converter);
701 BOOST_CHECK(ms_ins && ms_ins->IsValid() && !ms_ins->IsSane());
702 const auto insane_sub = ms_ins->FindInsaneSub();
703 BOOST_CHECK(insane_sub && *insane_sub->ToString(wsh_converter) ==
"and_b(after(1),a:after(1000000000))");
706 Test(
"after(100)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
707 Test(
"after(1000000000)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
708 Test(
"or_b(l:after(100),al:after(1000000000))",
"?",
"?", TESTMODE_VALID);
709 Test(
"and_b(after(100),a:after(1000000000))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX);
714 Test(
"thresh(2,ltv:after(1000000000),altv:after(100),a:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))",
"?",
"?", TESTMODE_VALID | TESTMODE_TIMELOCKMIX | TESTMODE_NONMAL);
716 Test(
"thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(1000000000),altv:after(100))",
"?",
"?", TESTMODE_VALID);
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
virtual bool CheckLockTime(const CScriptNum &nLockTime) const
virtual bool CheckSchnorrSignature(Span< const unsigned char > sig, Span< const unsigned char > pubkey, SigVersion sigversion, ScriptExecutionData &execdata, ScriptError *serror=nullptr) const
virtual bool CheckSequence(const CScriptNum &nSequence) const
virtual bool CheckECDSASignature(const std::vector< unsigned char > &scriptSig, const std::vector< unsigned char > &vchPubKey, const CScript &scriptCode, SigVersion sigversion) const
A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160).
void Finalize(Span< unsigned char > output)
CHash160 & Write(Span< const unsigned char > input)
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
CHash256 & Write(Span< const unsigned char > input)
void Finalize(Span< unsigned char > output)
An encapsulated private key.
bool SignSchnorr(const uint256 &hash, 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...
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized signature.
CPubKey GetPubKey() const
Compute the public key from a private key.
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
const unsigned char * end() const
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const unsigned char * begin() const
const unsigned char * data() const
A hasher class for RIPEMD-160.
CRIPEMD160 & Write(const unsigned char *data, size_t len)
void Finalize(unsigned char hash[OUTPUT_SIZE])
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Serialized script, used inside transaction inputs and outputs.
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
TaprootSpendData GetSpendData() const
Compute spending data (after Finalize()).
TaprootBuilder & Add(int depth, Span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
CPubKey GetEvenCorrespondingCPubKey() const
constexpr unsigned char * begin()
static uint32_t ReadLE32(const unsigned char *ptr)
BOOST_AUTO_TEST_SUITE_END()
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
BOOST_AUTO_TEST_CASE(fixed_tests)
std::shared_ptr< const Node< Key > > NodeRef
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
Fragment
The different node types in miniscript.
@ 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
Internal RIPEMD-160 implementation.
Internal SHA-256 implementation.
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
enum ScriptError_t ScriptError
size_t GetSerializeSize(const T &t)
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...
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
std::vector< std::vector< unsigned char > > stack
miniscript::Availability SatRIPEMD160(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
bool CheckAfter(uint32_t value) const
Time lock satisfactions.
const miniscript::MiniscriptContext m_script_ctx
The context of the script we are satisfying (either P2WSH or Tapscript).
miniscript::Availability SatSHA256(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Hash preimage satisfactions.
miniscript::Availability SatHASH256(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
Satisfier(const SigningProvider &provider LIFETIMEBOUND, SignatureData &sig_data LIFETIMEBOUND, const BaseSignatureCreator &creator LIFETIMEBOUND, const CScript &witscript LIFETIMEBOUND, miniscript::MiniscriptContext script_ctx)
miniscript::Availability SatHASH160(const std::vector< unsigned char > &hash, std::vector< unsigned char > &preimage) const
bool CheckOlder(uint32_t value) const
std::map< std::pair< std::vector< unsigned char >, int >, std::set< std::vector< unsigned char >, ShortestVectorFirstComparator > > scripts
Map from (script, leaf_version) to (sets of) control blocks.
A node in a miniscript expression.
FastRandomContext g_insecure_rand_ctx
This global and the helpers that use it are not thread-safe.
uint256 uint256S(const char *str)
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.