LCOV - code coverage report
Current view: top level - src/test - script_standard_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 322 322
Test Date: 2024-08-28 04:44:32 Functions: 100.0 % 15 15
Branches: 50.5 % 1728 873

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

Generated by: LCOV version 2.0-1