util_tests.cpp
1 // Copyright (c) 2011-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 <clientversion.h> 6 #include <common/signmessage.h> 7 #include <hash.h> 8 #include <key.h> 9 #include <script/parsing.h> 10 #include <span.h> 11 #include <sync.h> 12 #include <test/util/random.h> 13 #include <test/util/setup_common.h> 14 #include <uint256.h> 15 #include <util/bitdeque.h> 16 #include <util/byte_units.h> 17 #include <util/fs.h> 18 #include <util/fs_helpers.h> 19 #include <util/moneystr.h> 20 #include <util/overflow.h> 21 #include <util/readwritefile.h> 22 #include <util/strencodings.h> 23 #include <util/string.h> 24 #include <util/time.h> 25 #include <util/vector.h> 26 27 #include <array> 28 #include <cmath> 29 #include <cstdint> 30 #include <cstring> 31 #include <fstream> 32 #include <limits> 33 #include <map> 34 #include <optional> 35 #include <string> 36 #include <thread> 37 #include <univalue.h> 38 #include <utility> 39 #include <vector> 40 41 #include <sys/types.h> 42 43 #ifndef WIN32 44 #include <sys/wait.h> 45 #endif 46 47 #include <boost/test/unit_test.hpp> 48 49 using namespace std::literals; 50 using namespace util::hex_literals; 51 using util::ConstevalHexDigit; 52 using util::Join; 53 using util::RemovePrefix; 54 using util::RemovePrefixView; 55 using util::ReplaceAll; 56 using util::Split; 57 using util::SplitString; 58 using util::TrimString; 59 using util::TrimStringView; 60 61 static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s}; 62 63 /* defined in logging.cpp */ 64 namespace BCLog { 65 std::string LogEscapeMessage(std::string_view str); 66 } 67 68 BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup) 69 70 namespace { 71 class NoCopyOrMove 72 { 73 public: 74 int i; 75 explicit NoCopyOrMove(int i) : i{i} { } 76 77 NoCopyOrMove() = delete; 78 NoCopyOrMove(const NoCopyOrMove&) = delete; 79 NoCopyOrMove(NoCopyOrMove&&) = delete; 80 NoCopyOrMove& operator=(const NoCopyOrMove&) = delete; 81 NoCopyOrMove& operator=(NoCopyOrMove&&) = delete; 82 83 operator bool() const { return i != 0; } 84 85 int get_ip1() { return i + 1; } 86 bool test() 87 { 88 // Check that Assume can be used within a lambda and still call methods 89 [&]() { Assume(get_ip1()); }(); 90 return Assume(get_ip1() != 5); 91 } 92 }; 93 } // namespace 94 95 BOOST_AUTO_TEST_CASE(util_check) 96 { 97 // Check that Assert can forward 98 const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2)); 99 // Check that Assert works on lvalues and rvalues 100 const int two = *Assert(p_two); 101 Assert(two == 2); 102 Assert(true); 103 // Check that Assume can be used as unary expression 104 const bool result{Assume(two == 2)}; 105 Assert(result); 106 107 // Check that Assert doesn't require copy/move 108 NoCopyOrMove x{9}; 109 Assert(x).i += 3; 110 Assert(x).test(); 111 112 // Check nested Asserts 113 BOOST_CHECK_EQUAL(Assert((Assert(x).test() ? 3 : 0)), 3); 114 115 // Check -Wdangling-gsl does not trigger when copying the int. (It would 116 // trigger on "const int&") 117 const int nine{*Assert(std::optional<int>{9})}; 118 BOOST_CHECK_EQUAL(9, nine); 119 } 120 121 BOOST_AUTO_TEST_CASE(util_criticalsection) 122 { 123 RecursiveMutex cs; 124 125 do { 126 LOCK(cs); 127 break; 128 129 BOOST_ERROR("break was swallowed!"); 130 } while(0); 131 132 do { 133 TRY_LOCK(cs, lockTest); 134 if (lockTest) { 135 BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions" 136 break; 137 } 138 139 BOOST_ERROR("break was swallowed!"); 140 } while(0); 141 } 142 143 constexpr char HEX_PARSE_INPUT[] = "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"; 144 constexpr uint8_t HEX_PARSE_OUTPUT[] = { 145 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 146 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 147 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 148 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 149 0x5f 150 }; 151 static_assert((sizeof(HEX_PARSE_INPUT) - 1) == 2 * sizeof(HEX_PARSE_OUTPUT)); 152 BOOST_AUTO_TEST_CASE(parse_hex) 153 { 154 std::vector<unsigned char> result; 155 156 // Basic test vector 157 std::vector<unsigned char> expected(std::begin(HEX_PARSE_OUTPUT), std::end(HEX_PARSE_OUTPUT)); 158 constexpr std::array<std::byte, 65> hex_literal_array{operator""_hex<util::detail::Hex(HEX_PARSE_INPUT)>()}; 159 auto hex_literal_span{MakeUCharSpan(hex_literal_array)}; 160 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end()); 161 162 const std::vector<std::byte> hex_literal_vector{operator""_hex_v<util::detail::Hex(HEX_PARSE_INPUT)>()}; 163 auto hex_literal_vec_span = MakeUCharSpan(hex_literal_vector); 164 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_vec_span.begin(), hex_literal_vec_span.end(), expected.begin(), expected.end()); 165 166 constexpr std::array<uint8_t, 65> hex_literal_array_uint8{operator""_hex_u8<util::detail::Hex(HEX_PARSE_INPUT)>()}; 167 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_array_uint8.begin(), hex_literal_array_uint8.end(), expected.begin(), expected.end()); 168 169 result = operator""_hex_v_u8<util::detail::Hex(HEX_PARSE_INPUT)>(); 170 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 171 172 result = ParseHex(HEX_PARSE_INPUT); 173 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 174 175 result = TryParseHex<uint8_t>(HEX_PARSE_INPUT).value(); 176 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 177 178 // Spaces between bytes must be supported 179 expected = {0x12, 0x34, 0x56, 0x78}; 180 result = ParseHex("12 34 56 78"); 181 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 182 result = TryParseHex<uint8_t>("12 34 56 78").value(); 183 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 184 185 // Leading space must be supported 186 expected = {0x89, 0x34, 0x56, 0x78}; 187 result = ParseHex(" 89 34 56 78"); 188 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 189 result = TryParseHex<uint8_t>(" 89 34 56 78").value(); 190 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 191 192 // Mixed case and spaces are supported 193 expected = {0xff, 0xaa}; 194 result = ParseHex(" Ff aA "); 195 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 196 result = TryParseHex<uint8_t>(" Ff aA ").value(); 197 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); 198 199 // Empty string is supported 200 static_assert(""_hex.empty()); 201 static_assert(""_hex_u8.empty()); 202 BOOST_CHECK_EQUAL(""_hex_v.size(), 0); 203 BOOST_CHECK_EQUAL(""_hex_v_u8.size(), 0); 204 BOOST_CHECK_EQUAL(ParseHex("").size(), 0); 205 BOOST_CHECK_EQUAL(TryParseHex<uint8_t>("").value().size(), 0); 206 207 // Spaces between nibbles is treated as invalid 208 BOOST_CHECK_EQUAL(ParseHex("AAF F").size(), 0); 209 BOOST_CHECK(!TryParseHex("AAF F").has_value()); 210 211 // Embedded null is treated as invalid 212 const std::string with_embedded_null{" 11 "s 213 " \0 " 214 " 22 "s}; 215 BOOST_CHECK_EQUAL(with_embedded_null.size(), 11); 216 BOOST_CHECK_EQUAL(ParseHex(with_embedded_null).size(), 0); 217 BOOST_CHECK(!TryParseHex(with_embedded_null).has_value()); 218 219 // Non-hex is treated as invalid 220 BOOST_CHECK_EQUAL(ParseHex("1234 invalid 1234").size(), 0); 221 BOOST_CHECK(!TryParseHex("1234 invalid 1234").has_value()); 222 223 // Truncated input is treated as invalid 224 BOOST_CHECK_EQUAL(ParseHex("12 3").size(), 0); 225 BOOST_CHECK(!TryParseHex("12 3").has_value()); 226 } 227 228 BOOST_AUTO_TEST_CASE(consteval_hex_digit) 229 { 230 BOOST_CHECK_EQUAL(ConstevalHexDigit('0'), 0); 231 BOOST_CHECK_EQUAL(ConstevalHexDigit('9'), 9); 232 BOOST_CHECK_EQUAL(ConstevalHexDigit('a'), 0xa); 233 BOOST_CHECK_EQUAL(ConstevalHexDigit('f'), 0xf); 234 } 235 236 BOOST_AUTO_TEST_CASE(util_HexStr) 237 { 238 BOOST_CHECK_EQUAL(HexStr(HEX_PARSE_OUTPUT), HEX_PARSE_INPUT); 239 BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.last(0)), ""); 240 BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.first(0)), ""); 241 242 { 243 constexpr std::string_view out_exp{"04678afdb0"}; 244 constexpr std::span in_s{HEX_PARSE_OUTPUT, out_exp.size() / 2}; 245 const std::span<const uint8_t> in_u{MakeUCharSpan(in_s)}; 246 const std::span<const std::byte> in_b{MakeByteSpan(in_s)}; 247 248 BOOST_CHECK_EQUAL(HexStr(in_u), out_exp); 249 BOOST_CHECK_EQUAL(HexStr(in_s), out_exp); 250 BOOST_CHECK_EQUAL(HexStr(in_b), out_exp); 251 } 252 253 { 254 auto input = std::string(); 255 for (size_t i=0; i<256; ++i) { 256 input.push_back(static_cast<char>(i)); 257 } 258 259 auto hex = HexStr(input); 260 BOOST_TEST_REQUIRE(hex.size() == 512); 261 static constexpr auto hexmap = std::string_view("0123456789abcdef"); 262 for (size_t i = 0; i < 256; ++i) { 263 auto upper = hexmap.find(hex[i * 2]); 264 auto lower = hexmap.find(hex[i * 2 + 1]); 265 BOOST_TEST_REQUIRE(upper != std::string_view::npos); 266 BOOST_TEST_REQUIRE(lower != std::string_view::npos); 267 BOOST_TEST_REQUIRE(i == upper*16 + lower); 268 } 269 } 270 } 271 272 BOOST_AUTO_TEST_CASE(span_write_bytes) 273 { 274 std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}}; 275 const auto mut_bytes{MakeWritableByteSpan(mut_arr)}; 276 mut_bytes[1] = std::byte{0x11}; 277 BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa); 278 BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11); 279 } 280 281 BOOST_AUTO_TEST_CASE(util_Join) 282 { 283 // Normal version 284 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), ""); 285 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo"); 286 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar"); 287 288 // Version with unary operator 289 const auto op_upper = [](const std::string& s) { return ToUpper(s); }; 290 BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), ""); 291 BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO"); 292 BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR"); 293 } 294 295 BOOST_AUTO_TEST_CASE(util_ReplaceAll) 296 { 297 const std::string original("A test \"%s\" string '%s'."); 298 auto test_replaceall = [&original](const std::string& search, const std::string& substitute, const std::string& expected) { 299 auto test = original; 300 ReplaceAll(test, search, substitute); 301 BOOST_CHECK_EQUAL(test, expected); 302 }; 303 304 test_replaceall("", "foo", original); 305 test_replaceall(original, "foo", "foo"); 306 test_replaceall("%s", "foo", "A test \"foo\" string 'foo'."); 307 test_replaceall("\"", "foo", "A test foo%sfoo string '%s'."); 308 test_replaceall("'", "foo", "A test \"%s\" string foo%sfoo."); 309 } 310 311 BOOST_AUTO_TEST_CASE(util_TrimString) 312 { 313 BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar"); 314 BOOST_CHECK_EQUAL(TrimStringView("\t \n \n \f\n\r\t\v\tfoo \n \f\n\r\t\v\tbar\t \n \f\n\r\t\v\t\n "), "foo \n \f\n\r\t\v\tbar"); 315 BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar"); 316 BOOST_CHECK_EQUAL(TrimStringView("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n "); 317 BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar"); 318 BOOST_CHECK_EQUAL(TrimStringView("foo bar", "fobar"), " "); 319 BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7)); 320 BOOST_CHECK_EQUAL(TrimStringView(std::string(" foo ", 5)), std::string("foo", 3)); 321 BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2)); 322 BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6)); 323 BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01", 5)), std::string("\0", 1)); 324 BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), ""); 325 } 326 327 BOOST_AUTO_TEST_CASE(util_ParseISO8601DateTime) 328 { 329 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1969-12-31T23:59:59Z").value(), -1); 330 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z").value(), 0); 331 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:01Z").value(), 1); 332 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:01Z").value(), 946684801); 333 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z").value(), 1317425777); 334 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2100-12-31T23:59:59Z").value(), 4133980799); 335 BOOST_CHECK_EQUAL(ParseISO8601DateTime("9999-12-31T23:59:59Z").value(), 253402300799); 336 337 // Accept edge-cases, where the time overflows. They are not produced by 338 // FormatISO8601DateTime, so this can be changed in the future, if needed. 339 // For now, keep compatibility with the previous implementation. 340 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:00:00Z").value(), 947041200); 341 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:99:00Z").value(), 946690740); 342 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:99Z").value(), 946684899); 343 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:99:99Z").value(), 947047239); 344 345 // Reject date overflows. 346 BOOST_CHECK(!ParseISO8601DateTime("2000-99-01T00:00:00Z")); 347 BOOST_CHECK(!ParseISO8601DateTime("2000-01-99T00:00:00Z")); 348 349 // Reject out-of-range years 350 BOOST_CHECK(!ParseISO8601DateTime("32768-12-31T23:59:59Z")); 351 BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T23:59:59Z")); 352 BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T00:00:00Z")); 353 BOOST_CHECK(!ParseISO8601DateTime("999-12-31T00:00:00Z")); 354 355 // Reject invalid format 356 const std::string valid{"2000-01-01T00:00:01Z"}; 357 BOOST_CHECK(ParseISO8601DateTime(valid).has_value()); 358 for (auto mut{0U}; mut < valid.size(); ++mut) { 359 std::string invalid{valid}; 360 invalid[mut] = 'a'; 361 BOOST_CHECK(!ParseISO8601DateTime(invalid)); 362 } 363 } 364 365 BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime) 366 { 367 BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z"); 368 BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z"); 369 370 BOOST_CHECK_EQUAL(FormatISO8601DateTime(-1), "1969-12-31T23:59:59Z"); 371 BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z"); 372 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1), "1970-01-01T00:00:01Z"); 373 BOOST_CHECK_EQUAL(FormatISO8601DateTime(946684801), "2000-01-01T00:00:01Z"); 374 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z"); 375 BOOST_CHECK_EQUAL(FormatISO8601DateTime(4133980799), "2100-12-31T23:59:59Z"); 376 BOOST_CHECK_EQUAL(FormatISO8601DateTime(253402300799), "9999-12-31T23:59:59Z"); 377 } 378 379 BOOST_AUTO_TEST_CASE(util_FormatISO8601Date) 380 { 381 BOOST_CHECK_EQUAL(FormatISO8601Date(971890963199), "32767-12-31"); 382 BOOST_CHECK_EQUAL(FormatISO8601Date(971890876800), "32767-12-31"); 383 384 BOOST_CHECK_EQUAL(FormatISO8601Date(0), "1970-01-01"); 385 BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30"); 386 } 387 388 BOOST_AUTO_TEST_CASE(util_FormatMoney) 389 { 390 BOOST_CHECK_EQUAL(FormatMoney(0), "0.00"); 391 BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789"); 392 BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00"); 393 394 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00"); 395 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00"); 396 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00"); 397 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00"); 398 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00"); 399 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00"); 400 BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00"); 401 BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00"); 402 BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00"); 403 BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10"); 404 BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01"); 405 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001"); 406 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001"); 407 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001"); 408 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001"); 409 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001"); 410 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001"); 411 412 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807"); 413 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806"); 414 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805"); 415 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804"); 416 // ... 417 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805"); 418 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806"); 419 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807"); 420 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808"); 421 } 422 423 BOOST_AUTO_TEST_CASE(util_ParseMoney) 424 { 425 BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0); 426 BOOST_CHECK_EQUAL(ParseMoney(".").value(), 0); 427 BOOST_CHECK_EQUAL(ParseMoney("0.").value(), 0); 428 BOOST_CHECK_EQUAL(ParseMoney(".0").value(), 0); 429 BOOST_CHECK_EQUAL(ParseMoney(".6789").value(), 6789'0000); 430 BOOST_CHECK_EQUAL(ParseMoney("12345.").value(), COIN * 12345); 431 432 BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789); 433 434 BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000); 435 BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000); 436 BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000); 437 BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000); 438 BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000); 439 BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100); 440 BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10); 441 BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN); 442 BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN); 443 BOOST_CHECK_EQUAL(ParseMoney(" 1").value(), COIN); 444 BOOST_CHECK_EQUAL(ParseMoney("1 ").value(), COIN); 445 BOOST_CHECK_EQUAL(ParseMoney(" 1 ").value(), COIN); 446 BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10); 447 BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100); 448 BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000); 449 BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000); 450 BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000); 451 BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000); 452 BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000); 453 BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000); 454 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000); 455 BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000); 456 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000); 457 458 // Parsing amount that cannot be represented should fail 459 BOOST_CHECK(!ParseMoney("100000000.00")); 460 BOOST_CHECK(!ParseMoney("0.000000001")); 461 462 // Parsing empty string should fail 463 BOOST_CHECK(!ParseMoney("")); 464 BOOST_CHECK(!ParseMoney(" ")); 465 BOOST_CHECK(!ParseMoney(" ")); 466 467 // Parsing two numbers should fail 468 BOOST_CHECK(!ParseMoney("..")); 469 BOOST_CHECK(!ParseMoney("0..0")); 470 BOOST_CHECK(!ParseMoney("1 2")); 471 BOOST_CHECK(!ParseMoney(" 1 2 ")); 472 BOOST_CHECK(!ParseMoney(" 1.2 3 ")); 473 BOOST_CHECK(!ParseMoney(" 1 2.3 ")); 474 475 // Embedded whitespace should fail 476 BOOST_CHECK(!ParseMoney(" -1 .2 ")); 477 BOOST_CHECK(!ParseMoney(" 1 .2 ")); 478 BOOST_CHECK(!ParseMoney(" +1 .2 ")); 479 480 // Attempted 63 bit overflow should fail 481 BOOST_CHECK(!ParseMoney("92233720368.54775808")); 482 483 // Parsing negative amounts must fail 484 BOOST_CHECK(!ParseMoney("-1")); 485 486 // Parsing strings with embedded NUL characters should fail 487 BOOST_CHECK(!ParseMoney("\0-1"s)); 488 BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR)); 489 BOOST_CHECK(!ParseMoney("1\0"s)); 490 } 491 492 BOOST_AUTO_TEST_CASE(util_IsHex) 493 { 494 BOOST_CHECK(IsHex("00")); 495 BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF")); 496 BOOST_CHECK(IsHex("ff")); 497 BOOST_CHECK(IsHex("FF")); 498 499 BOOST_CHECK(!IsHex("")); 500 BOOST_CHECK(!IsHex("0")); 501 BOOST_CHECK(!IsHex("a")); 502 BOOST_CHECK(!IsHex("eleven")); 503 BOOST_CHECK(!IsHex("00xx00")); 504 BOOST_CHECK(!IsHex("0x0000")); 505 } 506 507 BOOST_AUTO_TEST_CASE(util_seed_insecure_rand) 508 { 509 SeedRandomForTest(SeedRand::ZEROS); 510 for (int mod=2;mod<11;mod++) 511 { 512 int mask = 1; 513 // Really rough binomial confidence approximation. 514 int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.); 515 //mask is 2^ceil(log2(mod))-1 516 while(mask<mod-1)mask=(mask<<1)+1; 517 518 int count = 0; 519 //How often does it get a zero from the uniform range [0,mod)? 520 for (int i = 0; i < 10000; i++) { 521 uint32_t rval; 522 do{ 523 rval=m_rng.rand32()&mask; 524 }while(rval>=(uint32_t)mod); 525 count += rval==0; 526 } 527 BOOST_CHECK(count<=10000/mod+err); 528 BOOST_CHECK(count>=10000/mod-err); 529 } 530 } 531 532 BOOST_AUTO_TEST_CASE(util_TimingResistantEqual) 533 { 534 BOOST_CHECK(TimingResistantEqual(std::string(""), std::string(""))); 535 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string(""))); 536 BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc"))); 537 BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa"))); 538 BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a"))); 539 BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc"))); 540 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba"))); 541 } 542 543 /* Test strprintf formatting directives. 544 * Put a string before and after to ensure sanity of element sizes on stack. */ 545 #define B "check_prefix" 546 #define E "check_postfix" 547 BOOST_AUTO_TEST_CASE(strprintf_numbers) 548 { 549 int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */ 550 uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */ 551 BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E); 552 BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E); 553 BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E); 554 555 size_t st = 12345678; /* unsigned size_t test value */ 556 ssize_t sst = -12345678; /* signed size_t test value */ 557 BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E); 558 BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E); 559 BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E); 560 561 ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */ 562 ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */ 563 BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E); 564 BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E); 565 BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E); 566 } 567 #undef B 568 #undef E 569 570 BOOST_AUTO_TEST_CASE(util_mocktime) 571 { 572 SetMockTime(111s); 573 // Check that mock time does not change after a sleep 574 for (const auto& num_sleep : {0ms, 1ms}) { 575 UninterruptibleSleep(num_sleep); 576 BOOST_CHECK_EQUAL(111, GetTime()); // Deprecated time getter 577 BOOST_CHECK_EQUAL(111, Now<NodeSeconds>().time_since_epoch().count()); 578 BOOST_CHECK_EQUAL(111, TicksSinceEpoch<std::chrono::seconds>(NodeClock::now())); 579 BOOST_CHECK_EQUAL(111, TicksSinceEpoch<SecondsDouble>(Now<NodeSeconds>())); 580 BOOST_CHECK_EQUAL(111, GetTime<std::chrono::seconds>().count()); 581 BOOST_CHECK_EQUAL(111000, GetTime<std::chrono::milliseconds>().count()); 582 BOOST_CHECK_EQUAL(111000, TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now())); 583 BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count()); 584 } 585 SetMockTime(0s); 586 } 587 588 BOOST_AUTO_TEST_CASE(test_IsDigit) 589 { 590 BOOST_CHECK_EQUAL(IsDigit('0'), true); 591 BOOST_CHECK_EQUAL(IsDigit('1'), true); 592 BOOST_CHECK_EQUAL(IsDigit('8'), true); 593 BOOST_CHECK_EQUAL(IsDigit('9'), true); 594 595 BOOST_CHECK_EQUAL(IsDigit('0' - 1), false); 596 BOOST_CHECK_EQUAL(IsDigit('9' + 1), false); 597 BOOST_CHECK_EQUAL(IsDigit(0), false); 598 BOOST_CHECK_EQUAL(IsDigit(1), false); 599 BOOST_CHECK_EQUAL(IsDigit(8), false); 600 BOOST_CHECK_EQUAL(IsDigit(9), false); 601 } 602 603 /* Check for overflow */ 604 template <typename T> 605 static void TestAddMatrixOverflow() 606 { 607 constexpr T MAXI{std::numeric_limits<T>::max()}; 608 BOOST_CHECK(!CheckedAdd(T{1}, MAXI)); 609 BOOST_CHECK(!CheckedAdd(MAXI, MAXI)); 610 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI)); 611 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(MAXI, MAXI)); 612 613 BOOST_CHECK_EQUAL(0, CheckedAdd(T{0}, T{0}).value()); 614 BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{0}, MAXI).value()); 615 BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{1}, MAXI - 1).value()); 616 BOOST_CHECK_EQUAL(MAXI - 1, CheckedAdd(T{1}, MAXI - 2).value()); 617 BOOST_CHECK_EQUAL(0, SaturatingAdd(T{0}, T{0})); 618 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{0}, MAXI)); 619 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI - 1)); 620 BOOST_CHECK_EQUAL(MAXI - 1, SaturatingAdd(T{1}, MAXI - 2)); 621 } 622 623 /* Check for overflow or underflow */ 624 template <typename T> 625 static void TestAddMatrix() 626 { 627 TestAddMatrixOverflow<T>(); 628 constexpr T MINI{std::numeric_limits<T>::min()}; 629 constexpr T MAXI{std::numeric_limits<T>::max()}; 630 BOOST_CHECK(!CheckedAdd(T{-1}, MINI)); 631 BOOST_CHECK(!CheckedAdd(MINI, MINI)); 632 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI)); 633 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(MINI, MINI)); 634 635 BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{0}, MINI).value()); 636 BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{-1}, MINI + 1).value()); 637 BOOST_CHECK_EQUAL(-1, CheckedAdd(MINI, MAXI).value()); 638 BOOST_CHECK_EQUAL(MINI + 1, CheckedAdd(T{-1}, MINI + 2).value()); 639 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{0}, MINI)); 640 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI + 1)); 641 BOOST_CHECK_EQUAL(MINI + 1, SaturatingAdd(T{-1}, MINI + 2)); 642 BOOST_CHECK_EQUAL(-1, SaturatingAdd(MINI, MAXI)); 643 } 644 645 BOOST_AUTO_TEST_CASE(util_overflow) 646 { 647 TestAddMatrixOverflow<unsigned>(); 648 TestAddMatrix<signed>(); 649 } 650 651 template <typename T> 652 static void RunToIntegralTests() 653 { 654 BOOST_CHECK(!ToIntegral<T>(STRING_WITH_EMBEDDED_NULL_CHAR)); 655 BOOST_CHECK(!ToIntegral<T>(" 1")); 656 BOOST_CHECK(!ToIntegral<T>("1 ")); 657 BOOST_CHECK(!ToIntegral<T>("1a")); 658 BOOST_CHECK(!ToIntegral<T>("1.1")); 659 BOOST_CHECK(!ToIntegral<T>("1.9")); 660 BOOST_CHECK(!ToIntegral<T>("+01.9")); 661 BOOST_CHECK(!ToIntegral<T>("-")); 662 BOOST_CHECK(!ToIntegral<T>("+")); 663 BOOST_CHECK(!ToIntegral<T>(" -1")); 664 BOOST_CHECK(!ToIntegral<T>("-1 ")); 665 BOOST_CHECK(!ToIntegral<T>(" -1 ")); 666 BOOST_CHECK(!ToIntegral<T>("+1")); 667 BOOST_CHECK(!ToIntegral<T>(" +1")); 668 BOOST_CHECK(!ToIntegral<T>(" +1 ")); 669 BOOST_CHECK(!ToIntegral<T>("+-1")); 670 BOOST_CHECK(!ToIntegral<T>("-+1")); 671 BOOST_CHECK(!ToIntegral<T>("++1")); 672 BOOST_CHECK(!ToIntegral<T>("--1")); 673 BOOST_CHECK(!ToIntegral<T>("")); 674 BOOST_CHECK(!ToIntegral<T>("aap")); 675 BOOST_CHECK(!ToIntegral<T>("0x1")); 676 BOOST_CHECK(!ToIntegral<T>("-32482348723847471234")); 677 BOOST_CHECK(!ToIntegral<T>("32482348723847471234")); 678 } 679 680 BOOST_AUTO_TEST_CASE(test_ToIntegral) 681 { 682 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("1234").value(), 1'234); 683 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("0").value(), 0); 684 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("01234").value(), 1'234); 685 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000001234").value(), 1'234); 686 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000001234").value(), -1'234); 687 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000000000").value(), 0); 688 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000000000").value(), 0); 689 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1234").value(), -1'234); 690 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1").value(), -1); 691 692 RunToIntegralTests<uint64_t>(); 693 RunToIntegralTests<int64_t>(); 694 RunToIntegralTests<uint32_t>(); 695 RunToIntegralTests<int32_t>(); 696 RunToIntegralTests<uint16_t>(); 697 RunToIntegralTests<int16_t>(); 698 RunToIntegralTests<uint8_t>(); 699 RunToIntegralTests<int8_t>(); 700 701 BOOST_CHECK(!ToIntegral<int64_t>("-9223372036854775809")); 702 BOOST_CHECK_EQUAL(ToIntegral<int64_t>("-9223372036854775808").value(), -9'223'372'036'854'775'807LL - 1LL); 703 BOOST_CHECK_EQUAL(ToIntegral<int64_t>("9223372036854775807").value(), 9'223'372'036'854'775'807); 704 BOOST_CHECK(!ToIntegral<int64_t>("9223372036854775808")); 705 706 BOOST_CHECK(!ToIntegral<uint64_t>("-1")); 707 BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("0").value(), 0U); 708 BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("18446744073709551615").value(), 18'446'744'073'709'551'615ULL); 709 BOOST_CHECK(!ToIntegral<uint64_t>("18446744073709551616")); 710 711 BOOST_CHECK(!ToIntegral<int32_t>("-2147483649")); 712 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-2147483648").value(), -2'147'483'648LL); 713 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("2147483647").value(), 2'147'483'647); 714 BOOST_CHECK(!ToIntegral<int32_t>("2147483648")); 715 716 BOOST_CHECK(!ToIntegral<uint32_t>("-1")); 717 BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("0").value(), 0U); 718 BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("4294967295").value(), 4'294'967'295U); 719 BOOST_CHECK(!ToIntegral<uint32_t>("4294967296")); 720 721 BOOST_CHECK(!ToIntegral<int16_t>("-32769")); 722 BOOST_CHECK_EQUAL(ToIntegral<int16_t>("-32768").value(), -32'768); 723 BOOST_CHECK_EQUAL(ToIntegral<int16_t>("32767").value(), 32'767); 724 BOOST_CHECK(!ToIntegral<int16_t>("32768")); 725 726 BOOST_CHECK(!ToIntegral<uint16_t>("-1")); 727 BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("0").value(), 0U); 728 BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("65535").value(), 65'535U); 729 BOOST_CHECK(!ToIntegral<uint16_t>("65536")); 730 731 BOOST_CHECK(!ToIntegral<int8_t>("-129")); 732 BOOST_CHECK_EQUAL(ToIntegral<int8_t>("-128").value(), -128); 733 BOOST_CHECK_EQUAL(ToIntegral<int8_t>("127").value(), 127); 734 BOOST_CHECK(!ToIntegral<int8_t>("128")); 735 736 BOOST_CHECK(!ToIntegral<uint8_t>("-1")); 737 BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("0").value(), 0U); 738 BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("255").value(), 255U); 739 BOOST_CHECK(!ToIntegral<uint8_t>("256")); 740 } 741 742 int64_t atoi64_legacy(const std::string& str) 743 { 744 return strtoll(str.c_str(), nullptr, 10); 745 } 746 747 BOOST_AUTO_TEST_CASE(test_LocaleIndependentAtoi) 748 { 749 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1234"), 1'234); 750 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0"), 0); 751 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("01234"), 1'234); 752 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1234"), -1'234); 753 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" 1"), 1); 754 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1 "), 1); 755 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1a"), 1); 756 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.1"), 1); 757 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.9"), 1); 758 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+01.9"), 1); 759 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1"), -1); 760 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1"), -1); 761 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1 "), -1); 762 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1 "), -1); 763 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+1"), 1); 764 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1"), 1); 765 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1 "), 1); 766 767 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+-1"), 0); 768 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-+1"), 0); 769 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("++1"), 0); 770 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("--1"), 0); 771 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(""), 0); 772 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("aap"), 0); 773 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0x1"), 0); 774 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-32482348723847471234"), -2'147'483'647 - 1); 775 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("32482348723847471234"), 2'147'483'647); 776 777 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775809"), -9'223'372'036'854'775'807LL - 1LL); 778 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775808"), -9'223'372'036'854'775'807LL - 1LL); 779 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775807"), 9'223'372'036'854'775'807); 780 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775808"), 9'223'372'036'854'775'807); 781 782 std::map<std::string, int64_t> atoi64_test_pairs = { 783 {"-9223372036854775809", std::numeric_limits<int64_t>::min()}, 784 {"-9223372036854775808", -9'223'372'036'854'775'807LL - 1LL}, 785 {"9223372036854775807", 9'223'372'036'854'775'807}, 786 {"9223372036854775808", std::numeric_limits<int64_t>::max()}, 787 {"+-", 0}, 788 {"0x1", 0}, 789 {"ox1", 0}, 790 {"", 0}, 791 }; 792 793 for (const auto& pair : atoi64_test_pairs) { 794 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), pair.second); 795 } 796 797 // Ensure legacy compatibility with previous versions of Bitcoin Core's atoi64 798 for (const auto& pair : atoi64_test_pairs) { 799 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), atoi64_legacy(pair.first)); 800 } 801 802 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("-1"), 0U); 803 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("0"), 0U); 804 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551615"), 18'446'744'073'709'551'615ULL); 805 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551616"), 18'446'744'073'709'551'615ULL); 806 807 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483649"), -2'147'483'648LL); 808 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483648"), -2'147'483'648LL); 809 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483647"), 2'147'483'647); 810 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483648"), 2'147'483'647); 811 812 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("-1"), 0U); 813 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("0"), 0U); 814 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967295"), 4'294'967'295U); 815 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967296"), 4'294'967'295U); 816 817 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32769"), -32'768); 818 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32768"), -32'768); 819 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32767"), 32'767); 820 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32768"), 32'767); 821 822 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("-1"), 0U); 823 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("0"), 0U); 824 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65535"), 65'535U); 825 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65536"), 65'535U); 826 827 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-129"), -128); 828 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-128"), -128); 829 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("127"), 127); 830 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("128"), 127); 831 832 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("-1"), 0U); 833 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("0"), 0U); 834 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("255"), 255U); 835 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("256"), 255U); 836 } 837 838 BOOST_AUTO_TEST_CASE(test_FormatParagraph) 839 { 840 BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), ""); 841 BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test"); 842 BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test"); 843 BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test"); 844 BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest"); 845 BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest"); 846 BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test"); 847 848 // Make sure we don't indent a fully-new line following a too-long line ending 849 BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n test\nabc"); 850 851 BOOST_CHECK_EQUAL(FormatParagraph("This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length until it gets here", 79), "This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length\nuntil it gets here"); 852 853 // Test wrap length is exact 854 BOOST_CHECK_EQUAL(FormatParagraph("a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p"); 855 BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p"); 856 // Indent should be included in length of lines 857 BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg h i j k", 79, 4), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\n f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg\n h i j k"); 858 859 BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string.", 79), "This is a very long test string. This is a second sentence in the very long\ntest string."); 860 BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string."); 861 BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string."); 862 BOOST_CHECK_EQUAL(FormatParagraph("Testing that normal newlines do not get indented.\nLike here.", 79), "Testing that normal newlines do not get indented.\nLike here."); 863 } 864 865 BOOST_AUTO_TEST_CASE(test_FormatSubVersion) 866 { 867 std::vector<std::string> comments; 868 comments.emplace_back("comment1"); 869 std::vector<std::string> comments2; 870 comments2.emplace_back("comment1"); 871 comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014 872 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:9.99.0/")); 873 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:9.99.0(comment1)/")); 874 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:9.99.0(comment1; Comment2; .,_?@-; )/")); 875 } 876 877 BOOST_AUTO_TEST_CASE(test_ParseFixedPoint) 878 { 879 int64_t amount = 0; 880 BOOST_CHECK(ParseFixedPoint("0", 8, &amount)); 881 BOOST_CHECK_EQUAL(amount, 0LL); 882 BOOST_CHECK(ParseFixedPoint("1", 8, &amount)); 883 BOOST_CHECK_EQUAL(amount, 100000000LL); 884 BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount)); 885 BOOST_CHECK_EQUAL(amount, 0LL); 886 BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount)); 887 BOOST_CHECK_EQUAL(amount, -10000000LL); 888 BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount)); 889 BOOST_CHECK_EQUAL(amount, 110000000LL); 890 BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount)); 891 BOOST_CHECK_EQUAL(amount, 110000000LL); 892 BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount)); 893 BOOST_CHECK_EQUAL(amount, 1100000000LL); 894 BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount)); 895 BOOST_CHECK_EQUAL(amount, 11000000LL); 896 BOOST_CHECK(ParseFixedPoint("1000", 8, &amount)); 897 BOOST_CHECK_EQUAL(amount, 100000000000LL); 898 BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount)); 899 BOOST_CHECK_EQUAL(amount, -100000000000LL); 900 BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount)); 901 BOOST_CHECK_EQUAL(amount, 1LL); 902 BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount)); 903 BOOST_CHECK_EQUAL(amount, 1LL); 904 BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount)); 905 BOOST_CHECK_EQUAL(amount, -1LL); 906 BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount)); 907 BOOST_CHECK_EQUAL(amount, 100000000000000001LL); 908 BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount)); 909 BOOST_CHECK_EQUAL(amount, 999999999999999999LL); 910 BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount)); 911 BOOST_CHECK_EQUAL(amount, -999999999999999999LL); 912 913 BOOST_CHECK(!ParseFixedPoint("", 8, &amount)); 914 BOOST_CHECK(!ParseFixedPoint("-", 8, &amount)); 915 BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount)); 916 BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount)); 917 BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount)); 918 BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount)); 919 BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount)); 920 BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount)); 921 BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount)); 922 BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount)); 923 BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount)); 924 BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount)); 925 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount)); 926 BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount)); 927 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount)); 928 BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount)); 929 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount)); 930 BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount)); 931 BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount)); 932 BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount)); 933 BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount)); 934 BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount)); 935 BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount)); 936 BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount)); 937 BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount)); 938 BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount)); 939 BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount)); 940 941 // Test with 3 decimal places for fee rates in sat/vB. 942 BOOST_CHECK(ParseFixedPoint("0.001", 3, &amount)); 943 BOOST_CHECK_EQUAL(amount, CAmount{1}); 944 BOOST_CHECK(!ParseFixedPoint("0.0009", 3, &amount)); 945 BOOST_CHECK(!ParseFixedPoint("31.00100001", 3, &amount)); 946 BOOST_CHECK(!ParseFixedPoint("31.0011", 3, &amount)); 947 BOOST_CHECK(!ParseFixedPoint("31.99999999", 3, &amount)); 948 BOOST_CHECK(!ParseFixedPoint("31.999999999999999999999", 3, &amount)); 949 } 950 951 #ifndef WIN32 // Cannot do this test on WIN32 due to lack of fork() 952 static constexpr char LockCommand = 'L'; 953 static constexpr char UnlockCommand = 'U'; 954 static constexpr char ExitCommand = 'X'; 955 enum : char { 956 ResSuccess = 2, // Start with 2 to avoid accidental collision with common values 0 and 1 957 ResErrorWrite, 958 ResErrorLock, 959 ResUnlockSuccess, 960 }; 961 962 [[noreturn]] static void TestOtherProcess(fs::path dirname, fs::path lockname, int fd) 963 { 964 char ch; 965 while (true) { 966 int rv = read(fd, &ch, 1); // Wait for command 967 assert(rv == 1); 968 switch (ch) { 969 case LockCommand: 970 ch = [&] { 971 switch (util::LockDirectory(dirname, lockname)) { 972 case util::LockResult::Success: return ResSuccess; 973 case util::LockResult::ErrorWrite: return ResErrorWrite; 974 case util::LockResult::ErrorLock: return ResErrorLock; 975 } // no default case, so the compiler can warn about missing cases 976 assert(false); 977 }(); 978 rv = write(fd, &ch, 1); 979 assert(rv == 1); 980 break; 981 case UnlockCommand: 982 ReleaseDirectoryLocks(); 983 ch = ResUnlockSuccess; // Always succeeds 984 rv = write(fd, &ch, 1); 985 assert(rv == 1); 986 break; 987 case ExitCommand: 988 close(fd); 989 exit(0); 990 default: 991 assert(0); 992 } 993 } 994 } 995 #endif 996 997 BOOST_AUTO_TEST_CASE(test_LockDirectory) 998 { 999 fs::path dirname = m_args.GetDataDirBase() / "lock_dir"; 1000 const fs::path lockname = ".lock"; 1001 #ifndef WIN32 1002 // Fork another process for testing before creating the lock, so that we 1003 // won't fork while holding the lock (which might be undefined, and is not 1004 // relevant as test case as that is avoided with -daemonize). 1005 int fd[2]; 1006 BOOST_CHECK_EQUAL(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0); 1007 pid_t pid = fork(); 1008 if (!pid) { 1009 BOOST_CHECK_EQUAL(close(fd[1]), 0); // Child: close parent end 1010 TestOtherProcess(dirname, lockname, fd[0]); 1011 } 1012 BOOST_CHECK_EQUAL(close(fd[0]), 0); // Parent: close child end 1013 1014 char ch; 1015 // Lock on non-existent directory should fail 1016 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); 1017 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); 1018 BOOST_CHECK_EQUAL(ch, ResErrorWrite); 1019 #endif 1020 // Lock on non-existent directory should fail 1021 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname), util::LockResult::ErrorWrite); 1022 1023 fs::create_directories(dirname); 1024 1025 // Probing lock on new directory should succeed 1026 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success); 1027 1028 // Persistent lock on new directory should succeed 1029 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname), util::LockResult::Success); 1030 1031 // Another lock on the directory from the same thread should succeed 1032 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname), util::LockResult::Success); 1033 1034 // Another lock on the directory from a different thread within the same process should succeed 1035 util::LockResult threadresult; 1036 std::thread thr([&] { threadresult = util::LockDirectory(dirname, lockname); }); 1037 thr.join(); 1038 BOOST_CHECK_EQUAL(threadresult, util::LockResult::Success); 1039 #ifndef WIN32 1040 // Try to acquire lock in child process while we're holding it, this should fail. 1041 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); 1042 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); 1043 BOOST_CHECK_EQUAL(ch, ResErrorLock); 1044 1045 // Give up our lock 1046 ReleaseDirectoryLocks(); 1047 // Probing lock from our side now should succeed, but not hold on to the lock. 1048 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success); 1049 1050 // Try to acquire the lock in the child process, this should be successful. 1051 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); 1052 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); 1053 BOOST_CHECK_EQUAL(ch, ResSuccess); 1054 1055 // When we try to probe the lock now, it should fail. 1056 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::ErrorLock); 1057 1058 // Unlock the lock in the child process 1059 BOOST_CHECK_EQUAL(write(fd[1], &UnlockCommand, 1), 1); 1060 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); 1061 BOOST_CHECK_EQUAL(ch, ResUnlockSuccess); 1062 1063 // When we try to probe the lock now, it should succeed. 1064 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success); 1065 1066 // Re-lock the lock in the child process, then wait for it to exit, check 1067 // successful return. After that, we check that exiting the process 1068 // has released the lock as we would expect by probing it. 1069 int processstatus; 1070 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); 1071 // The following line invokes the ~CNetCleanup dtor without 1072 // a paired SetupNetworking call. This is acceptable as long as 1073 // ~CNetCleanup is a no-op for non-Windows platforms. 1074 BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1); 1075 BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid); 1076 BOOST_CHECK_EQUAL(processstatus, 0); 1077 BOOST_CHECK_EQUAL(util::LockDirectory(dirname, lockname, true), util::LockResult::Success); 1078 1079 BOOST_CHECK_EQUAL(close(fd[1]), 0); // Close our side of the socketpair 1080 #endif 1081 // Clean up 1082 ReleaseDirectoryLocks(); 1083 fs::remove_all(dirname); 1084 } 1085 1086 BOOST_AUTO_TEST_CASE(test_ToLower) 1087 { 1088 BOOST_CHECK_EQUAL(ToLower('@'), '@'); 1089 BOOST_CHECK_EQUAL(ToLower('A'), 'a'); 1090 BOOST_CHECK_EQUAL(ToLower('Z'), 'z'); 1091 BOOST_CHECK_EQUAL(ToLower('['), '['); 1092 BOOST_CHECK_EQUAL(ToLower(0), 0); 1093 BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff'); 1094 1095 BOOST_CHECK_EQUAL(ToLower(""), ""); 1096 BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl"); 1097 BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff"); 1098 } 1099 1100 BOOST_AUTO_TEST_CASE(test_ToUpper) 1101 { 1102 BOOST_CHECK_EQUAL(ToUpper('`'), '`'); 1103 BOOST_CHECK_EQUAL(ToUpper('a'), 'A'); 1104 BOOST_CHECK_EQUAL(ToUpper('z'), 'Z'); 1105 BOOST_CHECK_EQUAL(ToUpper('{'), '{'); 1106 BOOST_CHECK_EQUAL(ToUpper(0), 0); 1107 BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff'); 1108 1109 BOOST_CHECK_EQUAL(ToUpper(""), ""); 1110 BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL"); 1111 BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff"); 1112 } 1113 1114 BOOST_AUTO_TEST_CASE(test_Capitalize) 1115 { 1116 BOOST_CHECK_EQUAL(Capitalize(""), ""); 1117 BOOST_CHECK_EQUAL(Capitalize("bitcoin"), "Bitcoin"); 1118 BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff"); 1119 } 1120 1121 static std::string SpanToStr(const std::span<const char>& span) 1122 { 1123 return std::string(span.begin(), span.end()); 1124 } 1125 1126 BOOST_AUTO_TEST_CASE(test_script_parsing) 1127 { 1128 using namespace script; 1129 std::string input; 1130 std::span<const char> sp; 1131 bool success; 1132 1133 // Const(...): parse a constant, update span to skip it if successful 1134 input = "MilkToastHoney"; 1135 sp = input; 1136 success = Const("", sp); // empty 1137 BOOST_CHECK(success); 1138 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney"); 1139 1140 success = Const("Milk", sp, /*skip=*/false); 1141 BOOST_CHECK(success); 1142 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney"); 1143 1144 success = Const("Milk", sp); 1145 BOOST_CHECK(success); 1146 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney"); 1147 1148 success = Const("Bread", sp, /*skip=*/false); 1149 BOOST_CHECK(!success); 1150 1151 success = Const("Bread", sp); 1152 BOOST_CHECK(!success); 1153 1154 success = Const("Toast", sp, /*skip=*/false); 1155 BOOST_CHECK(success); 1156 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney"); 1157 1158 success = Const("Toast", sp); 1159 BOOST_CHECK(success); 1160 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey"); 1161 1162 success = Const("Honeybadger", sp); 1163 BOOST_CHECK(!success); 1164 1165 success = Const("Honey", sp, /*skip=*/false); 1166 BOOST_CHECK(success); 1167 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey"); 1168 1169 success = Const("Honey", sp); 1170 BOOST_CHECK(success); 1171 BOOST_CHECK_EQUAL(SpanToStr(sp), ""); 1172 // Func(...): parse a function call, update span to argument if successful 1173 input = "Foo(Bar(xy,z()))"; 1174 sp = input; 1175 1176 success = Func("FooBar", sp); 1177 BOOST_CHECK(!success); 1178 1179 success = Func("Foo(", sp); 1180 BOOST_CHECK(!success); 1181 1182 success = Func("Foo", sp); 1183 BOOST_CHECK(success); 1184 BOOST_CHECK_EQUAL(SpanToStr(sp), "Bar(xy,z())"); 1185 1186 success = Func("Bar", sp); 1187 BOOST_CHECK(success); 1188 BOOST_CHECK_EQUAL(SpanToStr(sp), "xy,z()"); 1189 1190 success = Func("xy", sp); 1191 BOOST_CHECK(!success); 1192 1193 // Expr(...): return expression that span begins with, update span to skip it 1194 std::span<const char> result; 1195 1196 input = "(n*(n-1))/2"; 1197 sp = input; 1198 result = Expr(sp); 1199 BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2"); 1200 BOOST_CHECK_EQUAL(SpanToStr(sp), ""); 1201 1202 input = "foo,bar"; 1203 sp = input; 1204 result = Expr(sp); 1205 BOOST_CHECK_EQUAL(SpanToStr(result), "foo"); 1206 BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar"); 1207 1208 input = "(aaaaa,bbbbb()),c"; 1209 sp = input; 1210 result = Expr(sp); 1211 BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())"); 1212 BOOST_CHECK_EQUAL(SpanToStr(sp), ",c"); 1213 1214 input = "xyz)foo"; 1215 sp = input; 1216 result = Expr(sp); 1217 BOOST_CHECK_EQUAL(SpanToStr(result), "xyz"); 1218 BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo"); 1219 1220 input = "((a),(b),(c)),xxx"; 1221 sp = input; 1222 result = Expr(sp); 1223 BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))"); 1224 BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx"); 1225 1226 // Split(...): split a string on every instance of sep, return vector 1227 std::vector<std::span<const char>> results; 1228 1229 input = "xxx"; 1230 results = Split(input, 'x'); 1231 BOOST_CHECK_EQUAL(results.size(), 4U); 1232 BOOST_CHECK_EQUAL(SpanToStr(results[0]), ""); 1233 BOOST_CHECK_EQUAL(SpanToStr(results[1]), ""); 1234 BOOST_CHECK_EQUAL(SpanToStr(results[2]), ""); 1235 BOOST_CHECK_EQUAL(SpanToStr(results[3]), ""); 1236 1237 input = "one#two#three"; 1238 results = Split(input, '-'); 1239 BOOST_CHECK_EQUAL(results.size(), 1U); 1240 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three"); 1241 1242 input = "one#two#three"; 1243 results = Split(input, '#'); 1244 BOOST_CHECK_EQUAL(results.size(), 3U); 1245 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one"); 1246 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two"); 1247 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three"); 1248 1249 results = Split(input, '#', /*include_sep=*/true); 1250 BOOST_CHECK_EQUAL(results.size(), 3U); 1251 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#"); 1252 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two#"); 1253 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three"); 1254 1255 input = "*foo*bar*"; 1256 results = Split(input, '*'); 1257 BOOST_CHECK_EQUAL(results.size(), 4U); 1258 BOOST_CHECK_EQUAL(SpanToStr(results[0]), ""); 1259 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo"); 1260 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar"); 1261 BOOST_CHECK_EQUAL(SpanToStr(results[3]), ""); 1262 1263 results = Split(input, '*', /*include_sep=*/true); 1264 BOOST_CHECK_EQUAL(results.size(), 4U); 1265 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "*"); 1266 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo*"); 1267 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar*"); 1268 BOOST_CHECK_EQUAL(SpanToStr(results[3]), ""); 1269 } 1270 1271 BOOST_AUTO_TEST_CASE(test_SplitString) 1272 { 1273 // Empty string. 1274 { 1275 std::vector<std::string> result = SplitString("", '-'); 1276 BOOST_CHECK_EQUAL(result.size(), 1); 1277 BOOST_CHECK_EQUAL(result[0], ""); 1278 } 1279 1280 // Empty items. 1281 { 1282 std::vector<std::string> result = SplitString("-", '-'); 1283 BOOST_CHECK_EQUAL(result.size(), 2); 1284 BOOST_CHECK_EQUAL(result[0], ""); 1285 BOOST_CHECK_EQUAL(result[1], ""); 1286 } 1287 1288 // More empty items. 1289 { 1290 std::vector<std::string> result = SplitString("--", '-'); 1291 BOOST_CHECK_EQUAL(result.size(), 3); 1292 BOOST_CHECK_EQUAL(result[0], ""); 1293 BOOST_CHECK_EQUAL(result[1], ""); 1294 BOOST_CHECK_EQUAL(result[2], ""); 1295 } 1296 1297 // Separator is not present. 1298 { 1299 std::vector<std::string> result = SplitString("abc", '-'); 1300 BOOST_CHECK_EQUAL(result.size(), 1); 1301 BOOST_CHECK_EQUAL(result[0], "abc"); 1302 } 1303 1304 // Basic behavior. 1305 { 1306 std::vector<std::string> result = SplitString("a-b", '-'); 1307 BOOST_CHECK_EQUAL(result.size(), 2); 1308 BOOST_CHECK_EQUAL(result[0], "a"); 1309 BOOST_CHECK_EQUAL(result[1], "b"); 1310 } 1311 1312 // Case-sensitivity of the separator. 1313 { 1314 std::vector<std::string> result = SplitString("AAA", 'a'); 1315 BOOST_CHECK_EQUAL(result.size(), 1); 1316 BOOST_CHECK_EQUAL(result[0], "AAA"); 1317 } 1318 1319 // multiple split characters 1320 { 1321 using V = std::vector<std::string>; 1322 BOOST_TEST(SplitString("a,b.c:d;e", ",;") == V({"a", "b.c:d", "e"})); 1323 BOOST_TEST(SplitString("a,b.c:d;e", ",;:.") == V({"a", "b", "c", "d", "e"})); 1324 BOOST_TEST(SplitString("a,b.c:d;e", "") == V({"a,b.c:d;e"})); 1325 BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"})); 1326 BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"})); 1327 BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"})); 1328 BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"})); 1329 BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"})); 1330 } 1331 } 1332 1333 BOOST_AUTO_TEST_CASE(test_LogEscapeMessage) 1334 { 1335 // ASCII and UTF-8 must pass through unaltered. 1336 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓"); 1337 // Newlines must pass through unaltered. 1338 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n"); 1339 // Other control characters are escaped in C syntax. 1340 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)"); 1341 // Embedded NULL characters are escaped too. 1342 const std::string NUL("O\x00O", 3); 1343 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)"); 1344 } 1345 1346 namespace { 1347 1348 struct Tracker 1349 { 1350 //! Points to the original object (possibly itself) we moved/copied from 1351 const Tracker* origin; 1352 //! How many copies where involved between the original object and this one (moves are not counted) 1353 int copies{0}; 1354 1355 Tracker() noexcept : origin(this) {} 1356 Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {} 1357 Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {} 1358 Tracker& operator=(const Tracker& t) noexcept 1359 { 1360 if (this != &t) { 1361 origin = t.origin; 1362 copies = t.copies + 1; 1363 } 1364 return *this; 1365 } 1366 }; 1367 1368 } 1369 1370 BOOST_AUTO_TEST_CASE(test_tracked_vector) 1371 { 1372 Tracker t1; 1373 Tracker t2; 1374 Tracker t3; 1375 1376 BOOST_CHECK(t1.origin == &t1); 1377 BOOST_CHECK(t2.origin == &t2); 1378 BOOST_CHECK(t3.origin == &t3); 1379 1380 auto v1 = Vector(t1); 1381 BOOST_CHECK_EQUAL(v1.size(), 1U); 1382 BOOST_CHECK(v1[0].origin == &t1); 1383 BOOST_CHECK_EQUAL(v1[0].copies, 1); 1384 1385 auto v2 = Vector(std::move(t2)); 1386 BOOST_CHECK_EQUAL(v2.size(), 1U); 1387 BOOST_CHECK(v2[0].origin == &t2); // NOLINT(*-use-after-move) 1388 BOOST_CHECK_EQUAL(v2[0].copies, 0); 1389 1390 auto v3 = Vector(t1, std::move(t2)); 1391 BOOST_CHECK_EQUAL(v3.size(), 2U); 1392 BOOST_CHECK(v3[0].origin == &t1); 1393 BOOST_CHECK(v3[1].origin == &t2); // NOLINT(*-use-after-move) 1394 BOOST_CHECK_EQUAL(v3[0].copies, 1); 1395 BOOST_CHECK_EQUAL(v3[1].copies, 0); 1396 1397 auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3)); 1398 BOOST_CHECK_EQUAL(v4.size(), 3U); 1399 BOOST_CHECK(v4[0].origin == &t1); 1400 BOOST_CHECK(v4[1].origin == &t2); 1401 BOOST_CHECK(v4[2].origin == &t3); // NOLINT(*-use-after-move) 1402 BOOST_CHECK_EQUAL(v4[0].copies, 1); 1403 BOOST_CHECK_EQUAL(v4[1].copies, 1); 1404 BOOST_CHECK_EQUAL(v4[2].copies, 0); 1405 1406 auto v5 = Cat(v1, v4); 1407 BOOST_CHECK_EQUAL(v5.size(), 4U); 1408 BOOST_CHECK(v5[0].origin == &t1); 1409 BOOST_CHECK(v5[1].origin == &t1); 1410 BOOST_CHECK(v5[2].origin == &t2); 1411 BOOST_CHECK(v5[3].origin == &t3); 1412 BOOST_CHECK_EQUAL(v5[0].copies, 2); 1413 BOOST_CHECK_EQUAL(v5[1].copies, 2); 1414 BOOST_CHECK_EQUAL(v5[2].copies, 2); 1415 BOOST_CHECK_EQUAL(v5[3].copies, 1); 1416 1417 auto v6 = Cat(std::move(v1), v3); 1418 BOOST_CHECK_EQUAL(v6.size(), 3U); 1419 BOOST_CHECK(v6[0].origin == &t1); 1420 BOOST_CHECK(v6[1].origin == &t1); 1421 BOOST_CHECK(v6[2].origin == &t2); 1422 BOOST_CHECK_EQUAL(v6[0].copies, 1); 1423 BOOST_CHECK_EQUAL(v6[1].copies, 2); 1424 BOOST_CHECK_EQUAL(v6[2].copies, 1); 1425 1426 auto v7 = Cat(v2, std::move(v4)); 1427 BOOST_CHECK_EQUAL(v7.size(), 4U); 1428 BOOST_CHECK(v7[0].origin == &t2); 1429 BOOST_CHECK(v7[1].origin == &t1); 1430 BOOST_CHECK(v7[2].origin == &t2); 1431 BOOST_CHECK(v7[3].origin == &t3); 1432 BOOST_CHECK_EQUAL(v7[0].copies, 1); 1433 BOOST_CHECK_EQUAL(v7[1].copies, 1); 1434 BOOST_CHECK_EQUAL(v7[2].copies, 1); 1435 BOOST_CHECK_EQUAL(v7[3].copies, 0); 1436 1437 auto v8 = Cat(std::move(v2), std::move(v3)); 1438 BOOST_CHECK_EQUAL(v8.size(), 3U); 1439 BOOST_CHECK(v8[0].origin == &t2); 1440 BOOST_CHECK(v8[1].origin == &t1); 1441 BOOST_CHECK(v8[2].origin == &t2); 1442 BOOST_CHECK_EQUAL(v8[0].copies, 0); 1443 BOOST_CHECK_EQUAL(v8[1].copies, 1); 1444 BOOST_CHECK_EQUAL(v8[2].copies, 0); 1445 } 1446 1447 BOOST_AUTO_TEST_CASE(message_sign) 1448 { 1449 const std::array<unsigned char, 32> privkey_bytes = { 1450 // just some random data 1451 // derived address from this private key: 15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs 1452 0xD9, 0x7F, 0x51, 0x08, 0xF1, 0x1C, 0xDA, 0x6E, 1453 0xEE, 0xBA, 0xAA, 0x42, 0x0F, 0xEF, 0x07, 0x26, 1454 0xB1, 0xF8, 0x98, 0x06, 0x0B, 0x98, 0x48, 0x9F, 1455 0xA3, 0x09, 0x84, 0x63, 0xC0, 0x03, 0x28, 0x66 1456 }; 1457 1458 const std::string message = "Trust no one"; 1459 1460 const std::string expected_signature = 1461 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk="; 1462 1463 CKey privkey; 1464 std::string generated_signature; 1465 1466 BOOST_REQUIRE_MESSAGE(!privkey.IsValid(), 1467 "Confirm the private key is invalid"); 1468 1469 BOOST_CHECK_MESSAGE(!MessageSign(privkey, message, generated_signature), 1470 "Sign with an invalid private key"); 1471 1472 privkey.Set(privkey_bytes.begin(), privkey_bytes.end(), true); 1473 1474 BOOST_REQUIRE_MESSAGE(privkey.IsValid(), 1475 "Confirm the private key is valid"); 1476 1477 BOOST_CHECK_MESSAGE(MessageSign(privkey, message, generated_signature), 1478 "Sign with a valid private key"); 1479 1480 BOOST_CHECK_EQUAL(expected_signature, generated_signature); 1481 } 1482 1483 BOOST_AUTO_TEST_CASE(message_verify) 1484 { 1485 BOOST_CHECK_EQUAL( 1486 MessageVerify( 1487 "invalid address", 1488 "signature should be irrelevant", 1489 "message too"), 1490 MessageVerificationResult::ERR_INVALID_ADDRESS); 1491 1492 BOOST_CHECK_EQUAL( 1493 MessageVerify( 1494 "3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV", 1495 "signature should be irrelevant", 1496 "message too"), 1497 MessageVerificationResult::ERR_ADDRESS_NO_KEY); 1498 1499 BOOST_CHECK_EQUAL( 1500 MessageVerify( 1501 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm", 1502 "invalid signature, not in base64 encoding", 1503 "message should be irrelevant"), 1504 MessageVerificationResult::ERR_MALFORMED_SIGNATURE); 1505 1506 BOOST_CHECK_EQUAL( 1507 MessageVerify( 1508 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm", 1509 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", 1510 "message should be irrelevant"), 1511 MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED); 1512 1513 BOOST_CHECK_EQUAL( 1514 MessageVerify( 1515 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs", 1516 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=", 1517 "I never signed this"), 1518 MessageVerificationResult::ERR_NOT_SIGNED); 1519 1520 BOOST_CHECK_EQUAL( 1521 MessageVerify( 1522 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs", 1523 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=", 1524 "Trust no one"), 1525 MessageVerificationResult::OK); 1526 1527 BOOST_CHECK_EQUAL( 1528 MessageVerify( 1529 "11canuhp9X2NocwCq7xNrQYTmUgZAnLK3", 1530 "IIcaIENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzIAaHRtbCeDZINyavx14=", 1531 "Trust me"), 1532 MessageVerificationResult::OK); 1533 } 1534 1535 BOOST_AUTO_TEST_CASE(message_hash) 1536 { 1537 const std::string unsigned_tx = "..."; 1538 const std::string prefixed_message = 1539 std::string(1, (char)MESSAGE_MAGIC.length()) + 1540 MESSAGE_MAGIC + 1541 std::string(1, (char)unsigned_tx.length()) + 1542 unsigned_tx; 1543 1544 const uint256 signature_hash = Hash(unsigned_tx); 1545 const uint256 message_hash1 = Hash(prefixed_message); 1546 const uint256 message_hash2 = MessageHash(unsigned_tx); 1547 1548 BOOST_CHECK_EQUAL(message_hash1, message_hash2); 1549 BOOST_CHECK_NE(message_hash1, signature_hash); 1550 } 1551 1552 BOOST_AUTO_TEST_CASE(remove_prefix) 1553 { 1554 BOOST_CHECK_EQUAL(RemovePrefix("./common/system.h", "./"), "common/system.h"); 1555 BOOST_CHECK_EQUAL(RemovePrefixView("foo", "foo"), ""); 1556 BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o"); 1557 BOOST_CHECK_EQUAL(RemovePrefixView("foo", "f"), "oo"); 1558 BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo"); 1559 BOOST_CHECK_EQUAL(RemovePrefixView("fo", "foo"), "fo"); 1560 BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f"); 1561 BOOST_CHECK_EQUAL(RemovePrefixView("", "foo"), ""); 1562 BOOST_CHECK_EQUAL(RemovePrefix("", ""), ""); 1563 } 1564 1565 BOOST_AUTO_TEST_CASE(util_ParseByteUnits) 1566 { 1567 auto noop = ByteUnit::NOOP; 1568 1569 // no multiplier 1570 BOOST_CHECK_EQUAL(ParseByteUnits("1", noop).value(), 1); 1571 BOOST_CHECK_EQUAL(ParseByteUnits("0", noop).value(), 0); 1572 1573 BOOST_CHECK_EQUAL(ParseByteUnits("1k", noop).value(), 1000ULL); 1574 BOOST_CHECK_EQUAL(ParseByteUnits("1K", noop).value(), 1ULL << 10); 1575 1576 BOOST_CHECK_EQUAL(ParseByteUnits("2m", noop).value(), 2'000'000ULL); 1577 BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2ULL << 20); 1578 1579 BOOST_CHECK_EQUAL(ParseByteUnits("3g", noop).value(), 3'000'000'000ULL); 1580 BOOST_CHECK_EQUAL(ParseByteUnits("3G", noop).value(), 3ULL << 30); 1581 1582 BOOST_CHECK_EQUAL(ParseByteUnits("4t", noop).value(), 4'000'000'000'000ULL); 1583 BOOST_CHECK_EQUAL(ParseByteUnits("4T", noop).value(), 4ULL << 40); 1584 1585 // check default multiplier 1586 BOOST_CHECK_EQUAL(ParseByteUnits("5", ByteUnit::K).value(), 5ULL << 10); 1587 1588 // NaN 1589 BOOST_CHECK(!ParseByteUnits("", noop)); 1590 BOOST_CHECK(!ParseByteUnits("foo", noop)); 1591 1592 // whitespace 1593 BOOST_CHECK(!ParseByteUnits("123m ", noop)); 1594 BOOST_CHECK(!ParseByteUnits(" 123m", noop)); 1595 1596 // no +- 1597 BOOST_CHECK(!ParseByteUnits("-123m", noop)); 1598 BOOST_CHECK(!ParseByteUnits("+123m", noop)); 1599 1600 // zero padding 1601 BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20ULL << 20); 1602 1603 // fractions not allowed 1604 BOOST_CHECK(!ParseByteUnits("0.5T", noop)); 1605 1606 // overflow 1607 BOOST_CHECK(!ParseByteUnits("18446744073709551615g", noop)); 1608 1609 // invalid unit 1610 BOOST_CHECK(!ParseByteUnits("1x", noop)); 1611 } 1612 1613 BOOST_AUTO_TEST_CASE(util_ReadBinaryFile) 1614 { 1615 fs::path tmpfolder = m_args.GetDataDirBase(); 1616 fs::path tmpfile = tmpfolder / "read_binary.dat"; 1617 std::string expected_text; 1618 for (int i = 0; i < 30; i++) { 1619 expected_text += "0123456789"; 1620 } 1621 { 1622 std::ofstream file{tmpfile.std_path()}; 1623 file << expected_text; 1624 } 1625 { 1626 // read all contents in file 1627 auto [valid, text] = ReadBinaryFile(tmpfile); 1628 BOOST_CHECK(valid); 1629 BOOST_CHECK_EQUAL(text, expected_text); 1630 } 1631 { 1632 // read half contents in file 1633 auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2); 1634 BOOST_CHECK(valid); 1635 BOOST_CHECK_EQUAL(text, expected_text.substr(0, expected_text.size() / 2)); 1636 } 1637 { 1638 // read from non-existent file 1639 fs::path invalid_file = tmpfolder / "invalid_binary.dat"; 1640 auto [valid, text] = ReadBinaryFile(invalid_file); 1641 BOOST_CHECK(!valid); 1642 BOOST_CHECK(text.empty()); 1643 } 1644 } 1645 1646 BOOST_AUTO_TEST_CASE(util_WriteBinaryFile) 1647 { 1648 fs::path tmpfolder = m_args.GetDataDirBase(); 1649 fs::path tmpfile = tmpfolder / "write_binary.dat"; 1650 std::string expected_text = "bitcoin"; 1651 auto valid = WriteBinaryFile(tmpfile, expected_text); 1652 std::string actual_text; 1653 std::ifstream file{tmpfile.std_path()}; 1654 file >> actual_text; 1655 BOOST_CHECK(valid); 1656 BOOST_CHECK_EQUAL(actual_text, expected_text); 1657 } 1658 1659 BOOST_AUTO_TEST_CASE(clearshrink_test) 1660 { 1661 { 1662 std::vector<uint8_t> v = {1, 2, 3}; 1663 ClearShrink(v); 1664 BOOST_CHECK_EQUAL(v.size(), 0); 1665 BOOST_CHECK_EQUAL(v.capacity(), 0); 1666 } 1667 1668 { 1669 std::vector<bool> v = {false, true, false, false, true, true}; 1670 ClearShrink(v); 1671 BOOST_CHECK_EQUAL(v.size(), 0); 1672 BOOST_CHECK_EQUAL(v.capacity(), 0); 1673 } 1674 1675 { 1676 std::deque<int> v = {1, 3, 3, 7}; 1677 ClearShrink(v); 1678 BOOST_CHECK_EQUAL(v.size(), 0); 1679 // std::deque has no capacity() we can observe. 1680 } 1681 } 1682 1683 template <typename T> 1684 void TestCheckedLeftShift() 1685 { 1686 constexpr auto MAX{std::numeric_limits<T>::max()}; 1687 1688 // Basic operations 1689 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 1), 0); 1690 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 127), 0); 1691 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, 1), 2); 1692 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(2, 2), 8); 1693 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MAX >> 1, 1), MAX - 1); 1694 1695 // Max left shift 1696 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1); 1697 1698 // Overflow cases 1699 BOOST_CHECK(!CheckedLeftShift<T>((MAX >> 1) + 1, 1)); 1700 BOOST_CHECK(!CheckedLeftShift<T>(MAX, 1)); 1701 BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits)); 1702 BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits + 1)); 1703 1704 if constexpr (std::is_signed_v<T>) { 1705 constexpr auto MIN{std::numeric_limits<T>::min()}; 1706 // Negative input 1707 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(-1, 1), -2); 1708 BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 2), 1), MIN / 2); 1709 BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2); 1710 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MIN >> 1, 1), MIN); 1711 // Overflow negative 1712 BOOST_CHECK(!CheckedLeftShift<T>((MIN >> 1) - 1, 1)); 1713 BOOST_CHECK(!CheckedLeftShift<T>(MIN >> 1, 2)); 1714 BOOST_CHECK(!CheckedLeftShift<T>(-1, 100)); 1715 } 1716 } 1717 1718 template <typename T> 1719 void TestSaturatingLeftShift() 1720 { 1721 constexpr auto MAX{std::numeric_limits<T>::max()}; 1722 1723 // Basic operations 1724 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 1), 0); 1725 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 127), 0); 1726 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, 1), 2); 1727 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(2, 2), 8); 1728 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX >> 1, 1), MAX - 1); 1729 1730 // Max left shift 1731 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1); 1732 1733 // Saturation cases 1734 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MAX >> 1) + 1, 1), MAX); 1735 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX, 1), MAX); 1736 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits), MAX); 1737 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits + 1), MAX); 1738 1739 if constexpr (std::is_signed_v<T>) { 1740 constexpr auto MIN{std::numeric_limits<T>::min()}; 1741 // Negative input 1742 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 1), -2); 1743 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 2), 1), MIN / 2); 1744 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2); 1745 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 1), MIN); 1746 // Saturation negative 1747 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) - 1, 1), MIN); 1748 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 2), MIN); 1749 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 100), MIN); 1750 } 1751 } 1752 1753 BOOST_AUTO_TEST_CASE(checked_left_shift_test) 1754 { 1755 TestCheckedLeftShift<uint8_t>(); 1756 TestCheckedLeftShift<int8_t>(); 1757 TestCheckedLeftShift<size_t>(); 1758 TestCheckedLeftShift<uint64_t>(); 1759 TestCheckedLeftShift<int64_t>(); 1760 } 1761 1762 BOOST_AUTO_TEST_CASE(saturating_left_shift_test) 1763 { 1764 TestSaturatingLeftShift<uint8_t>(); 1765 TestSaturatingLeftShift<int8_t>(); 1766 TestSaturatingLeftShift<size_t>(); 1767 TestSaturatingLeftShift<uint64_t>(); 1768 TestSaturatingLeftShift<int64_t>(); 1769 } 1770 1771 BOOST_AUTO_TEST_CASE(mib_string_literal_test) 1772 { 1773 BOOST_CHECK_EQUAL(0_MiB, 0); 1774 BOOST_CHECK_EQUAL(1_MiB, 1024 * 1024); 1775 const auto max_mib{std::numeric_limits<size_t>::max() >> 20}; 1776 BOOST_CHECK_EXCEPTION(operator""_MiB(static_cast<unsigned long long>(max_mib) + 1), std::overflow_error, HasReason("MiB value too large for size_t byte conversion")); 1777 } 1778 1779 BOOST_AUTO_TEST_SUITE_END()