LCOV - code coverage report
Current view: top level - src/test - script_standard_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 254 254 100.0 %
Date: 2020-09-26 01:30:44 Functions: 44 44 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2017-2019 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 <key.h>
       6             : #include <script/script.h>
       7             : #include <script/signingprovider.h>
       8             : #include <script/standard.h>
       9             : #include <test/util/setup_common.h>
      10             : 
      11             : #include <boost/test/unit_test.hpp>
      12             : 
      13             : 
      14          89 : BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)
      15             : 
      16          95 : BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)
      17             : {
      18           1 :     CTxDestination dest;
      19           1 :     BOOST_CHECK(!IsValidDestination(dest));
      20           1 : }
      21             : 
      22          95 : BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
      23             : {
      24           3 :     CKey keys[3];
      25           3 :     CPubKey pubkeys[3];
      26           4 :     for (int i = 0; i < 3; i++) {
      27           3 :         keys[i].MakeNewKey(true);
      28           3 :         pubkeys[i] = keys[i].GetPubKey();
      29             :     }
      30             : 
      31           1 :     CScript s;
      32           1 :     std::vector<std::vector<unsigned char> > solutions;
      33             : 
      34             :     // TxoutType::PUBKEY
      35           1 :     s.clear();
      36           1 :     s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
      37           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEY);
      38           1 :     BOOST_CHECK_EQUAL(solutions.size(), 1U);
      39           1 :     BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
      40             : 
      41             :     // TxoutType::PUBKEYHASH
      42           1 :     s.clear();
      43           1 :     s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
      44           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEYHASH);
      45           1 :     BOOST_CHECK_EQUAL(solutions.size(), 1U);
      46           1 :     BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
      47             : 
      48             :     // TxoutType::SCRIPTHASH
      49           1 :     CScript redeemScript(s); // initialize with leftover P2PKH script
      50           1 :     s.clear();
      51           1 :     s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
      52           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::SCRIPTHASH);
      53           1 :     BOOST_CHECK_EQUAL(solutions.size(), 1U);
      54           1 :     BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
      55             : 
      56             :     // TxoutType::MULTISIG
      57           1 :     s.clear();
      58           3 :     s << OP_1 <<
      59           2 :         ToByteVector(pubkeys[0]) <<
      60           2 :         ToByteVector(pubkeys[1]) <<
      61           1 :         OP_2 << OP_CHECKMULTISIG;
      62           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
      63           1 :     BOOST_CHECK_EQUAL(solutions.size(), 4U);
      64           1 :     BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
      65           1 :     BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
      66           1 :     BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
      67           1 :     BOOST_CHECK(solutions[3] == std::vector<unsigned char>({2}));
      68             : 
      69           1 :     s.clear();
      70           3 :     s << OP_2 <<
      71           2 :         ToByteVector(pubkeys[0]) <<
      72           2 :         ToByteVector(pubkeys[1]) <<
      73           2 :         ToByteVector(pubkeys[2]) <<
      74           1 :         OP_3 << OP_CHECKMULTISIG;
      75           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
      76           1 :     BOOST_CHECK_EQUAL(solutions.size(), 5U);
      77           1 :     BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
      78           1 :     BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
      79           1 :     BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
      80           1 :     BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
      81           1 :     BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
      82             : 
      83             :     // TxoutType::NULL_DATA
      84           1 :     s.clear();
      85           3 :     s << OP_RETURN <<
      86           2 :         std::vector<unsigned char>({0}) <<
      87           2 :         std::vector<unsigned char>({75}) <<
      88           1 :         std::vector<unsigned char>({255});
      89           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NULL_DATA);
      90           1 :     BOOST_CHECK_EQUAL(solutions.size(), 0U);
      91             : 
      92             :     // TxoutType::WITNESS_V0_KEYHASH
      93           1 :     s.clear();
      94           1 :     s << OP_0 << ToByteVector(pubkeys[0].GetID());
      95           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_KEYHASH);
      96           1 :     BOOST_CHECK_EQUAL(solutions.size(), 1U);
      97           1 :     BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
      98             : 
      99             :     // TxoutType::WITNESS_V0_SCRIPTHASH
     100           1 :     uint256 scriptHash;
     101           2 :     CSHA256().Write(&redeemScript[0], redeemScript.size())
     102           1 :         .Finalize(scriptHash.begin());
     103             : 
     104           1 :     s.clear();
     105           1 :     s << OP_0 << ToByteVector(scriptHash);
     106           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_SCRIPTHASH);
     107           1 :     BOOST_CHECK_EQUAL(solutions.size(), 1U);
     108           1 :     BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
     109             : 
     110             :     // TxoutType::NONSTANDARD
     111           1 :     s.clear();
     112           1 :     s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
     113           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     114           3 : }
     115             : 
     116          95 : BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
     117             : {
     118           1 :     CKey key;
     119           1 :     CPubKey pubkey;
     120           1 :     key.MakeNewKey(true);
     121           1 :     pubkey = key.GetPubKey();
     122             : 
     123           1 :     CScript s;
     124           1 :     std::vector<std::vector<unsigned char> > solutions;
     125             : 
     126             :     // TxoutType::PUBKEY with incorrectly sized pubkey
     127           1 :     s.clear();
     128           1 :     s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
     129           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     130             : 
     131             :     // TxoutType::PUBKEYHASH with incorrectly sized key hash
     132           1 :     s.clear();
     133           1 :     s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
     134           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     135             : 
     136             :     // TxoutType::SCRIPTHASH with incorrectly sized script hash
     137           1 :     s.clear();
     138           1 :     s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
     139           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     140             : 
     141             :     // TxoutType::MULTISIG 0/2
     142           1 :     s.clear();
     143           1 :     s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
     144           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     145             : 
     146             :     // TxoutType::MULTISIG 2/1
     147           1 :     s.clear();
     148           1 :     s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
     149           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     150             : 
     151             :     // TxoutType::MULTISIG n = 2 with 1 pubkey
     152           1 :     s.clear();
     153           1 :     s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
     154           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     155             : 
     156             :     // TxoutType::MULTISIG n = 1 with 0 pubkeys
     157           1 :     s.clear();
     158           1 :     s << OP_1 << OP_1 << OP_CHECKMULTISIG;
     159           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     160             : 
     161             :     // TxoutType::NULL_DATA with other opcodes
     162           1 :     s.clear();
     163           1 :     s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
     164           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     165             : 
     166             :     // TxoutType::WITNESS_UNKNOWN with incorrect program size
     167           1 :     s.clear();
     168           1 :     s << OP_0 << std::vector<unsigned char>(19, 0x01);
     169           1 :     BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
     170           1 : }
     171             : 
     172          95 : BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
     173             : {
     174           1 :     CKey key;
     175           1 :     CPubKey pubkey;
     176           1 :     key.MakeNewKey(true);
     177           1 :     pubkey = key.GetPubKey();
     178             : 
     179           1 :     CScript s;
     180           1 :     CTxDestination address;
     181             : 
     182             :     // TxoutType::PUBKEY
     183           1 :     s.clear();
     184           1 :     s << ToByteVector(pubkey) << OP_CHECKSIG;
     185           1 :     BOOST_CHECK(ExtractDestination(s, address));
     186           1 :     BOOST_CHECK(boost::get<PKHash>(&address) &&
     187             :                 *boost::get<PKHash>(&address) == PKHash(pubkey));
     188             : 
     189             :     // TxoutType::PUBKEYHASH
     190           1 :     s.clear();
     191           1 :     s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
     192           1 :     BOOST_CHECK(ExtractDestination(s, address));
     193           1 :     BOOST_CHECK(boost::get<PKHash>(&address) &&
     194             :                 *boost::get<PKHash>(&address) == PKHash(pubkey));
     195             : 
     196             :     // TxoutType::SCRIPTHASH
     197           1 :     CScript redeemScript(s); // initialize with leftover P2PKH script
     198           1 :     s.clear();
     199           1 :     s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
     200           1 :     BOOST_CHECK(ExtractDestination(s, address));
     201           1 :     BOOST_CHECK(boost::get<ScriptHash>(&address) &&
     202             :                 *boost::get<ScriptHash>(&address) == ScriptHash(redeemScript));
     203             : 
     204             :     // TxoutType::MULTISIG
     205           1 :     s.clear();
     206           1 :     s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
     207           1 :     BOOST_CHECK(!ExtractDestination(s, address));
     208             : 
     209             :     // TxoutType::NULL_DATA
     210           1 :     s.clear();
     211           1 :     s << OP_RETURN << std::vector<unsigned char>({75});
     212           1 :     BOOST_CHECK(!ExtractDestination(s, address));
     213             : 
     214             :     // TxoutType::WITNESS_V0_KEYHASH
     215           1 :     s.clear();
     216           1 :     s << OP_0 << ToByteVector(pubkey.GetID());
     217           1 :     BOOST_CHECK(ExtractDestination(s, address));
     218           1 :     WitnessV0KeyHash keyhash;
     219           1 :     CHash160().Write(pubkey).Finalize(keyhash);
     220           1 :     BOOST_CHECK(boost::get<WitnessV0KeyHash>(&address) && *boost::get<WitnessV0KeyHash>(&address) == keyhash);
     221             : 
     222             :     // TxoutType::WITNESS_V0_SCRIPTHASH
     223           1 :     s.clear();
     224           1 :     WitnessV0ScriptHash scripthash;
     225           1 :     CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
     226           1 :     s << OP_0 << ToByteVector(scripthash);
     227           1 :     BOOST_CHECK(ExtractDestination(s, address));
     228           1 :     BOOST_CHECK(boost::get<WitnessV0ScriptHash>(&address) && *boost::get<WitnessV0ScriptHash>(&address) == scripthash);
     229             : 
     230             :     // TxoutType::WITNESS_UNKNOWN with unknown version
     231           1 :     s.clear();
     232           1 :     s << OP_1 << ToByteVector(pubkey);
     233           1 :     BOOST_CHECK(ExtractDestination(s, address));
     234           1 :     WitnessUnknown unk;
     235           1 :     unk.length = 33;
     236           1 :     unk.version = 1;
     237           1 :     std::copy(pubkey.begin(), pubkey.end(), unk.program);
     238           1 :     BOOST_CHECK(boost::get<WitnessUnknown>(&address) && *boost::get<WitnessUnknown>(&address) == unk);
     239           1 : }
     240             : 
     241          95 : BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
     242             : {
     243           3 :     CKey keys[3];
     244           3 :     CPubKey pubkeys[3];
     245           4 :     for (int i = 0; i < 3; i++) {
     246           3 :         keys[i].MakeNewKey(true);
     247           3 :         pubkeys[i] = keys[i].GetPubKey();
     248             :     }
     249             : 
     250           1 :     CScript s;
     251           1 :     TxoutType whichType;
     252           1 :     std::vector<CTxDestination> addresses;
     253           1 :     int nRequired;
     254             : 
     255             :     // TxoutType::PUBKEY
     256           1 :     s.clear();
     257           1 :     s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
     258           1 :     BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
     259           1 :     BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEY);
     260           1 :     BOOST_CHECK_EQUAL(addresses.size(), 1U);
     261           1 :     BOOST_CHECK_EQUAL(nRequired, 1);
     262           1 :     BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
     263             :                 *boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
     264             : 
     265             :     // TxoutType::PUBKEYHASH
     266           1 :     s.clear();
     267           1 :     s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
     268           1 :     BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
     269           1 :     BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEYHASH);
     270           1 :     BOOST_CHECK_EQUAL(addresses.size(), 1U);
     271           1 :     BOOST_CHECK_EQUAL(nRequired, 1);
     272           1 :     BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
     273             :                 *boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
     274             : 
     275             :     // TxoutType::SCRIPTHASH
     276           1 :     CScript redeemScript(s); // initialize with leftover P2PKH script
     277           1 :     s.clear();
     278           1 :     s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
     279           1 :     BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
     280           1 :     BOOST_CHECK_EQUAL(whichType, TxoutType::SCRIPTHASH);
     281           1 :     BOOST_CHECK_EQUAL(addresses.size(), 1U);
     282           1 :     BOOST_CHECK_EQUAL(nRequired, 1);
     283           1 :     BOOST_CHECK(boost::get<ScriptHash>(&addresses[0]) &&
     284             :                 *boost::get<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript));
     285             : 
     286             :     // TxoutType::MULTISIG
     287           1 :     s.clear();
     288           3 :     s << OP_2 <<
     289           2 :         ToByteVector(pubkeys[0]) <<
     290           2 :         ToByteVector(pubkeys[1]) <<
     291           1 :         OP_2 << OP_CHECKMULTISIG;
     292           1 :     BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
     293           1 :     BOOST_CHECK_EQUAL(whichType, TxoutType::MULTISIG);
     294           1 :     BOOST_CHECK_EQUAL(addresses.size(), 2U);
     295           1 :     BOOST_CHECK_EQUAL(nRequired, 2);
     296           1 :     BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
     297             :                 *boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
     298           1 :     BOOST_CHECK(boost::get<PKHash>(&addresses[1]) &&
     299             :                 *boost::get<PKHash>(&addresses[1]) == PKHash(pubkeys[1]));
     300             : 
     301             :     // TxoutType::NULL_DATA
     302           1 :     s.clear();
     303           1 :     s << OP_RETURN << std::vector<unsigned char>({75});
     304           1 :     BOOST_CHECK(!ExtractDestinations(s, whichType, addresses, nRequired));
     305           3 : }
     306             : 
     307          95 : BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
     308             : {
     309           3 :     CKey keys[3];
     310           3 :     CPubKey pubkeys[3];
     311           4 :     for (int i = 0; i < 3; i++) {
     312           3 :         keys[i].MakeNewKey(true);
     313           3 :         pubkeys[i] = keys[i].GetPubKey();
     314             :     }
     315             : 
     316           1 :     CScript expected, result;
     317             : 
     318             :     // PKHash
     319           1 :     expected.clear();
     320           1 :     expected << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
     321           1 :     result = GetScriptForDestination(PKHash(pubkeys[0]));
     322           1 :     BOOST_CHECK(result == expected);
     323             : 
     324             :     // CScriptID
     325           1 :     CScript redeemScript(result);
     326           1 :     expected.clear();
     327           1 :     expected << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
     328           1 :     result = GetScriptForDestination(ScriptHash(redeemScript));
     329           1 :     BOOST_CHECK(result == expected);
     330             : 
     331             :     // CNoDestination
     332           1 :     expected.clear();
     333           1 :     result = GetScriptForDestination(CNoDestination());
     334           1 :     BOOST_CHECK(result == expected);
     335             : 
     336             :     // GetScriptForRawPubKey
     337           1 :     expected.clear();
     338           1 :     expected << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
     339           1 :     result = GetScriptForRawPubKey(pubkeys[0]);
     340           1 :     BOOST_CHECK(result == expected);
     341             : 
     342             :     // GetScriptForMultisig
     343           1 :     expected.clear();
     344           3 :     expected << OP_2 <<
     345           2 :         ToByteVector(pubkeys[0]) <<
     346           2 :         ToByteVector(pubkeys[1]) <<
     347           2 :         ToByteVector(pubkeys[2]) <<
     348           1 :         OP_3 << OP_CHECKMULTISIG;
     349           1 :     result = GetScriptForMultisig(2, std::vector<CPubKey>(pubkeys, pubkeys + 3));
     350           1 :     BOOST_CHECK(result == expected);
     351             : 
     352             :     // WitnessV0KeyHash
     353           1 :     expected.clear();
     354           1 :     expected << OP_0 << ToByteVector(pubkeys[0].GetID());
     355           1 :     result = GetScriptForDestination(WitnessV0KeyHash(Hash160(ToByteVector(pubkeys[0]))));
     356           1 :     BOOST_CHECK(result == expected);
     357           1 :     result = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0].GetID()));
     358           1 :     BOOST_CHECK(result == expected);
     359             : 
     360             :     // WitnessV0ScriptHash (multisig)
     361           1 :     CScript witnessScript;
     362           1 :     witnessScript << OP_1 << ToByteVector(pubkeys[0]) << OP_1 << OP_CHECKMULTISIG;
     363             : 
     364           1 :     uint256 scriptHash;
     365           2 :     CSHA256().Write(&witnessScript[0], witnessScript.size())
     366           1 :         .Finalize(scriptHash.begin());
     367             : 
     368           1 :     expected.clear();
     369           1 :     expected << OP_0 << ToByteVector(scriptHash);
     370           1 :     result = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
     371           1 :     BOOST_CHECK(result == expected);
     372           3 : }
     373             : 
     374          89 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.15