LCOV - code coverage report
Current view: top level - src/test - util_tests.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 0 1211 0.0 %
Date: 2023-10-05 12:38:51 Functions: 0 275 0.0 %
Branches: 0 0 -

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

Generated by: LCOV version 1.14