script_standard_tests.cpp raw
1 // Copyright (c) 2017-2022 The Limenka developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <test/data/bip341_wallet_vectors.json.h>
6
7 #include <key.h>
8 #include <key_io.h>
9 #include <script/script.h>
10 #include <script/signingprovider.h>
11 #include <script/solver.h>
12 #include <test/util/setup_common.h>
13 #include <util/strencodings.h>
14
15 #include <boost/test/unit_test.hpp>
16
17 #include <univalue.h>
18
19 using namespace util::hex_literals;
20
21 BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)
22
23 BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)
24 {
25 CTxDestination dest;
26 BOOST_CHECK(!IsValidDestination(dest));
27 }
28
29 BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
30 {
31 CKey keys[3];
32 CPubKey pubkeys[3];
33 for (int i = 0; i < 3; i++) {
34 keys[i].MakeNewKey(true);
35 pubkeys[i] = keys[i].GetPubKey();
36 }
37
38 CScript s;
39 std::vector<std::vector<unsigned char> > solutions;
40
41 // TxoutType::PUBKEY
42 s.clear();
43 s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
44 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEY);
45 BOOST_CHECK_EQUAL(solutions.size(), 1U);
46 BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
47
48 // TxoutType::PUBKEYHASH
49 s.clear();
50 s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
51 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEYHASH);
52 BOOST_CHECK_EQUAL(solutions.size(), 1U);
53 BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
54
55 // TxoutType::SCRIPTHASH
56 CScript redeemScript(s); // initialize with leftover P2PKH script
57 s.clear();
58 s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
59 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::SCRIPTHASH);
60 BOOST_CHECK_EQUAL(solutions.size(), 1U);
61 BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
62
63 // TxoutType::MULTISIG
64 s.clear();
65 s << OP_1 <<
66 ToByteVector(pubkeys[0]) <<
67 ToByteVector(pubkeys[1]) <<
68 OP_2 << OP_CHECKMULTISIG;
69 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
70 BOOST_CHECK_EQUAL(solutions.size(), 4U);
71 BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
72 BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
73 BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
74 BOOST_CHECK(solutions[3] == std::vector<unsigned char>({2}));
75
76 s.clear();
77 s << OP_2 <<
78 ToByteVector(pubkeys[0]) <<
79 ToByteVector(pubkeys[1]) <<
80 ToByteVector(pubkeys[2]) <<
81 OP_3 << OP_CHECKMULTISIG;
82 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
83 BOOST_CHECK_EQUAL(solutions.size(), 5U);
84 BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
85 BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
86 BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
87 BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
88 BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
89
90 // TxoutType::NULL_DATA
91 s.clear();
92 s << OP_RETURN <<
93 std::vector<unsigned char>({0}) <<
94 std::vector<unsigned char>({75}) <<
95 std::vector<unsigned char>({255});
96 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NULL_DATA);
97 BOOST_CHECK_EQUAL(solutions.size(), 0U);
98
99 // TxoutType::WITNESS_V0_KEYHASH
100 s.clear();
101 s << OP_0 << ToByteVector(pubkeys[0].GetID());
102 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_KEYHASH);
103 BOOST_CHECK_EQUAL(solutions.size(), 1U);
104 BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
105
106 // TxoutType::WITNESS_V0_SCRIPTHASH
107 uint256 scriptHash;
108 CSHA256().Write(redeemScript.data(), redeemScript.size())
109 .Finalize(scriptHash.begin());
110
111 s.clear();
112 s << OP_0 << ToByteVector(scriptHash);
113 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_SCRIPTHASH);
114 BOOST_CHECK_EQUAL(solutions.size(), 1U);
115 BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
116
117 // TxoutType::WITNESS_V1_TAPROOT
118 s.clear();
119 s << OP_1 << ToByteVector(uint256::ZERO);
120 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V1_TAPROOT);
121 BOOST_CHECK_EQUAL(solutions.size(), 1U);
122 BOOST_CHECK(solutions[0] == ToByteVector(uint256::ZERO));
123
124 // TxoutType::WITNESS_UNKNOWN
125 s.clear();
126 s << OP_16 << ToByteVector(uint256::ONE);
127 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);
128 BOOST_CHECK_EQUAL(solutions.size(), 2U);
129 BOOST_CHECK(solutions[0] == std::vector<unsigned char>{16});
130 BOOST_CHECK(solutions[1] == ToByteVector(uint256::ONE));
131
132 // TxoutType::ANCHOR
133 std::vector<unsigned char> anchor_bytes{0x4e, 0x73};
134 s.clear();
135 s << OP_1 << anchor_bytes;
136 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::ANCHOR);
137 BOOST_CHECK(solutions.empty());
138
139 // Sanity-check IsPayToAnchor
140 int version{-1};
141 std::vector<unsigned char> witness_program;
142 BOOST_CHECK(s.IsPayToAnchor());
143 BOOST_CHECK(s.IsWitnessProgram(version, witness_program));
144 BOOST_CHECK(CScript::IsPayToAnchor(version, witness_program));
145
146 // TxoutType::NONSTANDARD
147 s.clear();
148 s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
149 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
150 }
151
152 BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
153 {
154 CKey key = GenerateRandomKey();
155 CPubKey pubkey = key.GetPubKey();
156
157 CScript s;
158 std::vector<std::vector<unsigned char> > solutions;
159
160 // TxoutType::PUBKEY with incorrectly sized pubkey
161 s.clear();
162 s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
163 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
164
165 // TxoutType::PUBKEYHASH with incorrectly sized key hash
166 s.clear();
167 s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
168 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
169
170 // TxoutType::SCRIPTHASH with incorrectly sized script hash
171 s.clear();
172 s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
173 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
174
175 // TxoutType::MULTISIG 0/2
176 s.clear();
177 s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
178 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
179
180 // TxoutType::MULTISIG 2/1
181 s.clear();
182 s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
183 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
184
185 // TxoutType::MULTISIG n = 2 with 1 pubkey
186 s.clear();
187 s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
188 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
189
190 // TxoutType::MULTISIG n = 1 with 0 pubkeys
191 s.clear();
192 s << OP_1 << OP_1 << OP_CHECKMULTISIG;
193 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
194
195 // TxoutType::NULL_DATA with other opcodes
196 s.clear();
197 s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
198 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
199
200 // TxoutType::WITNESS_UNKNOWN with incorrect program size
201 s.clear();
202 s << OP_0 << std::vector<unsigned char>(19, 0x01);
203 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
204
205 // TxoutType::ANCHOR but wrong witness version
206 s.clear();
207 s << OP_2 << std::vector<unsigned char>{0x4e, 0x73};
208 BOOST_CHECK(!s.IsPayToAnchor());
209 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);
210
211 // TxoutType::ANCHOR but wrong 2-byte data push
212 s.clear();
213 s << OP_1 << std::vector<unsigned char>{0xff, 0xff};
214 BOOST_CHECK(!s.IsPayToAnchor());
215 BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);
216 }
217
218 BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
219 {
220 CKey key = GenerateRandomKey();
221 CPubKey pubkey = key.GetPubKey();
222
223 CScript s;
224 CTxDestination address;
225
226 // TxoutType::PUBKEY
227 s.clear();
228 s << ToByteVector(pubkey) << OP_CHECKSIG;
229 BOOST_CHECK(!ExtractDestination(s, address));
230 BOOST_CHECK(std::get<PubKeyDestination>(address) == PubKeyDestination(pubkey));
231
232 // TxoutType::PUBKEYHASH
233 s.clear();
234 s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
235 BOOST_CHECK(ExtractDestination(s, address));
236 BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
237
238 // TxoutType::SCRIPTHASH
239 CScript redeemScript(s); // initialize with leftover P2PKH script
240 s.clear();
241 s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
242 BOOST_CHECK(ExtractDestination(s, address));
243 BOOST_CHECK(std::get<ScriptHash>(address) == ScriptHash(redeemScript));
244
245 // TxoutType::MULTISIG
246 s.clear();
247 s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
248 BOOST_CHECK(!ExtractDestination(s, address));
249
250 // TxoutType::NULL_DATA
251 s.clear();
252 s << OP_RETURN << std::vector<unsigned char>({75});
253 BOOST_CHECK(!ExtractDestination(s, address));
254
255 // TxoutType::WITNESS_V0_KEYHASH
256 s.clear();
257 s << OP_0 << ToByteVector(pubkey.GetID());
258 BOOST_CHECK(ExtractDestination(s, address));
259 WitnessV0KeyHash keyhash;
260 CHash160().Write(pubkey).Finalize(keyhash);
261 BOOST_CHECK(std::get<WitnessV0KeyHash>(address) == keyhash);
262
263 // TxoutType::WITNESS_V0_SCRIPTHASH
264 s.clear();
265 WitnessV0ScriptHash scripthash;
266 CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
267 s << OP_0 << ToByteVector(scripthash);
268 BOOST_CHECK(ExtractDestination(s, address));
269 BOOST_CHECK(std::get<WitnessV0ScriptHash>(address) == scripthash);
270
271 // TxoutType::WITNESS_UNKNOWN with unknown version
272 s.clear();
273 s << OP_1 << ToByteVector(pubkey);
274 BOOST_CHECK(ExtractDestination(s, address));
275 WitnessUnknown unk{1, ToByteVector(pubkey)};
276 BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
277 }
278
279 BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
280 {
281 CKey keys[3];
282 CPubKey pubkeys[3];
283 for (int i = 0; i < 3; i++) {
284 keys[i].MakeNewKey(true);
285 pubkeys[i] = keys[i].GetPubKey();
286 }
287
288 CScript expected, result;
289
290 // PKHash
291 expected.clear();
292 expected << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
293 result = GetScriptForDestination(PKHash(pubkeys[0]));
294 BOOST_CHECK(result == expected);
295
296 // CScriptID
297 CScript redeemScript(result);
298 expected.clear();
299 expected << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
300 result = GetScriptForDestination(ScriptHash(redeemScript));
301 BOOST_CHECK(result == expected);
302
303 // CNoDestination
304 expected.clear();
305 result = GetScriptForDestination(CNoDestination());
306 BOOST_CHECK(result == expected);
307
308 // GetScriptForRawPubKey
309 expected.clear();
310 expected << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
311 result = GetScriptForRawPubKey(pubkeys[0]);
312 BOOST_CHECK(result == expected);
313
314 // GetScriptForMultisig
315 expected.clear();
316 expected << OP_2 <<
317 ToByteVector(pubkeys[0]) <<
318 ToByteVector(pubkeys[1]) <<
319 ToByteVector(pubkeys[2]) <<
320 OP_3 << OP_CHECKMULTISIG;
321 result = GetScriptForMultisig(2, std::vector<CPubKey>(pubkeys, pubkeys + 3));
322 BOOST_CHECK(result == expected);
323
324 // WitnessV0KeyHash
325 expected.clear();
326 expected << OP_0 << ToByteVector(pubkeys[0].GetID());
327 result = GetScriptForDestination(WitnessV0KeyHash(Hash160(ToByteVector(pubkeys[0]))));
328 BOOST_CHECK(result == expected);
329 result = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0].GetID()));
330 BOOST_CHECK(result == expected);
331
332 // WitnessV0ScriptHash (multisig)
333 CScript witnessScript;
334 witnessScript << OP_1 << ToByteVector(pubkeys[0]) << OP_1 << OP_CHECKMULTISIG;
335
336 uint256 scriptHash;
337 CSHA256().Write(witnessScript.data(), witnessScript.size())
338 .Finalize(scriptHash.begin());
339
340 expected.clear();
341 expected << OP_0 << ToByteVector(scriptHash);
342 result = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
343 BOOST_CHECK(result == expected);
344 }
345
346 BOOST_AUTO_TEST_CASE(script_standard_taproot_builder)
347 {
348 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({}), true);
349 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0}), true);
350 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1}), false);
351 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2}), false);
352 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,0}), false);
353 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,1}), false);
354 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,2}), false);
355 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,0}), false);
356 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,1}), true);
357 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,2}), false);
358 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,0}), false);
359 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,1}), false);
360 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,2}), false);
361 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,0,0}), false);
362 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,0,1}), false);
363 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,0,2}), false);
364 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,1,0}), false);
365 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,1,1}), false);
366 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,1,2}), false);
367 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,2,0}), false);
368 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,2,1}), false);
369 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({0,2,2}), false);
370 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,0,0}), false);
371 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,0,1}), false);
372 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,0,2}), false);
373 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,1,0}), false);
374 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,1,1}), false);
375 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,1,2}), false);
376 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,2,0}), false);
377 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,2,1}), false);
378 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({1,2,2}), true);
379 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,0,0}), false);
380 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,0,1}), false);
381 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,0,2}), false);
382 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,1,0}), false);
383 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,1,1}), false);
384 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,1,2}), false);
385 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,2,0}), false);
386 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,2,1}), true);
387 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,2,2}), false);
388 // REDUCED_DATA limits Taproot tree depth to 7 instead of 128
389 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,2,2,3,4,5,6,7,7}), true);
390 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({7,7,6,5,4,3,2,1}), true);
391 BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({8,8,7,6,5,4,3,2,1}), false);
392
393 XOnlyPubKey key_inner{"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"_hex_u8};
394 XOnlyPubKey key_1{"c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"_hex_u8};
395 XOnlyPubKey key_2{"f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9"_hex_u8};
396 CScript script_1 = CScript() << ToByteVector(key_1) << OP_CHECKSIG;
397 CScript script_2 = CScript() << ToByteVector(key_2) << OP_CHECKSIG;
398 constexpr uint256 hash_3{"31fe7061656bea2a36aa60a2f7ef940578049273746935d296426dc0afd86b68"};
399
400 TaprootBuilder builder;
401 BOOST_CHECK(builder.IsValid() && builder.IsComplete());
402 builder.Add(2, script_2, 0xc0);
403 BOOST_CHECK(builder.IsValid() && !builder.IsComplete());
404 builder.AddOmitted(2, hash_3);
405 BOOST_CHECK(builder.IsValid() && !builder.IsComplete());
406 builder.Add(1, script_1, 0xc0);
407 BOOST_CHECK(builder.IsValid() && builder.IsComplete());
408 builder.Finalize(key_inner);
409 BOOST_CHECK(builder.IsValid() && builder.IsComplete());
410 BOOST_CHECK_EQUAL(EncodeDestination(builder.GetOutput()), "bc1pj6gaw944fy0xpmzzu45ugqde4rz7mqj5kj0tg8kmr5f0pjq8vnaqgynnge");
411 }
412
413 BOOST_AUTO_TEST_CASE(bip341_spk_test_vectors)
414 {
415 using control_set = decltype(TaprootSpendData::scripts)::mapped_type;
416
417 UniValue tests;
418 tests.read(json_tests::bip341_wallet_vectors);
419
420 const auto& vectors = tests["scriptPubKey"];
421
422 for (const auto& vec : vectors.getValues()) {
423 TaprootBuilder spktest;
424 std::map<std::pair<std::vector<unsigned char>, int>, int> scriptposes;
425 std::function<void (const UniValue&, int)> parse_tree = [&](const UniValue& node, int depth) {
426 if (node.isNull()) return;
427 if (node.isObject()) {
428 auto script = ParseHex(node["script"].get_str());
429 int idx = node["id"].getInt<int>();
430 int leaf_version = node["leafVersion"].getInt<int>();
431 scriptposes[{script, leaf_version}] = idx;
432 spktest.Add(depth, script, leaf_version);
433 } else {
434 parse_tree(node[0], depth + 1);
435 parse_tree(node[1], depth + 1);
436 }
437 };
438 parse_tree(vec["given"]["scriptTree"], 0);
439 spktest.Finalize(XOnlyPubKey(ParseHex(vec["given"]["internalPubkey"].get_str())));
440 BOOST_CHECK_EQUAL(HexStr(GetScriptForDestination(spktest.GetOutput())), vec["expected"]["scriptPubKey"].get_str());
441 BOOST_CHECK_EQUAL(EncodeDestination(spktest.GetOutput()), vec["expected"]["bip350Address"].get_str());
442 auto spend_data = spktest.GetSpendData();
443 BOOST_CHECK_EQUAL(vec["intermediary"]["merkleRoot"].isNull(), spend_data.merkle_root.IsNull());
444 if (!spend_data.merkle_root.IsNull()) {
445 BOOST_CHECK_EQUAL(vec["intermediary"]["merkleRoot"].get_str(), HexStr(spend_data.merkle_root));
446 }
447 BOOST_CHECK_EQUAL(spend_data.scripts.size(), scriptposes.size());
448 for (const auto& scriptpos : scriptposes) {
449 BOOST_CHECK(spend_data.scripts[scriptpos.first] == control_set{ParseHex(vec["expected"]["scriptPathControlBlocks"][scriptpos.second].get_str())});
450 }
451 }
452 }
453
454 BOOST_AUTO_TEST_SUITE_END()
455