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