scriptnum_tests.cpp
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/scriptnum10.h> 7 #include <test/util/setup_common.h> 8 9 #include <boost/test/unit_test.hpp> 10 #include <climits> 11 #include <cstdint> 12 13 BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup) 14 15 /** A selection of numbers that do not trigger int64_t overflow 16 * when added/subtracted. */ 17 static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 }; 18 19 static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; 20 21 static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum) 22 { 23 return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint(); 24 } 25 26 static void CheckCreateVch(const int64_t& num) 27 { 28 CScriptNum10 bignum(num); 29 CScriptNum scriptnum(num); 30 BOOST_CHECK(verify(bignum, scriptnum)); 31 32 CScriptNum10 bignum2(bignum.getvch(), false); 33 CScriptNum scriptnum2(scriptnum.getvch(), false); 34 BOOST_CHECK(verify(bignum2, scriptnum2)); 35 36 CScriptNum10 bignum3(scriptnum2.getvch(), false); 37 CScriptNum scriptnum3(bignum2.getvch(), false); 38 BOOST_CHECK(verify(bignum3, scriptnum3)); 39 } 40 41 static void CheckCreateInt(const int64_t& num) 42 { 43 CScriptNum10 bignum(num); 44 CScriptNum scriptnum(num); 45 BOOST_CHECK(verify(bignum, scriptnum)); 46 BOOST_CHECK(verify(CScriptNum10(bignum.getint()), CScriptNum(scriptnum.getint()))); 47 BOOST_CHECK(verify(CScriptNum10(scriptnum.getint()), CScriptNum(bignum.getint()))); 48 BOOST_CHECK(verify(CScriptNum10(CScriptNum10(scriptnum.getint()).getint()), CScriptNum(CScriptNum(bignum.getint()).getint()))); 49 } 50 51 52 static void CheckAdd(const int64_t& num1, const int64_t& num2) 53 { 54 const CScriptNum10 bignum1(num1); 55 const CScriptNum10 bignum2(num2); 56 const CScriptNum scriptnum1(num1); 57 const CScriptNum scriptnum2(num2); 58 CScriptNum10 bignum3(num1); 59 CScriptNum10 bignum4(num1); 60 CScriptNum scriptnum3(num1); 61 CScriptNum scriptnum4(num1); 62 63 // int64_t overflow is undefined. 64 bool invalid = (((num2 > 0) && (num1 > (std::numeric_limits<int64_t>::max() - num2))) || 65 ((num2 < 0) && (num1 < (std::numeric_limits<int64_t>::min() - num2)))); 66 if (!invalid) 67 { 68 BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + scriptnum2)); 69 BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + num2)); 70 BOOST_CHECK(verify(bignum1 + bignum2, scriptnum2 + num1)); 71 } 72 } 73 74 static void CheckNegate(const int64_t& num) 75 { 76 const CScriptNum10 bignum(num); 77 const CScriptNum scriptnum(num); 78 79 // -INT64_MIN is undefined 80 if (num != std::numeric_limits<int64_t>::min()) 81 BOOST_CHECK(verify(-bignum, -scriptnum)); 82 } 83 84 static void CheckSubtract(const int64_t& num1, const int64_t& num2) 85 { 86 const CScriptNum10 bignum1(num1); 87 const CScriptNum10 bignum2(num2); 88 const CScriptNum scriptnum1(num1); 89 const CScriptNum scriptnum2(num2); 90 91 // int64_t overflow is undefined. 92 bool invalid = ((num2 > 0 && num1 < std::numeric_limits<int64_t>::min() + num2) || 93 (num2 < 0 && num1 > std::numeric_limits<int64_t>::max() + num2)); 94 if (!invalid) 95 { 96 BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - scriptnum2)); 97 BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - num2)); 98 } 99 100 invalid = ((num1 > 0 && num2 < std::numeric_limits<int64_t>::min() + num1) || 101 (num1 < 0 && num2 > std::numeric_limits<int64_t>::max() + num1)); 102 if (!invalid) 103 { 104 BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - scriptnum1)); 105 BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - num1)); 106 } 107 } 108 109 static void CheckCompare(const int64_t& num1, const int64_t& num2) 110 { 111 const CScriptNum10 bignum1(num1); 112 const CScriptNum10 bignum2(num2); 113 const CScriptNum scriptnum1(num1); 114 const CScriptNum scriptnum2(num2); 115 116 BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == scriptnum1)); 117 BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != scriptnum1)); 118 BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < scriptnum1)); 119 BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > scriptnum1)); 120 BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= scriptnum1)); 121 BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= scriptnum1)); 122 123 BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == num1)); 124 BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != num1)); 125 BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < num1)); 126 BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > num1)); 127 BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= num1)); 128 BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= num1)); 129 130 BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == scriptnum2)); 131 BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != scriptnum2)); 132 BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < scriptnum2)); 133 BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > scriptnum2)); 134 BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= scriptnum2)); 135 BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= scriptnum2)); 136 137 BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == num2)); 138 BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != num2)); 139 BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < num2)); 140 BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > num2)); 141 BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= num2)); 142 BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= num2)); 143 } 144 145 static void RunCreate(const int64_t& num) 146 { 147 CheckCreateInt(num); 148 CScriptNum scriptnum(num); 149 if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize) 150 CheckCreateVch(num); 151 else 152 { 153 BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum10_error); 154 } 155 } 156 157 static void RunOperators(const int64_t& num1, const int64_t& num2) 158 { 159 CheckAdd(num1, num2); 160 CheckSubtract(num1, num2); 161 CheckNegate(num1); 162 CheckCompare(num1, num2); 163 } 164 165 BOOST_AUTO_TEST_CASE(creation) 166 { 167 for(size_t i = 0; i < std::size(values); ++i) 168 { 169 for(size_t j = 0; j < std::size(offsets); ++j) 170 { 171 RunCreate(values[i]); 172 RunCreate(values[i] + offsets[j]); 173 RunCreate(values[i] - offsets[j]); 174 } 175 } 176 } 177 178 BOOST_AUTO_TEST_CASE(operators) 179 { 180 for(size_t i = 0; i < std::size(values); ++i) 181 { 182 for(size_t j = 0; j < std::size(offsets); ++j) 183 { 184 RunOperators(values[i], values[i]); 185 RunOperators(values[i], -values[i]); 186 RunOperators(values[i], values[j]); 187 RunOperators(values[i], -values[j]); 188 RunOperators(values[i] + values[j], values[j]); 189 RunOperators(values[i] + values[j], -values[j]); 190 RunOperators(values[i] - values[j], values[j]); 191 RunOperators(values[i] - values[j], -values[j]); 192 RunOperators(values[i] + values[j], values[i] + values[j]); 193 RunOperators(values[i] + values[j], values[i] - values[j]); 194 RunOperators(values[i] - values[j], values[i] + values[j]); 195 RunOperators(values[i] - values[j], values[i] - values[j]); 196 } 197 } 198 } 199 200 BOOST_AUTO_TEST_SUITE_END()