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