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());
293 using miniscript::operator
"" _mst;
298 std::set<Challenge> FindChallenges(
const NodeRef& ref) {
299 std::set<Challenge> chal;
300 for (
const auto& key : ref->keys) {
301 chal.emplace(ChallengeType::PK, ChallengeNumber(key));
304 chal.emplace(ChallengeType::OLDER, ref->k);
306 chal.emplace(ChallengeType::AFTER, ref->k);
308 chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data));
312 chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data));
314 chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data));
316 for (
const auto& sub : ref->subs) {
317 auto sub_chal = FindChallenges(sub);
318 chal.insert(sub_chal.begin(), sub_chal.end());
344 void TestSatisfy(
const KeyConverter& converter,
const std::string& testcase,
const NodeRef&
node) {
345 auto script =
node->ToScript(converter);
346 auto challenges = FindChallenges(
node);
347 std::vector<Challenge> challist(challenges.begin(), challenges.end());
348 for (
int iter = 0; iter < 3; ++iter) {
350 Satisfier satisfier(converter.MsContext());
351 TestSignatureChecker checker(satisfier);
352 bool prev_mal_success =
false, prev_nonmal_success =
false;
354 for (
int add = -1; add < (int)challist.size(); ++add) {
355 if (add >= 0) satisfier.supported.insert(challist[add]);
359 const CScript script_pubkey{ScriptPubKey(converter.MsContext(), script, builder)};
364 SatisfactionToWitness(converter.MsContext(), witness_mal, script, builder);
371 SatisfactionToWitness(converter.MsContext(), witness_nonmal, script, builder);
373 if (nonmal_success) {
382 assert(wit_size <= *node->GetWitnessSize());
396 if (mal_success && (!nonmal_success || witness_mal.
stack != witness_nonmal.
stack)) {
405 if (
node->IsSane()) {
415 if (
node->IsSane() || add < 0 || challist[add].first == ChallengeType::PK) {
416 BOOST_CHECK(nonmal_success >= prev_nonmal_success);
419 prev_mal_success = mal_success;
420 prev_nonmal_success = nonmal_success;
423 bool satisfiable =
node->IsSatisfiable([](
const Node&) {
return true; });
431 enum TestMode :
int {
433 TESTMODE_INVALID = 0,
437 TESTMODE_NEEDSIG = 4,
438 TESTMODE_TIMELOCKMIX = 8,
440 TESTMODE_P2WSH_INVALID = 16,
442 TESTMODE_TAPSCRIPT_INVALID = 32,
445 void Test(
const std::string& ms,
const std::string& hexscript,
int mode,
const KeyConverter& converter,
446 int opslimit = -1,
int stacklimit = -1, std::optional<uint32_t> max_wit_size = std::nullopt,
447 std::optional<uint32_t> stack_exec = {})
451 if (mode == TESTMODE_INVALID || ((mode & TESTMODE_P2WSH_INVALID) && !is_tapscript) || ((mode & TESTMODE_TAPSCRIPT_INVALID) && is_tapscript)) {
452 BOOST_CHECK_MESSAGE(!
node || !
node->IsValid(),
"Unexpectedly valid: " + ms);
454 BOOST_CHECK_MESSAGE(
node,
"Unparseable: " + ms);
455 BOOST_CHECK_MESSAGE(
node->IsValid(),
"Invalid: " + ms);
456 BOOST_CHECK_MESSAGE(
node->IsValidTopLevel(),
"Invalid top level: " + ms);
457 auto computed_script =
node->ToScript(converter);
458 BOOST_CHECK_MESSAGE(
node->ScriptSize() == computed_script.size(),
"Script size mismatch: " + ms);
459 if (hexscript !=
"?") BOOST_CHECK_MESSAGE(
HexStr(computed_script) == hexscript,
"Script mismatch: " + ms +
" (" +
HexStr(computed_script) +
" vs " + hexscript +
")");
460 BOOST_CHECK_MESSAGE(
node->IsNonMalleable() == !!(mode & TESTMODE_NONMAL),
"Malleability mismatch: " + ms);
461 BOOST_CHECK_MESSAGE(
node->NeedsSignature() == !!(mode & TESTMODE_NEEDSIG),
"Signature necessity mismatch: " + ms);
462 BOOST_CHECK_MESSAGE((
node->GetType() <<
"k"_mst) == !(mode & TESTMODE_TIMELOCKMIX),
"Timelock mix mismatch: " + ms);
464 BOOST_CHECK_MESSAGE(inferred_miniscript,
"Cannot infer miniscript from script: " + ms);
465 BOOST_CHECK_MESSAGE(inferred_miniscript->ToScript(converter) == computed_script,
"Roundtrip failure: miniscript->script != miniscript->script->miniscript->script: " + ms);
466 if (opslimit != -1) BOOST_CHECK_MESSAGE((
int)*
node->GetOps() == opslimit,
"Ops limit mismatch: " << ms <<
" (" << *
node->GetOps() <<
" vs " << opslimit <<
")");
467 if (stacklimit != -1) BOOST_CHECK_MESSAGE((
int)*
node->GetStackSize() == stacklimit,
"Stack limit mismatch: " << ms <<
" (" << *
node->GetStackSize() <<
" vs " << stacklimit <<
")");
468 if (max_wit_size) BOOST_CHECK_MESSAGE(*
node->GetWitnessSize() == *max_wit_size,
"Witness size limit mismatch: " << ms <<
" (" << *
node->GetWitnessSize() <<
" vs " << *max_wit_size <<
")");
469 if (stack_exec) BOOST_CHECK_MESSAGE(*
node->GetExecStackSize() == *stack_exec,
"Stack execution limit mismatch: " << ms <<
" (" << *
node->GetExecStackSize() <<
" vs " << *stack_exec <<
")");
470 TestSatisfy(converter, ms,
node);
474 void Test(
const std::string& ms,
const std::string& hexscript,
const std::string& hextapscript,
int mode,
475 int opslimit,
int stacklimit, std::optional<uint32_t> max_wit_size,
476 std::optional<uint32_t> max_tap_wit_size,
477 std::optional<uint32_t> stack_exec)
480 Test(ms, hexscript, mode, wsh_converter, opslimit, stacklimit, max_wit_size, stack_exec);
482 Test(ms, hextapscript ==
"=" ? hexscript : hextapscript, mode, tap_converter, opslimit, stacklimit, max_tap_wit_size, stack_exec);
485 void Test(
const std::string& ms,
const std::string& hexscript,
const std::string& hextapscript,
int mode)
487 Test(ms, hexscript, hextapscript, mode,
489 std::nullopt, std::nullopt, std::nullopt);
498 g_testdata.reset(
new TestData());
501 Test(
"l:older(1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
502 Test(
"l:older(0)",
"?",
"?", TESTMODE_INVALID);
503 Test(
"l:older(2147483647)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
504 Test(
"l:older(2147483648)",
"?",
"?", TESTMODE_INVALID);
505 Test(
"u:after(1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
506 Test(
"u:after(0)",
"?",
"?", TESTMODE_INVALID);
507 Test(
"u:after(2147483647)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
508 Test(
"u:after(2147483648)",
"?",
"?", TESTMODE_INVALID);
509 Test(
"andor(0,1,1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
510 Test(
"andor(a:0,1,1)",
"?",
"?", TESTMODE_INVALID);
511 Test(
"andor(0,a:1,a:1)",
"?",
"?", TESTMODE_INVALID);
512 Test(
"andor(1,1,1)",
"?",
"?", TESTMODE_INVALID);
513 Test(
"andor(n:or_i(0,after(1)),1,1)",
"?",
"?", TESTMODE_VALID);
514 Test(
"andor(or_i(0,after(1)),1,1)",
"?",
"?", TESTMODE_INVALID);
515 Test(
"c:andor(0,pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
516 Test(
"t:andor(0,v:1,v:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
517 Test(
"and_v(v:1,1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
518 Test(
"t:and_v(v:1,v:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
519 Test(
"c:and_v(v:1,pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
520 Test(
"and_v(1,1)",
"?",
"?", TESTMODE_INVALID);
521 Test(
"and_v(pk_k(02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),1)",
"?",
"?", TESTMODE_INVALID);
522 Test(
"and_v(v:1,a:1)",
"?",
"?", TESTMODE_INVALID);
523 Test(
"and_b(1,a:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
524 Test(
"and_b(1,1)",
"?",
"?", TESTMODE_INVALID);
525 Test(
"and_b(v:1,a:1)",
"?",
"?", TESTMODE_INVALID);
526 Test(
"and_b(a:1,a:1)",
"?",
"?", TESTMODE_INVALID);
527 Test(
"and_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:1)",
"?",
"?", TESTMODE_INVALID);
528 Test(
"or_b(0,a:0)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
529 Test(
"or_b(1,a:0)",
"?",
"?", TESTMODE_INVALID);
530 Test(
"or_b(0,a:1)",
"?",
"?", TESTMODE_INVALID);
531 Test(
"or_b(0,0)",
"?",
"?", TESTMODE_INVALID);
532 Test(
"or_b(v:0,a:0)",
"?",
"?", TESTMODE_INVALID);
533 Test(
"or_b(a:0,a:0)",
"?",
"?", TESTMODE_INVALID);
534 Test(
"or_b(pk_k(025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),a:0)",
"?",
"?", TESTMODE_INVALID);
535 Test(
"t:or_c(0,v:1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
536 Test(
"t:or_c(a:0,v:1)",
"?",
"?", TESTMODE_INVALID);
537 Test(
"t:or_c(1,v:1)",
"?",
"?", TESTMODE_INVALID);
538 Test(
"t:or_c(n:or_i(0,after(1)),v:1)",
"?",
"?", TESTMODE_VALID);
539 Test(
"t:or_c(or_i(0,after(1)),v:1)",
"?",
"?", TESTMODE_INVALID);
540 Test(
"t:or_c(0,1)",
"?",
"?", TESTMODE_INVALID);
541 Test(
"or_d(0,1)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
542 Test(
"or_d(a:0,1)",
"?",
"?", TESTMODE_INVALID);
543 Test(
"or_d(1,1)",
"?",
"?", TESTMODE_INVALID);
544 Test(
"or_d(n:or_i(0,after(1)),1)",
"?",
"?", TESTMODE_VALID);
545 Test(
"or_d(or_i(0,after(1)),1)",
"?",
"?", TESTMODE_INVALID);
546 Test(
"or_d(0,v:1)",
"?",
"?", TESTMODE_INVALID);
547 Test(
"or_i(1,1)",
"?",
"?", TESTMODE_VALID);
548 Test(
"t:or_i(v:1,v:1)",
"?",
"?", TESTMODE_VALID);
549 Test(
"c:or_i(pk_k(03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7),pk_k(036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
550 Test(
"or_i(a:1,a:1)",
"?",
"?", TESTMODE_INVALID);
551 Test(
"or_b(l:after(100),al:after(1000000000))",
"?",
"?", TESTMODE_VALID);
552 Test(
"and_b(after(100),a:after(1000000000))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX);
553 Test(
"pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac",
"20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
554 Test(
"pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)",
"76a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac",
"76a914fd1690c37fa3b0f04395ddc9415b220ab1ccc59588ac", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG);
557 Test(
"lltvln:after(1231488000)",
"6300676300676300670400046749b1926869516868",
"=", TESTMODE_VALID | TESTMODE_NONMAL, 12, 3, 3, 3, 3);
558 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);
559 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);
560 Test(
"j:and_v(vdv:after(1567547623),older(2016))",
"829263766304e7e06e5db169686902e007b268",
"=", TESTMODE_VALID | TESTMODE_NONMAL, 11, 1, 2, 2, 2);
561 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);
562 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);
563 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);
564 Test(
"or_d(sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6),and_n(un:after(499999999),older(4194305)))",
"82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868",
"82012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68773646304ff64cd1db19267006864006703010040b26868", TESTMODE_VALID, 16, 1, 33, 33, 3);
565 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);
566 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);
567 Test(
"and_b(older(16),s:or_d(sha256(e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f),n:after(1567547623)))",
"60b27c82012088a820e38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f87736404e7e06e5db192689a",
"=", TESTMODE_VALID, 12, 1, 33, 33, 4);
568 Test(
"j:and_v(v:hash160(20195b5a3d650c17f0f29f91c33f8f6335193d07),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))",
"82926382012088a91420195b5a3d650c17f0f29f91c33f8f6335193d078882012088a82096de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c4787736460b26868",
"=", TESTMODE_VALID, 16, 2, 33 + 33, 33 + 33, 4);
569 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);
570 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);
571 Test(
"and_n(sha256(d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68),t:or_i(v:older(4252898),v:older(144)))",
"82012088a820d1ec675902ef1633427ca360b290b0b3045a0d9058ddb5e648b4c3c3224c5c68876400676303e2e440b26967029000b269685168",
"=", TESTMODE_VALID, 14, 2, 33 + 2, 33 + 2, 4);
572 Test(
"or_d(nd:and_v(v:older(4252898),v:older(4252898)),sha256(38df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b6))",
"766303e2e440b26903e2e440b2696892736482012088a82038df1c1f64a24a77b23393bca50dff872e31edc4f3b5aa3b90ad0b82f4f089b68768",
"=", TESTMODE_VALID, 15, 2, 1 + 33, 1 + 33, 3);
573 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);
574 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);
575 Test(
"and_v(andor(hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),v:hash256(939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735),v:older(50000)),after(499999999))",
"82012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b2587640350c300b2696782012088aa20939894f70e6c3a25da75da0cc2071b4076d9b006563cf635986ada2e93c0d735886804ff64cd1db1",
"=", TESTMODE_VALID, 14, 2, 33 + 33, 33 + 33, 4);
576 Test(
"andor(hash256(5f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040),j:and_v(v:hash160(3a2bff0da9d96868e66abc4427bea4691cf61ccd),older(4194305)),ripemd160(44d90e2d3714c8663b632fcf0f9d5f22192cc4c8))",
"82012088aa205f8d30e655a7ba0d7596bb3ddfb1d2d20390d23b1845000e1e118b3be1b3f040876482012088a61444d90e2d3714c8663b632fcf0f9d5f22192cc4c8876782926382012088a9143a2bff0da9d96868e66abc4427bea4691cf61ccd8803010040b26868",
"=", TESTMODE_VALID, 20, 2, 33 + 33, 33 + 33, 4);
577 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);
578 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);
579 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);
580 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);
581 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);
582 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);
583 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);
584 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);
585 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);
586 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);
587 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);
596 const auto no_pubkey{
ParseHex(
"ac519c")};
598 const auto incomplete_multi_a{
ParseHex(
"ba20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba519c")};
600 const auto incomplete_multi_a_2{
ParseHex(
"ac2079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba519c")};
603 Test(
"and_v(v:multi_a(2,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),after(1231488000))",
"?",
"20d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85aac205601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7ccba529d0400046749b1", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4, 2, {}, {}, 3);
605 std::string ms_str_multi_a{
"multi_a(1,"};
606 for (
size_t i = 0; i < 21; ++i) {
607 ms_str_multi_a +=
HexStr(g_testdata->pubkeys[i]);
608 if (i < 20) ms_str_multi_a +=
",";
610 ms_str_multi_a +=
")";
611 Test(ms_str_multi_a,
"?",
"2079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac20c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5ba20f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9ba20e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13ba202f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4ba20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ba205cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bcba202f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01ba20acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbeba20a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ba20774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cbba20d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85aba20f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8ba20499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4ba20d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080eba20e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0aba20defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34ba205601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7ccba202b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6cba204ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97ba20352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5ba519c", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 22, 21, {}, {}, 22);
613 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);
616 for (
const auto pk_count: {99, 110, 200}) {
617 std::string ms_str_large;
618 for (
auto i = 0; i < pk_count - 1; ++i) {
619 ms_str_large +=
"and_b(pk(" +
HexStr(g_testdata->pubkeys[i]) +
"),a:";
621 ms_str_large +=
"pk(" +
HexStr(g_testdata->pubkeys[pk_count - 1]) +
")";
622 ms_str_large.insert(ms_str_large.end(), pk_count - 1,
')');
623 Test(ms_str_large,
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, pk_count + (pk_count - 1) * 3, pk_count, {}, {}, pk_count + 1);
626 std::string ms_stack_limit;
628 for (
auto i = 0; i <
count; ++i) {
629 ms_stack_limit +=
"and_b(older(1),a:";
631 ms_stack_limit +=
"pk(" +
HexStr(g_testdata->pubkeys[0]) +
")";
632 ms_stack_limit.insert(ms_stack_limit.end(),
count,
')');
634 BOOST_CHECK(ms_stack_ok && ms_stack_ok->CheckStackSize());
635 Test(ms_stack_limit,
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4 *
count + 1, 1, {}, {}, 1 +
count + 1);
638 ms_stack_limit =
"and_b(older(1),a:" + ms_stack_limit +
")";
640 BOOST_CHECK(ms_stack_nok && !ms_stack_nok->CheckStackSize());
641 Test(ms_stack_limit,
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_NEEDSIG | TESTMODE_P2WSH_INVALID, 4 *
count + 1, 1, {}, {}, 1 +
count + 1);
645 std::vector<unsigned char> nonminpush =
ParseHex(
"0000210232780000feff00ffffffffffff21ff005f00ae21ae00000000060602060406564c2102320000060900fe00005f00ae21ae00100000060606060606000000000000000000000000000000000000000000000000000000000000000000");
646 const CScript nonminpush_script(nonminpush.begin(), nonminpush.end());
650 std::vector<unsigned char> nonminverify =
ParseHex(
"2103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ac6951");
651 const CScript nonminverify_script(nonminverify.begin(), nonminverify.end());
655 Test(
"thresh(2,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),altv:after(100))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287",
"20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac6b6300670164b16951686c935287", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
657 Test(
"thresh(1,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187",
"20d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c20fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187", TESTMODE_VALID | TESTMODE_NEEDSIG | TESTMODE_NONMAL);
659 Test(
"thresh(3,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187",
"=", TESTMODE_INVALID);
661 Test(
"thresh(0,c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),sc:pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
"2103d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65ac7c2103fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556ac935187",
"=", TESTMODE_INVALID);
663 const auto ms_multi =
miniscript::FromString(
"multi(1,03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", wsh_converter);
674 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);
675 BOOST_CHECK(ms_minimalif && !ms_minimalif->IsValid());
677 const auto ms_dup1 =
miniscript::FromString(
"and_v(v:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", wsh_converter);
679 BOOST_CHECK(!ms_dup1->IsSane() && !ms_dup1->CheckDuplicateKey());
681 const auto ms_dup2 =
miniscript::FromString(
"or_b(c:pk_k(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),ac:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))", wsh_converter);
682 BOOST_CHECK(ms_dup2 && !ms_dup2->IsSane() && !ms_dup2->CheckDuplicateKey());
684 const auto ms_dup3 =
miniscript::FromString(
"or_i(and_b(pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556)),and_b(older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", wsh_converter);
685 BOOST_CHECK(ms_dup3 && !ms_dup3->IsSane() && !ms_dup3->CheckDuplicateKey());
687 const auto ms_dup4 =
miniscript::FromString(
"thresh(2,pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),a:and_b(dv:older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", wsh_converter);
688 BOOST_CHECK(ms_dup4 && !ms_dup4->IsSane() && !ms_dup4->CheckDuplicateKey());
690 const auto ms_nondup =
miniscript::FromString(
"pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", wsh_converter);
691 BOOST_CHECK(ms_nondup && ms_nondup->CheckDuplicateKey() && ms_nondup->IsSane());
697 const auto ms_ins =
miniscript::FromString(
"or_i(and_b(after(1),a:after(1000000000)),pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204))", wsh_converter);
698 BOOST_CHECK(ms_ins && ms_ins->IsValid() && !ms_ins->IsSane());
699 const auto insane_sub = ms_ins->FindInsaneSub();
700 BOOST_CHECK(insane_sub && *insane_sub->ToString(wsh_converter) ==
"and_b(after(1),a:after(1000000000))");
703 Test(
"after(100)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
704 Test(
"after(1000000000)",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL);
705 Test(
"or_b(l:after(100),al:after(1000000000))",
"?",
"?", TESTMODE_VALID);
706 Test(
"and_b(after(100),a:after(1000000000))",
"?",
"?", TESTMODE_VALID | TESTMODE_NONMAL | TESTMODE_TIMELOCKMIX);
711 Test(
"thresh(2,ltv:after(1000000000),altv:after(100),a:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65))",
"?",
"?", TESTMODE_VALID | TESTMODE_TIMELOCKMIX | TESTMODE_NONMAL);
713 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
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...
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.