/ src / test / script_segwit_tests.cpp
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()