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