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