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