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