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