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 % 322 322
Test Date: 2024-11-04 05:10:19 Functions: 100.0 % 15 15
Branches: 50.5 % 1716 867

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

Generated by: LCOV version 2.0-1