Bitcoin Core  24.99.0
P2P Digital Currency
script_segwit_tests.cpp
Go to the documentation of this file.
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>
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);
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);
30 }
31 
32 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_Size)
33 {
34  uint160 dummy;
35  CScript notp2wsh;
36  notp2wsh << OP_0 << ToByteVector(dummy);
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);
46 }
47 
48 BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Invalid_EmptyScript)
49 {
50  CScript notp2wsh;
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 
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:411
void clear()
Definition: script.h:554
bool IsPayToWitnessScriptHash() const
Definition: script.cpp:210
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
Definition: script.cpp:220
160-bit opaque blob.
Definition: uint256.h:108
256-bit opaque blob.
Definition: uint256.h:119
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
#define BOOST_CHECK(expr)
Definition: object.cpp:16
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:63
@ OP_PUSHDATA4
Definition: script.h:76
@ OP_1NEGATE
Definition: script.h:77
@ OP_16
Definition: script.h:95
@ OP_NOP
Definition: script.h:98
@ OP_1
Definition: script.h:79
@ OP_PUSHDATA1
Definition: script.h:74
@ OP_PUSHDATA2
Definition: script.h:75
@ OP_0
Definition: script.h:72
@ OP_5
Definition: script.h:84
BOOST_AUTO_TEST_CASE(IsPayToWitnessScriptHash_Valid)
Basic testing setup.
Definition: setup_common.h:83