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: 2026-03-16 05:20:51 Functions: 100.0 % 15 15
Branches: 50.5 % 1906 962

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

Generated by: LCOV version 2.0-1