diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/Makefile.am | 1 | ||||
-rw-r--r-- | src/test/data/script_invalid.json | 3 | ||||
-rw-r--r-- | src/test/data/script_valid.json | 13 | ||||
-rw-r--r-- | src/test/scriptnum_tests.cpp | 196 |
4 files changed, 213 insertions, 0 deletions
diff --git a/src/test/Makefile.am b/src/test/Makefile.am index b375ba1306..e12f4904f1 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -61,6 +61,7 @@ test_bitcoin_SOURCES = \ transaction_tests.cpp \ uint256_tests.cpp \ util_tests.cpp \ + scriptnum_tests.cpp \ sighash_tests.cpp \ $(JSON_TEST_FILES) $(RAW_TEST_FILES) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 8cb365a46f..fdceb1ffa9 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -257,7 +257,10 @@ ["1","0xba", "0xba == OP_NOP10 + 1"], ["2147483648", "1ADD 1", "We cannot do math on 5-byte integers"], +["2147483648", "NEGATE 1", "We cannot do math on 5-byte integers"], ["-2147483648", "1ADD 1", "Because we use a sign bit, -2147483648 is also 5 bytes"], +["2147483647", "1ADD 1SUB 1", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], +["2147483648", "1SUB 1", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], ["1", "1 ENDIF", "ENDIF without IF"], ["1", "IF 1", "IF without ENDIF"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 3b4c191865..67b985e355 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -97,6 +97,9 @@ ["8388608", "SIZE 4 EQUAL"], ["2147483647", "SIZE 4 EQUAL"], ["2147483648", "SIZE 5 EQUAL"], +["549755813887", "SIZE 5 EQUAL"], +["549755813888", "SIZE 6 EQUAL"], +["9223372036854775807", "SIZE 8 EQUAL"], ["-1", "SIZE 1 EQUAL"], ["-127", "SIZE 1 EQUAL"], ["-128", "SIZE 2 EQUAL"], @@ -106,6 +109,9 @@ ["-8388608", "SIZE 4 EQUAL"], ["-2147483647", "SIZE 4 EQUAL"], ["-2147483648", "SIZE 5 EQUAL"], +["-549755813887", "SIZE 5 EQUAL"], +["-549755813888", "SIZE 6 EQUAL"], +["-9223372036854775807", "SIZE 8 EQUAL"], ["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL"], @@ -306,6 +312,9 @@ ["8388608", "0x04 0x00008000 EQUAL"], ["2147483647", "0x04 0xFFFFFF7F EQUAL"], ["2147483648", "0x05 0x0000008000 EQUAL"], +["549755813887", "0x05 0xFFFFFFFF7F EQUAL"], +["549755813888", "0x06 0xFFFFFFFF7F EQUAL"], +["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL"], ["-1", "0x01 0x81 EQUAL", "Numbers are little-endian with the MSB being a sign bit"], ["-127", "0x01 0xFF EQUAL"], ["-128", "0x02 0x8080 EQUAL"], @@ -315,6 +324,10 @@ ["-8388608", "0x04 0x00008080 EQUAL"], ["-2147483647", "0x04 0xFFFFFFFF EQUAL"], ["-2147483648", "0x05 0x0000008080 EQUAL"], +["-4294967295", "0x05 0xFFFFFFFF80 EQUAL"], +["-549755813887", "0x05 0xFFFFFFFFFF EQUAL"], +["-549755813888", "0x06 0x000000008080 EQUAL"], +["-9223372036854775807", "0x08 0xFFFFFFFFFFFFFFFF EQUAL"], ["2147483647", "1ADD 2147483648 EQUAL", "We can do math on 4-byte integers, and compare 5-byte ones"], ["2147483647", "1ADD 1"], diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp new file mode 100644 index 0000000000..cd194cc4d9 --- /dev/null +++ b/src/test/scriptnum_tests.cpp @@ -0,0 +1,196 @@ +// Copyright (c) 2012-2014 The Bitcoin Core developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bignum.h" +#include "script.h" +#include <boost/test/unit_test.hpp> +#include <limits.h> +#include <stdint.h> +BOOST_AUTO_TEST_SUITE(scriptnum_tests) + +static const int64_t values[] = \ +{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX }; +static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; + +static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum) +{ + return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint(); +} + +static void CheckCreateVch(const int64_t& num) +{ + CBigNum bignum(num); + CScriptNum scriptnum(num); + BOOST_CHECK(verify(bignum, scriptnum)); + + CBigNum bignum2(bignum.getvch()); + CScriptNum scriptnum2(scriptnum.getvch()); + BOOST_CHECK(verify(bignum2, scriptnum2)); + + CBigNum bignum3(scriptnum2.getvch()); + CScriptNum scriptnum3(bignum2.getvch()); + BOOST_CHECK(verify(bignum3, scriptnum3)); +} + +static void CheckCreateInt(const int64_t& num) +{ + CBigNum bignum(num); + CScriptNum scriptnum(num); + BOOST_CHECK(verify(bignum, scriptnum)); + BOOST_CHECK(verify(bignum.getint(), CScriptNum(scriptnum.getint()))); + BOOST_CHECK(verify(scriptnum.getint(), CScriptNum(bignum.getint()))); + BOOST_CHECK(verify(CBigNum(scriptnum.getint()).getint(), CScriptNum(CScriptNum(bignum.getint()).getint()))); +} + + +static void CheckAdd(const int64_t& num1, const int64_t& num2) +{ + const CBigNum bignum1(num1); + const CBigNum bignum2(num2); + const CScriptNum scriptnum1(num1); + const CScriptNum scriptnum2(num2); + CBigNum bignum3(num1); + CBigNum bignum4(num1); + CScriptNum scriptnum3(num1); + CScriptNum scriptnum4(num1); + + // int64_t overflow is undefined. + bool invalid = (((num2 > 0) && (num1 > (std::numeric_limits<int64_t>::max() - num2))) || + ((num2 < 0) && (num1 < (std::numeric_limits<int64_t>::min() - num2)))); + if (!invalid) + { + BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + scriptnum2)); + BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + num2)); + BOOST_CHECK(verify(bignum1 + bignum2, scriptnum2 + num1)); + } +} + +static void CheckNegate(const int64_t& num) +{ + const CBigNum bignum(num); + const CScriptNum scriptnum(num); + + // -INT64_MIN is undefined + if (num != std::numeric_limits<int64_t>::min()) + BOOST_CHECK(verify(-bignum, -scriptnum)); +} + +static void CheckSubtract(const int64_t& num1, const int64_t& num2) +{ + const CBigNum bignum1(num1); + const CBigNum bignum2(num2); + const CScriptNum scriptnum1(num1); + const CScriptNum scriptnum2(num2); + bool invalid = false; + + // int64_t overflow is undefined. + invalid = ((num2 > 0 && num1 < std::numeric_limits<int64_t>::min() + num2) || + (num2 < 0 && num1 > std::numeric_limits<int64_t>::max() + num2)); + if (!invalid) + { + BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - scriptnum2)); + BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - num2)); + } + + invalid = ((num1 > 0 && num2 < std::numeric_limits<int64_t>::min() + num1) || + (num1 < 0 && num2 > std::numeric_limits<int64_t>::max() + num1)); + if (!invalid) + { + BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - scriptnum1)); + BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - num1)); + } +} + +static void CheckCompare(const int64_t& num1, const int64_t& num2) +{ + const CBigNum bignum1(num1); + const CBigNum bignum2(num2); + const CScriptNum scriptnum1(num1); + const CScriptNum scriptnum2(num2); + + BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == scriptnum1)); + BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != scriptnum1)); + BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < scriptnum1)); + BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > scriptnum1)); + BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= scriptnum1)); + BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= scriptnum1)); + + BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == num1)); + BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != num1)); + BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < num1)); + BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > num1)); + BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= num1)); + BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= num1)); + + BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == scriptnum2)); + BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != scriptnum2)); + BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < scriptnum2)); + BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > scriptnum2)); + BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= scriptnum2)); + BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= scriptnum2)); + + BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == num2)); + BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != num2)); + BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < num2)); + BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > num2)); + BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= num2)); + BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= num2)); +} + +static void RunCreate(const int64_t& num) +{ + CheckCreateInt(num); + CScriptNum scriptnum(num); + if (scriptnum.getvch().size() <= CScriptNum::nMaxNumSize) + CheckCreateVch(num); + else + { + BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum_error); + } +} + +static void RunOperators(const int64_t& num1, const int64_t& num2) +{ + CheckAdd(num1, num2); + CheckSubtract(num1, num2); + CheckNegate(num1); + CheckCompare(num1, num2); +} + +BOOST_AUTO_TEST_CASE(creation) +{ + for(size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) + { + for(size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j) + { + RunCreate(values[i]); + RunCreate(values[i] + offsets[j]); + RunCreate(values[i] - offsets[j]); + } + } +} + +BOOST_AUTO_TEST_CASE(operators) +{ + for(size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) + { + for(size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j) + { + RunOperators(values[i], values[i]); + RunOperators(values[i], -values[i]); + RunOperators(values[i], values[j]); + RunOperators(values[i], -values[j]); + RunOperators(values[i] + values[j], values[j]); + RunOperators(values[i] + values[j], -values[j]); + RunOperators(values[i] - values[j], values[j]); + RunOperators(values[i] - values[j], -values[j]); + RunOperators(values[i] + values[j], values[i] + values[j]); + RunOperators(values[i] + values[j], values[i] - values[j]); + RunOperators(values[i] - values[j], values[i] + values[j]); + RunOperators(values[i] - values[j], values[i] - values[j]); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() |