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