Changeset View
Changeset View
Standalone View
Standalone View
src/test/intmath_tests.cpp
| // Copyright (c) 2021 The Bitcoin developers | // Copyright (c) 2021 The Bitcoin developers | ||||
| // Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
| // file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
| #include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
| #include <test/lcg.h> | #include <test/lcg.h> | ||||
| #include <test/util/setup_common.h> | #include <test/util/setup_common.h> | ||||
| #include <script/intmath.h> | #include <script/intmath.h> | ||||
| #include <script/script.h> | |||||
| #include <boost/multiprecision/cpp_int.hpp> | #include <boost/multiprecision/cpp_int.hpp> | ||||
| BOOST_FIXTURE_TEST_SUITE(intmath_tests, BasicTestingSetup) | BOOST_FIXTURE_TEST_SUITE(intmath_tests, BasicTestingSetup) | ||||
| using i128_t = boost::multiprecision::checked_int128_t; | using i128_t = boost::multiprecision::checked_int128_t; | ||||
| const i128_t MAX_SCRIPT_63_BIT_INT = 0x7fff'ffff'ffff'ffff; | const i128_t MAX_SCRIPT_63_BIT_INT = 0x7fff'ffff'ffff'ffff; | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | const i128_t b = b_64; | ||||
| int64_t result; | int64_t result; | ||||
| bool had_overflow = AddInt63Overflow(a_64, b_64, result); | bool had_overflow = AddInt63Overflow(a_64, b_64, result); | ||||
| CheckArithmeticResult(strprintf("%d + %d", a, b), expect_overflow, | CheckArithmeticResult(strprintf("%d + %d", a, b), expect_overflow, | ||||
| had_overflow_emulated, result_emulated, a + b); | had_overflow_emulated, result_emulated, a + b); | ||||
| if (!expect_overflow) { | if (!expect_overflow) { | ||||
| BOOST_CHECK_EQUAL(result, result_emulated); | BOOST_CHECK_EQUAL(result, result_emulated); | ||||
| } | } | ||||
| BOOST_CHECK_EQUAL(had_overflow, had_overflow_emulated); | BOOST_CHECK_EQUAL(had_overflow, had_overflow_emulated); | ||||
| // Test CScriptNum + and += | |||||
| if (expect_overflow) { | |||||
| BOOST_CHECK_EXCEPTION(CScriptNum(a_64) + CScriptNum(b_64), | |||||
| scriptnum_error, | |||||
| HasReason("script number overflow")); | |||||
| CScriptNum lhs(a_64); | |||||
| BOOST_CHECK_EXCEPTION(lhs += CScriptNum(b_64), scriptnum_error, | |||||
| HasReason("script number overflow")); | |||||
| } else { | |||||
| BOOST_CHECK_EQUAL((CScriptNum(a_64) + CScriptNum(b_64)).getint(), | |||||
| a + b); | |||||
| CScriptNum lhs(a_64); | |||||
| BOOST_CHECK_EQUAL((lhs += CScriptNum(b_64)).getint(), a + b); | |||||
| BOOST_CHECK_EQUAL(lhs.getint(), a + b); | |||||
| } | |||||
| } | } | ||||
| { | { | ||||
| bool expect_overflow = !IsInScriptBounds(a - b); | bool expect_overflow = !IsInScriptBounds(a - b); | ||||
| // Test SubInt63OverflowEmulated | // Test SubInt63OverflowEmulated | ||||
| int64_t result_emulated = uint64_t(1) + a_64 - b_64; | int64_t result_emulated = uint64_t(1) + a_64 - b_64; | ||||
| bool had_overflow_emulated = | bool had_overflow_emulated = | ||||
| SubInt63OverflowEmulated(a_64, b_64, result_emulated); | SubInt63OverflowEmulated(a_64, b_64, result_emulated); | ||||
| CheckArithmeticResult(strprintf("%d - %d", a, b), expect_overflow, | CheckArithmeticResult(strprintf("%d - %d", a, b), expect_overflow, | ||||
| had_overflow_emulated, result_emulated, a - b); | had_overflow_emulated, result_emulated, a - b); | ||||
| // Test SubInt63Overflow | // Test SubInt63Overflow | ||||
| int64_t result; | int64_t result; | ||||
| bool had_overflow = SubInt63Overflow(a_64, b_64, result); | bool had_overflow = SubInt63Overflow(a_64, b_64, result); | ||||
| CheckArithmeticResult(strprintf("%d - %d", a, b), expect_overflow, | CheckArithmeticResult(strprintf("%d - %d", a, b), expect_overflow, | ||||
| had_overflow_emulated, result_emulated, a - b); | had_overflow_emulated, result_emulated, a - b); | ||||
| if (!expect_overflow) { | if (!expect_overflow) { | ||||
| BOOST_CHECK_EQUAL(result, result_emulated); | BOOST_CHECK_EQUAL(result, result_emulated); | ||||
| } | } | ||||
| BOOST_CHECK_EQUAL(had_overflow, had_overflow_emulated); | BOOST_CHECK_EQUAL(had_overflow, had_overflow_emulated); | ||||
| // Test CScriptNum - and -= | |||||
| if (expect_overflow) { | |||||
| BOOST_CHECK_EXCEPTION(CScriptNum(a_64) - CScriptNum(b_64), | |||||
| scriptnum_error, | |||||
| HasReason("script number overflow")); | |||||
| CScriptNum lhs(a_64); | |||||
| BOOST_CHECK_EXCEPTION(lhs -= CScriptNum(b_64), scriptnum_error, | |||||
| HasReason("script number overflow")); | |||||
| } else { | |||||
| BOOST_CHECK_EQUAL((CScriptNum(a_64) - CScriptNum(b_64)).getint(), | |||||
| a - b); | |||||
| CScriptNum lhs(a_64); | |||||
| BOOST_CHECK_EQUAL((lhs -= CScriptNum(b_64)).getint(), a - b); | |||||
| BOOST_CHECK_EQUAL(lhs.getint(), a - b); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /** Generate random number in [-2^63; 2^63]. */ | /** Generate random number in [-2^63; 2^63]. */ | ||||
| int64_t GenInt63(MMIXLinearCongruentialGenerator &lcg) { | int64_t GenInt63(MMIXLinearCongruentialGenerator &lcg) { | ||||
| while (true) { | while (true) { | ||||
| // Uniform number in [-2^63; 2^63]. | // Uniform number in [-2^63; 2^63]. | ||||
| int64_t val = (int64_t(lcg.next()) << 32) | lcg.next(); | int64_t val = (int64_t(lcg.next()) << 32) | lcg.next(); | ||||
| Show All 28 Lines | |||||