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