LCOV - code coverage report
Current view: top level - src/test - util_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 99.4 % 1374 1366
Test Date: 2026-09-03 06:37:27 Functions: 100.0 % 149 149
Branches: 50.1 % 8076 4048

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

Generated by: LCOV version 2.0-1