LCOV - code coverage report
Current view: top level - src/test - script_standard_tests.cpp (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 350 350
Test Date: 2025-04-28 05:00:59 Functions: 100.0 % 15 15
Branches: 50.5 % 1812 915

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

Generated by: LCOV version 2.0-1