script_segwit_tests.cpp raw
1 // Copyright (c) 2012-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <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()
165