script_segwit_tests.cpp
1 // Copyright (c) 2012-2021 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 <script/script.h> 6 #include <test/util/setup_common.h> 7 8 #include <boost/test/unit_test.hpp> 9 10 BOOST_FIXTURE_TEST_SUITE(script_segwit_tests, BasicTestingSetup) 11 12 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Valid) 13 { 14 uint256 dummy; 15 CScript p2wsh; 16 p2wsh << OP_0 << ToByteVector(dummy); 17 BOOST_CHECK(p2wsh.IsPayToWitnessScriptHash()); 18 19 std::vector<unsigned char> bytes = {OP_0, 32}; 20 bytes.insert(bytes.end(), 32, 0); 21 BOOST_CHECK(CScript(bytes.begin(), bytes.end()).IsPayToWitnessScriptHash()); 22 } 23 24 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_NotOp0) 25 { 26 uint256 dummy; 27 CScript notp2wsh; 28 notp2wsh << OP_1 << ToByteVector(dummy); 29 BOOST_CHECK(!notp2wsh.IsPayToWitnessScriptHash()); 30 } 31 32 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_Size) 33 { 34 uint160 dummy; 35 CScript notp2wsh; 36 notp2wsh << OP_0 << ToByteVector(dummy); 37 BOOST_CHECK(!notp2wsh.IsPayToWitnessScriptHash()); 38 } 39 40 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_Nop) 41 { 42 uint256 dummy; 43 CScript notp2wsh; 44 notp2wsh << OP_0 << OP_NOP << ToByteVector(dummy); 45 BOOST_CHECK(!notp2wsh.IsPayToWitnessScriptHash()); 46 } 47 48 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_EmptyScript) 49 { 50 CScript notp2wsh; 51 BOOST_CHECK(!notp2wsh.IsPayToWitnessScriptHash()); 52 } 53 54 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_Pushdata) 55 { 56 // A script is not P2WSH if OP_PUSHDATA is used to push the hash. 57 std::vector<unsigned char> bytes = {OP_0, OP_PUSHDATA1, 32}; 58 bytes.insert(bytes.end(), 32, 0); 59 BOOST_CHECK(!CScript(bytes.begin(), bytes.end()).IsPayToWitnessScriptHash()); 60 61 bytes = {OP_0, OP_PUSHDATA2, 32, 0}; 62 bytes.insert(bytes.end(), 32, 0); 63 BOOST_CHECK(!CScript(bytes.begin(), bytes.end()).IsPayToWitnessScriptHash()); 64 65 bytes = {OP_0, OP_PUSHDATA4, 32, 0, 0, 0}; 66 bytes.insert(bytes.end(), 32, 0); 67 BOOST_CHECK(!CScript(bytes.begin(), bytes.end()).IsPayToWitnessScriptHash()); 68 } 69 70 namespace { 71 72 bool IsExpectedWitnessProgram(const CScript& script, const int expectedVersion, const std::vector<unsigned char>& expectedProgram) 73 { 74 int actualVersion; 75 std::vector<unsigned char> actualProgram; 76 if (!script.IsWitnessProgram(actualVersion, actualProgram)) { 77 return false; 78 } 79 BOOST_CHECK_EQUAL(actualVersion, expectedVersion); 80 BOOST_CHECK(actualProgram == expectedProgram); 81 return true; 82 } 83 84 bool IsNoWitnessProgram(const CScript& script) 85 { 86 int dummyVersion; 87 std::vector<unsigned char> dummyProgram; 88 return !script.IsWitnessProgram(dummyVersion, dummyProgram); 89 } 90 91 } // anonymous namespace 92 93 BOOST_AUTO_TEST_CASE(IsWitnessProgram_Valid) 94 { 95 // Witness programs have a minimum data push of 2 bytes. 96 std::vector<unsigned char> program = {42, 18}; 97 CScript wit; 98 wit << OP_0 << program; 99 BOOST_CHECK(IsExpectedWitnessProgram(wit, 0, program)); 100 101 wit.clear(); 102 // Witness programs have a maximum data push of 40 bytes. 103 program.resize(40); 104 wit << OP_16 << program; 105 BOOST_CHECK(IsExpectedWitnessProgram(wit, 16, program)); 106 107 program.resize(32); 108 std::vector<unsigned char> bytes = {OP_5, static_cast<unsigned char>(program.size())}; 109 bytes.insert(bytes.end(), program.begin(), program.end()); 110 BOOST_CHECK(IsExpectedWitnessProgram(CScript(bytes.begin(), bytes.end()), 5, program)); 111 } 112 113 BOOST_AUTO_TEST_CASE(IsWitnessProgram_Invalid_Version) 114 { 115 std::vector<unsigned char> program(10); 116 CScript nowit; 117 nowit << OP_1NEGATE << program; 118 BOOST_CHECK(IsNoWitnessProgram(nowit)); 119 } 120 121 BOOST_AUTO_TEST_CASE(IsWitnessProgram_Invalid_Size) 122 { 123 std::vector<unsigned char> program(1); 124 CScript nowit; 125 nowit << OP_0 << program; 126 BOOST_CHECK(IsNoWitnessProgram(nowit)); 127 128 nowit.clear(); 129 program.resize(41); 130 nowit << OP_0 << program; 131 BOOST_CHECK(IsNoWitnessProgram(nowit)); 132 } 133 134 BOOST_AUTO_TEST_CASE(IsWitnessProgram_Invalid_Nop) 135 { 136 std::vector<unsigned char> program(10); 137 CScript nowit; 138 nowit << OP_0 << OP_NOP << program; 139 BOOST_CHECK(IsNoWitnessProgram(nowit)); 140 } 141 142 BOOST_AUTO_TEST_CASE(IsWitnessProgram_Invalid_EmptyScript) 143 { 144 CScript nowit; 145 BOOST_CHECK(IsNoWitnessProgram(nowit)); 146 } 147 148 BOOST_AUTO_TEST_CASE(IsWitnessProgram_Invalid_Pushdata) 149 { 150 // A script is no witness program if OP_PUSHDATA is used to push the hash. 151 std::vector<unsigned char> bytes = {OP_0, OP_PUSHDATA1, 32}; 152 bytes.insert(bytes.end(), 32, 0); 153 BOOST_CHECK(IsNoWitnessProgram(CScript(bytes.begin(), bytes.end()))); 154 155 bytes = {OP_0, OP_PUSHDATA2, 32, 0}; 156 bytes.insert(bytes.end(), 32, 0); 157 BOOST_CHECK(IsNoWitnessProgram(CScript(bytes.begin(), bytes.end()))); 158 159 bytes = {OP_0, OP_PUSHDATA4, 32, 0, 0, 0}; 160 bytes.insert(bytes.end(), 32, 0); 161 BOOST_CHECK(IsNoWitnessProgram(CScript(bytes.begin(), bytes.end()))); 162 } 163 164 BOOST_AUTO_TEST_SUITE_END()