LCOV - code coverage report
Current view: top level - src/test - util_tests.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 1884 1923 98.0 %
Date: 2022-04-21 14:51:19 Functions: 111 113 98.2 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 125 146 85.6 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2011-2021 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 <util/system.h>
#       6                 :            : 
#       7                 :            : #include <clientversion.h>
#       8                 :            : #include <fs.h>
#       9                 :            : #include <hash.h> // For Hash()
#      10                 :            : #include <key.h>  // For CKey
#      11                 :            : #include <sync.h>
#      12                 :            : #include <test/util/logging.h>
#      13                 :            : #include <test/util/setup_common.h>
#      14                 :            : #include <test/util/str.h>
#      15                 :            : #include <uint256.h>
#      16                 :            : #include <util/getuniquepath.h>
#      17                 :            : #include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
#      18                 :            : #include <util/moneystr.h>
#      19                 :            : #include <util/overflow.h>
#      20                 :            : #include <util/readwritefile.h>
#      21                 :            : #include <util/spanparsing.h>
#      22                 :            : #include <util/strencodings.h>
#      23                 :            : #include <util/string.h>
#      24                 :            : #include <util/time.h>
#      25                 :            : #include <util/vector.h>
#      26                 :            : 
#      27                 :            : #include <array>
#      28                 :            : #include <fstream>
#      29                 :            : #include <limits>
#      30                 :            : #include <map>
#      31                 :            : #include <optional>
#      32                 :            : #include <stdint.h>
#      33                 :            : #include <string.h>
#      34                 :            : #include <thread>
#      35                 :            : #include <univalue.h>
#      36                 :            : #include <utility>
#      37                 :            : #include <vector>
#      38                 :            : #ifndef WIN32
#      39                 :            : #include <signal.h>
#      40                 :            : #include <sys/types.h>
#      41                 :            : #include <sys/wait.h>
#      42                 :            : #endif
#      43                 :            : 
#      44                 :            : #include <boost/test/unit_test.hpp>
#      45                 :            : 
#      46                 :            : using namespace std::literals;
#      47                 :            : static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s};
#      48                 :            : 
#      49                 :            : /* defined in logging.cpp */
#      50                 :            : namespace BCLog {
#      51                 :            :     std::string LogEscapeMessage(const std::string& str);
#      52                 :            : }
#      53                 :            : 
#      54                 :            : BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
#      55                 :            : 
#      56                 :            : BOOST_AUTO_TEST_CASE(util_datadir)
#      57                 :          2 : {
#      58                 :            :     // Use local args variable instead of m_args to avoid making assumptions about test setup
#      59                 :          2 :     ArgsManager args;
#      60                 :          2 :     args.ForceSetArg("-datadir", fs::PathToString(m_path_root));
#      61                 :            : 
#      62                 :          2 :     const fs::path dd_norm = args.GetDataDirBase();
#      63                 :            : 
#      64                 :          2 :     args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/");
#      65                 :          2 :     args.ClearPathCache();
#      66                 :          2 :     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
#      67                 :            : 
#      68                 :          2 :     args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.");
#      69                 :          2 :     args.ClearPathCache();
#      70                 :          2 :     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
#      71                 :            : 
#      72                 :          2 :     args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/./");
#      73                 :          2 :     args.ClearPathCache();
#      74                 :          2 :     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
#      75                 :            : 
#      76                 :          2 :     args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
#      77                 :          2 :     args.ClearPathCache();
#      78                 :          2 :     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
#      79                 :          2 : }
#      80                 :            : 
#      81                 :            : namespace {
#      82                 :            : class NoCopyOrMove
#      83                 :            : {
#      84                 :            : public:
#      85                 :            :     int i;
#      86                 :          2 :     explicit NoCopyOrMove(int i) : i{i} { }
#      87                 :            : 
#      88                 :            :     NoCopyOrMove() = delete;
#      89                 :            :     NoCopyOrMove(const NoCopyOrMove&) = delete;
#      90                 :            :     NoCopyOrMove(NoCopyOrMove&&) = delete;
#      91                 :            :     NoCopyOrMove& operator=(const NoCopyOrMove&) = delete;
#      92                 :            :     NoCopyOrMove& operator=(NoCopyOrMove&&) = delete;
#      93                 :            : 
#      94                 :          6 :     operator bool() const { return i != 0; }
#      95                 :            : 
#      96                 :          8 :     int get_ip1() { return i + 1; }
#      97                 :            :     bool test()
#      98                 :          4 :     {
#      99                 :            :         // Check that Assume can be used within a lambda and still call methods
#     100                 :          4 :         [&]() { Assume(get_ip1()); }();
#     101                 :          4 :         return Assume(get_ip1() != 5);
#     102                 :          4 :     }
#     103                 :            : };
#     104                 :            : } // namespace
#     105                 :            : 
#     106                 :            : BOOST_AUTO_TEST_CASE(util_check)
#     107                 :          2 : {
#     108                 :            :     // Check that Assert can forward
#     109                 :          2 :     const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2));
#     110                 :            :     // Check that Assert works on lvalues and rvalues
#     111                 :          2 :     const int two = *Assert(p_two);
#     112                 :          2 :     Assert(two == 2);
#     113                 :          2 :     Assert(true);
#     114                 :            :     // Check that Assume can be used as unary expression
#     115                 :          2 :     const bool result{Assume(two == 2)};
#     116                 :          2 :     Assert(result);
#     117                 :            : 
#     118                 :            :     // Check that Assert doesn't require copy/move
#     119                 :          2 :     NoCopyOrMove x{9};
#     120                 :          2 :     Assert(x).i += 3;
#     121                 :          2 :     Assert(x).test();
#     122                 :            : 
#     123                 :            :     // Check nested Asserts
#     124                 :          2 :     BOOST_CHECK_EQUAL(Assert((Assert(x).test() ? 3 : 0)), 3);
#     125                 :          2 : }
#     126                 :            : 
#     127                 :            : BOOST_AUTO_TEST_CASE(util_criticalsection)
#     128                 :          2 : {
#     129                 :          2 :     RecursiveMutex cs;
#     130                 :            : 
#     131                 :          2 :     do {
#     132                 :          2 :         LOCK(cs);
#     133                 :          2 :         break;
#     134                 :            : 
#     135                 :          0 :         BOOST_ERROR("break was swallowed!");
#     136                 :          0 :     } while(0);
#     137                 :            : 
#     138                 :          2 :     do {
#     139                 :          2 :         TRY_LOCK(cs, lockTest);
#     140         [ +  - ]:          2 :         if (lockTest) {
#     141                 :          2 :             BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
#     142                 :          2 :             break;
#     143                 :          2 :         }
#     144                 :            : 
#     145                 :          0 :         BOOST_ERROR("break was swallowed!");
#     146                 :          0 :     } while(0);
#     147                 :          2 : }
#     148                 :            : 
#     149                 :            : static const unsigned char ParseHex_expected[65] = {
#     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                 :            : BOOST_AUTO_TEST_CASE(util_ParseHex)
#     157                 :          2 : {
#     158                 :          2 :     std::vector<unsigned char> result;
#     159                 :          2 :     std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
#     160                 :            :     // Basic test vector
#     161                 :          2 :     result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
#     162                 :          2 :     BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
#     163                 :            : 
#     164                 :            :     // Spaces between bytes must be supported
#     165                 :          2 :     result = ParseHex("12 34 56 78");
#     166                 :          2 :     BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
#     167                 :            : 
#     168                 :            :     // Leading space must be supported (used in BerkeleyEnvironment::Salvage)
#     169                 :          2 :     result = ParseHex(" 89 34 56 78");
#     170                 :          2 :     BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
#     171                 :            : 
#     172                 :            :     // Stop parsing at invalid value
#     173                 :          2 :     result = ParseHex("1234 invalid 1234");
#     174                 :          2 :     BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
#     175                 :          2 : }
#     176                 :            : 
#     177                 :            : BOOST_AUTO_TEST_CASE(util_HexStr)
#     178                 :          2 : {
#     179                 :          2 :     BOOST_CHECK_EQUAL(
#     180                 :          2 :         HexStr(ParseHex_expected),
#     181                 :          2 :         "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
#     182                 :            : 
#     183                 :          2 :     BOOST_CHECK_EQUAL(
#     184                 :          2 :         HexStr(Span{ParseHex_expected}.last(0)),
#     185                 :          2 :         "");
#     186                 :            : 
#     187                 :          2 :     BOOST_CHECK_EQUAL(
#     188                 :          2 :         HexStr(Span{ParseHex_expected}.first(0)),
#     189                 :          2 :         "");
#     190                 :            : 
#     191                 :          2 :     {
#     192                 :          2 :         const std::vector<char> in_s{ParseHex_expected, ParseHex_expected + 5};
#     193                 :          2 :         const Span<const uint8_t> in_u{MakeUCharSpan(in_s)};
#     194                 :          2 :         const Span<const std::byte> in_b{MakeByteSpan(in_s)};
#     195                 :          2 :         const std::string out_exp{"04678afdb0"};
#     196                 :            : 
#     197                 :          2 :         BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
#     198                 :          2 :         BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
#     199                 :          2 :         BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
#     200                 :          2 :     }
#     201                 :          2 : }
#     202                 :            : 
#     203                 :            : BOOST_AUTO_TEST_CASE(span_write_bytes)
#     204                 :          2 : {
#     205                 :          2 :     std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}};
#     206                 :          2 :     const auto mut_bytes{MakeWritableByteSpan(mut_arr)};
#     207                 :          2 :     mut_bytes[1] = std::byte{0x11};
#     208                 :          2 :     BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa);
#     209                 :          2 :     BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11);
#     210                 :          2 : }
#     211                 :            : 
#     212                 :            : BOOST_AUTO_TEST_CASE(util_Join)
#     213                 :          2 : {
#     214                 :            :     // Normal version
#     215                 :          2 :     BOOST_CHECK_EQUAL(Join({}, ", "), "");
#     216                 :          2 :     BOOST_CHECK_EQUAL(Join({"foo"}, ", "), "foo");
#     217                 :          2 :     BOOST_CHECK_EQUAL(Join({"foo", "bar"}, ", "), "foo, bar");
#     218                 :            : 
#     219                 :            :     // Version with unary operator
#     220                 :          6 :     const auto op_upper = [](const std::string& s) { return ToUpper(s); };
#     221                 :          2 :     BOOST_CHECK_EQUAL(Join<std::string>({}, ", ", op_upper), "");
#     222                 :          2 :     BOOST_CHECK_EQUAL(Join<std::string>({"foo"}, ", ", op_upper), "FOO");
#     223                 :          2 :     BOOST_CHECK_EQUAL(Join<std::string>({"foo", "bar"}, ", ", op_upper), "FOO, BAR");
#     224                 :          2 : }
#     225                 :            : 
#     226                 :            : BOOST_AUTO_TEST_CASE(util_TrimString)
#     227                 :          2 : {
#     228                 :          2 :     BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar");
#     229                 :          2 :     BOOST_CHECK_EQUAL(TrimString("\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");
#     230                 :          2 :     BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar");
#     231                 :          2 :     BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n ");
#     232                 :          2 :     BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar");
#     233                 :          2 :     BOOST_CHECK_EQUAL(TrimString("foo bar", "fobar"), " ");
#     234                 :          2 :     BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7));
#     235                 :          2 :     BOOST_CHECK_EQUAL(TrimString(std::string(" foo ", 5)), std::string("foo", 3));
#     236                 :          2 :     BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2));
#     237                 :          2 :     BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6));
#     238                 :          2 :     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));
#     239                 :          2 :     BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), "");
#     240                 :          2 : }
#     241                 :            : 
#     242                 :            : BOOST_AUTO_TEST_CASE(util_FormatParseISO8601DateTime)
#     243                 :          2 : {
#     244                 :          2 :     BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
#     245                 :          2 :     BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z");
#     246                 :            : 
#     247                 :          2 :     BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z"), 0);
#     248                 :          2 :     BOOST_CHECK_EQUAL(ParseISO8601DateTime("1960-01-01T00:00:00Z"), 0);
#     249                 :          2 :     BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z"), 1317425777);
#     250                 :            : 
#     251                 :          2 :     auto time = GetTimeSeconds();
#     252                 :          2 :     BOOST_CHECK_EQUAL(ParseISO8601DateTime(FormatISO8601DateTime(time)), time);
#     253                 :          2 : }
#     254                 :            : 
#     255                 :            : BOOST_AUTO_TEST_CASE(util_FormatISO8601Date)
#     256                 :          2 : {
#     257                 :          2 :     BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30");
#     258                 :          2 : }
#     259                 :            : 
#     260                 :            : struct TestArgsManager : public ArgsManager
#     261                 :            : {
#     262                 :      56274 :     TestArgsManager() { m_network_only_args.clear(); }
#     263                 :            :     void ReadConfigString(const std::string str_config)
#     264                 :         26 :     {
#     265                 :         26 :         std::istringstream streamConfig(str_config);
#     266                 :         26 :         {
#     267                 :         26 :             LOCK(cs_args);
#     268                 :         26 :             m_settings.ro_config.clear();
#     269                 :         26 :             m_config_sections.clear();
#     270                 :         26 :         }
#     271                 :         26 :         std::string error;
#     272                 :         26 :         BOOST_REQUIRE(ReadConfigStream(streamConfig, "", error));
#     273                 :         26 :     }
#     274                 :            :     void SetNetworkOnlyArg(const std::string arg)
#     275                 :      26718 :     {
#     276                 :      26718 :         LOCK(cs_args);
#     277                 :      26718 :         m_network_only_args.insert(arg);
#     278                 :      26718 :     }
#     279                 :            :     void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args)
#     280                 :        106 :     {
#     281         [ +  + ]:        144 :         for (const auto& arg : args) {
#     282                 :        144 :             AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS);
#     283                 :        144 :         }
#     284                 :        106 :     }
#     285                 :            :     using ArgsManager::GetSetting;
#     286                 :            :     using ArgsManager::GetSettingsList;
#     287                 :            :     using ArgsManager::ReadConfigStream;
#     288                 :            :     using ArgsManager::cs_args;
#     289                 :            :     using ArgsManager::m_network;
#     290                 :            :     using ArgsManager::m_settings;
#     291                 :            : };
#     292                 :            : 
#     293                 :            : //! Test GetSetting and GetArg type coercion, negation, and default value handling.
#     294                 :            : class CheckValueTest : public TestChain100Setup
#     295                 :            : {
#     296                 :            : public:
#     297                 :            :     struct Expect {
#     298                 :            :         util::SettingsValue setting;
#     299                 :            :         bool default_string = false;
#     300                 :            :         bool default_int = false;
#     301                 :            :         bool default_bool = false;
#     302                 :            :         const char* string_value = nullptr;
#     303                 :            :         std::optional<int64_t> int_value;
#     304                 :            :         std::optional<bool> bool_value;
#     305                 :            :         std::optional<std::vector<std::string>> list_value;
#     306                 :            :         const char* error = nullptr;
#     307                 :            : 
#     308                 :         26 :         explicit Expect(util::SettingsValue s) : setting(std::move(s)) {}
#     309                 :          2 :         Expect& DefaultString() { default_string = true; return *this; }
#     310                 :          2 :         Expect& DefaultInt() { default_int = true; return *this; }
#     311                 :          2 :         Expect& DefaultBool() { default_bool = true; return *this; }
#     312                 :         24 :         Expect& String(const char* s) { string_value = s; return *this; }
#     313                 :         24 :         Expect& Int(int64_t i) { int_value = i; return *this; }
#     314                 :         24 :         Expect& Bool(bool b) { bool_value = b; return *this; }
#     315                 :         26 :         Expect& List(std::vector<std::string> m) { list_value = std::move(m); return *this; }
#     316                 :          0 :         Expect& Error(const char* e) { error = e; return *this; }
#     317                 :            :     };
#     318                 :            : 
#     319                 :            :     void CheckValue(unsigned int flags, const char* arg, const Expect& expect)
#     320                 :         26 :     {
#     321                 :         26 :         TestArgsManager test;
#     322                 :         26 :         test.SetupArgs({{"-value", flags}});
#     323                 :         26 :         const char* argv[] = {"ignored", arg};
#     324                 :         26 :         std::string error;
#     325         [ +  + ]:         26 :         bool success = test.ParseParameters(arg ? 2 : 1, (char**)argv, error);
#     326                 :            : 
#     327                 :         26 :         BOOST_CHECK_EQUAL(test.GetSetting("-value").write(), expect.setting.write());
#     328                 :         26 :         auto settings_list = test.GetSettingsList("-value");
#     329 [ +  + ][ +  + ]:         26 :         if (expect.setting.isNull() || expect.setting.isFalse()) {
#     330                 :         10 :             BOOST_CHECK_EQUAL(settings_list.size(), 0U);
#     331                 :         16 :         } else {
#     332                 :         16 :             BOOST_CHECK_EQUAL(settings_list.size(), 1U);
#     333                 :         16 :             BOOST_CHECK_EQUAL(settings_list[0].write(), expect.setting.write());
#     334                 :         16 :         }
#     335                 :            : 
#     336         [ -  + ]:         26 :         if (expect.error) {
#     337                 :          0 :             BOOST_CHECK(!success);
#     338                 :          0 :             BOOST_CHECK_NE(error.find(expect.error), std::string::npos);
#     339                 :         26 :         } else {
#     340                 :         26 :             BOOST_CHECK(success);
#     341                 :         26 :             BOOST_CHECK_EQUAL(error, "");
#     342                 :         26 :         }
#     343                 :            : 
#     344         [ +  + ]:         26 :         if (expect.default_string) {
#     345                 :          2 :             BOOST_CHECK_EQUAL(test.GetArg("-value", "zzzzz"), "zzzzz");
#     346         [ +  - ]:         24 :         } else if (expect.string_value) {
#     347                 :         24 :             BOOST_CHECK_EQUAL(test.GetArg("-value", "zzzzz"), expect.string_value);
#     348                 :         24 :         } else {
#     349                 :          0 :             BOOST_CHECK(!success);
#     350                 :          0 :         }
#     351                 :            : 
#     352         [ +  + ]:         26 :         if (expect.default_int) {
#     353                 :          2 :             BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), 99999);
#     354         [ +  - ]:         24 :         } else if (expect.int_value) {
#     355                 :         24 :             BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), *expect.int_value);
#     356                 :         24 :         } else {
#     357                 :          0 :             BOOST_CHECK(!success);
#     358                 :          0 :         }
#     359                 :            : 
#     360         [ +  + ]:         26 :         if (expect.default_bool) {
#     361                 :          2 :             BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), false);
#     362                 :          2 :             BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), true);
#     363         [ +  - ]:         24 :         } else if (expect.bool_value) {
#     364                 :         24 :             BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), *expect.bool_value);
#     365                 :         24 :             BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), *expect.bool_value);
#     366                 :         24 :         } else {
#     367                 :          0 :             BOOST_CHECK(!success);
#     368                 :          0 :         }
#     369                 :            : 
#     370         [ +  - ]:         26 :         if (expect.list_value) {
#     371                 :         26 :             auto l = test.GetArgs("-value");
#     372                 :         26 :             BOOST_CHECK_EQUAL_COLLECTIONS(l.begin(), l.end(), expect.list_value->begin(), expect.list_value->end());
#     373                 :         26 :         } else {
#     374                 :          0 :             BOOST_CHECK(!success);
#     375                 :          0 :         }
#     376                 :         26 :     }
#     377                 :            : };
#     378                 :            : 
#     379                 :            : BOOST_FIXTURE_TEST_CASE(util_CheckValue, CheckValueTest)
#     380                 :          2 : {
#     381                 :          2 :     using M = ArgsManager;
#     382                 :            : 
#     383                 :          2 :     CheckValue(M::ALLOW_ANY, nullptr, Expect{{}}.DefaultString().DefaultInt().DefaultBool().List({}));
#     384                 :          2 :     CheckValue(M::ALLOW_ANY, "-novalue", Expect{false}.String("0").Int(0).Bool(false).List({}));
#     385                 :          2 :     CheckValue(M::ALLOW_ANY, "-novalue=", Expect{false}.String("0").Int(0).Bool(false).List({}));
#     386                 :          2 :     CheckValue(M::ALLOW_ANY, "-novalue=0", Expect{true}.String("1").Int(1).Bool(true).List({"1"}));
#     387                 :          2 :     CheckValue(M::ALLOW_ANY, "-novalue=1", Expect{false}.String("0").Int(0).Bool(false).List({}));
#     388                 :          2 :     CheckValue(M::ALLOW_ANY, "-novalue=2", Expect{false}.String("0").Int(0).Bool(false).List({}));
#     389                 :          2 :     CheckValue(M::ALLOW_ANY, "-novalue=abc", Expect{true}.String("1").Int(1).Bool(true).List({"1"}));
#     390                 :          2 :     CheckValue(M::ALLOW_ANY, "-value", Expect{""}.String("").Int(0).Bool(true).List({""}));
#     391                 :          2 :     CheckValue(M::ALLOW_ANY, "-value=", Expect{""}.String("").Int(0).Bool(true).List({""}));
#     392                 :          2 :     CheckValue(M::ALLOW_ANY, "-value=0", Expect{"0"}.String("0").Int(0).Bool(false).List({"0"}));
#     393                 :          2 :     CheckValue(M::ALLOW_ANY, "-value=1", Expect{"1"}.String("1").Int(1).Bool(true).List({"1"}));
#     394                 :          2 :     CheckValue(M::ALLOW_ANY, "-value=2", Expect{"2"}.String("2").Int(2).Bool(true).List({"2"}));
#     395                 :          2 :     CheckValue(M::ALLOW_ANY, "-value=abc", Expect{"abc"}.String("abc").Int(0).Bool(false).List({"abc"}));
#     396                 :          2 : }
#     397                 :            : 
#     398                 :            : struct NoIncludeConfTest {
#     399                 :            :     std::string Parse(const char* arg)
#     400                 :          6 :     {
#     401                 :          6 :         TestArgsManager test;
#     402                 :          6 :         test.SetupArgs({{"-includeconf", ArgsManager::ALLOW_ANY}});
#     403                 :          6 :         std::array argv{"ignored", arg};
#     404                 :          6 :         std::string error;
#     405                 :          6 :         (void)test.ParseParameters(argv.size(), argv.data(), error);
#     406                 :          6 :         return error;
#     407                 :          6 :     }
#     408                 :            : };
#     409                 :            : 
#     410                 :            : BOOST_FIXTURE_TEST_CASE(util_NoIncludeConf, NoIncludeConfTest)
#     411                 :          2 : {
#     412                 :          2 :     BOOST_CHECK_EQUAL(Parse("-noincludeconf"), "");
#     413                 :          2 :     BOOST_CHECK_EQUAL(Parse("-includeconf"), "-includeconf cannot be used from commandline; -includeconf=\"\"");
#     414                 :          2 :     BOOST_CHECK_EQUAL(Parse("-includeconf=file"), "-includeconf cannot be used from commandline; -includeconf=\"file\"");
#     415                 :          2 : }
#     416                 :            : 
#     417                 :            : BOOST_AUTO_TEST_CASE(util_ParseParameters)
#     418                 :          2 : {
#     419                 :          2 :     TestArgsManager testArgs;
#     420                 :          2 :     const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
#     421                 :          2 :     const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
#     422                 :          2 :     const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);
#     423                 :          2 :     const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
#     424                 :            : 
#     425                 :          2 :     const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};
#     426                 :            : 
#     427                 :          2 :     std::string error;
#     428                 :          2 :     LOCK(testArgs.cs_args);
#     429                 :          2 :     testArgs.SetupArgs({a, b, ccc, d});
#     430                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(0, (char**)argv_test, error));
#     431                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
#     432                 :            : 
#     433                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
#     434                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
#     435                 :            : 
#     436                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
#     437                 :            :     // expectation: -ignored is ignored (program name argument),
#     438                 :            :     // -a, -b and -ccc end up in map, -d ignored because it is after
#     439                 :            :     // a non-option argument (non-GNU option parsing)
#     440                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options.size() == 3 && testArgs.m_settings.ro_config.empty());
#     441                 :          2 :     BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && testArgs.IsArgSet("-ccc")
#     442                 :          2 :                 && !testArgs.IsArgSet("f") && !testArgs.IsArgSet("-d"));
#     443                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options.count("a") && testArgs.m_settings.command_line_options.count("b") && testArgs.m_settings.command_line_options.count("ccc")
#     444                 :          2 :                 && !testArgs.m_settings.command_line_options.count("f") && !testArgs.m_settings.command_line_options.count("d"));
#     445                 :            : 
#     446                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options["a"].size() == 1);
#     447                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options["a"].front().get_str() == "");
#     448                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].size() == 2);
#     449                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].front().get_str() == "argument");
#     450                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].back().get_str() == "multiple");
#     451                 :          2 :     BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2);
#     452                 :          2 : }
#     453                 :            : 
#     454                 :            : BOOST_AUTO_TEST_CASE(util_ParseInvalidParameters)
#     455                 :          2 : {
#     456                 :          2 :     TestArgsManager test;
#     457                 :          2 :     test.SetupArgs({{"-registered", ArgsManager::ALLOW_ANY}});
#     458                 :            : 
#     459                 :          2 :     const char* argv[] = {"ignored", "-registered"};
#     460                 :          2 :     std::string error;
#     461                 :          2 :     BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
#     462                 :          2 :     BOOST_CHECK_EQUAL(error, "");
#     463                 :            : 
#     464                 :          2 :     argv[1] = "-unregistered";
#     465                 :          2 :     BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
#     466                 :          2 :     BOOST_CHECK_EQUAL(error, "Invalid parameter -unregistered");
#     467                 :            : 
#     468                 :            :     // Make sure registered parameters prefixed with a chain name trigger errors.
#     469                 :            :     // (Previously, they were accepted and ignored.)
#     470                 :          2 :     argv[1] = "-test.registered";
#     471                 :          2 :     BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
#     472                 :          2 :     BOOST_CHECK_EQUAL(error, "Invalid parameter -test.registered");
#     473                 :          2 : }
#     474                 :            : 
#     475                 :            : static void TestParse(const std::string& str, bool expected_bool, int64_t expected_int)
#     476                 :         62 : {
#     477                 :         62 :     TestArgsManager test;
#     478                 :         62 :     test.SetupArgs({{"-value", ArgsManager::ALLOW_ANY}});
#     479                 :         62 :     std::string arg = "-value=" + str;
#     480                 :         62 :     const char* argv[] = {"ignored", arg.c_str()};
#     481                 :         62 :     std::string error;
#     482                 :         62 :     BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
#     483                 :         62 :     BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), expected_bool);
#     484                 :         62 :     BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), expected_bool);
#     485                 :         62 :     BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99998), expected_int);
#     486                 :         62 :     BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), expected_int);
#     487                 :         62 : }
#     488                 :            : 
#     489                 :            : // Test bool and int parsing.
#     490                 :            : BOOST_AUTO_TEST_CASE(util_ArgParsing)
#     491                 :          2 : {
#     492                 :            :     // Some of these cases could be ambiguous or surprising to users, and might
#     493                 :            :     // be worth triggering errors or warnings in the future. But for now basic
#     494                 :            :     // test coverage is useful to avoid breaking backwards compatibility
#     495                 :            :     // unintentionally.
#     496                 :          2 :     TestParse("", true, 0);
#     497                 :          2 :     TestParse(" ", false, 0);
#     498                 :          2 :     TestParse("0", false, 0);
#     499                 :          2 :     TestParse("0 ", false, 0);
#     500                 :          2 :     TestParse(" 0", false, 0);
#     501                 :          2 :     TestParse("+0", false, 0);
#     502                 :          2 :     TestParse("-0", false, 0);
#     503                 :          2 :     TestParse("5", true, 5);
#     504                 :          2 :     TestParse("5 ", true, 5);
#     505                 :          2 :     TestParse(" 5", true, 5);
#     506                 :          2 :     TestParse("+5", true, 5);
#     507                 :          2 :     TestParse("-5", true, -5);
#     508                 :          2 :     TestParse("0 5", false, 0);
#     509                 :          2 :     TestParse("5 0", true, 5);
#     510                 :          2 :     TestParse("050", true, 50);
#     511                 :          2 :     TestParse("0.", false, 0);
#     512                 :          2 :     TestParse("5.", true, 5);
#     513                 :          2 :     TestParse("0.0", false, 0);
#     514                 :          2 :     TestParse("0.5", false, 0);
#     515                 :          2 :     TestParse("5.0", true, 5);
#     516                 :          2 :     TestParse("5.5", true, 5);
#     517                 :          2 :     TestParse("x", false, 0);
#     518                 :          2 :     TestParse("x0", false, 0);
#     519                 :          2 :     TestParse("x5", false, 0);
#     520                 :          2 :     TestParse("0x", false, 0);
#     521                 :          2 :     TestParse("5x", true, 5);
#     522                 :          2 :     TestParse("0x5", false, 0);
#     523                 :          2 :     TestParse("false", false, 0);
#     524                 :          2 :     TestParse("true", false, 0);
#     525                 :          2 :     TestParse("yes", false, 0);
#     526                 :          2 :     TestParse("no", false, 0);
#     527                 :          2 : }
#     528                 :            : 
#     529                 :            : BOOST_AUTO_TEST_CASE(util_GetBoolArg)
#     530                 :          2 : {
#     531                 :          2 :     TestArgsManager testArgs;
#     532                 :          2 :     const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
#     533                 :          2 :     const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
#     534                 :          2 :     const auto c = std::make_pair("-c", ArgsManager::ALLOW_ANY);
#     535                 :          2 :     const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
#     536                 :          2 :     const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);
#     537                 :          2 :     const auto f = std::make_pair("-f", ArgsManager::ALLOW_ANY);
#     538                 :            : 
#     539                 :          2 :     const char *argv_test[] = {
#     540                 :          2 :         "ignored", "-a", "-nob", "-c=0", "-d=1", "-e=false", "-f=true"};
#     541                 :          2 :     std::string error;
#     542                 :          2 :     LOCK(testArgs.cs_args);
#     543                 :          2 :     testArgs.SetupArgs({a, b, c, d, e, f});
#     544                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
#     545                 :            : 
#     546                 :            :     // Each letter should be set.
#     547         [ +  + ]:          2 :     for (const char opt : "abcdef")
#     548                 :         14 :         BOOST_CHECK(testArgs.IsArgSet({'-', opt}) || !opt);
#     549                 :            : 
#     550                 :            :     // Nothing else should be in the map
#     551                 :          2 :     BOOST_CHECK(testArgs.m_settings.command_line_options.size() == 6 &&
#     552                 :          2 :                 testArgs.m_settings.ro_config.empty());
#     553                 :            : 
#     554                 :            :     // The -no prefix should get stripped on the way in.
#     555                 :          2 :     BOOST_CHECK(!testArgs.IsArgSet("-nob"));
#     556                 :            : 
#     557                 :            :     // The -b option is flagged as negated, and nothing else is
#     558                 :          2 :     BOOST_CHECK(testArgs.IsArgNegated("-b"));
#     559                 :          2 :     BOOST_CHECK(!testArgs.IsArgNegated("-a"));
#     560                 :            : 
#     561                 :            :     // Check expected values.
#     562                 :          2 :     BOOST_CHECK(testArgs.GetBoolArg("-a", false) == true);
#     563                 :          2 :     BOOST_CHECK(testArgs.GetBoolArg("-b", true) == false);
#     564                 :          2 :     BOOST_CHECK(testArgs.GetBoolArg("-c", true) == false);
#     565                 :          2 :     BOOST_CHECK(testArgs.GetBoolArg("-d", false) == true);
#     566                 :          2 :     BOOST_CHECK(testArgs.GetBoolArg("-e", true) == false);
#     567                 :          2 :     BOOST_CHECK(testArgs.GetBoolArg("-f", true) == false);
#     568                 :          2 : }
#     569                 :            : 
#     570                 :            : BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
#     571                 :          2 : {
#     572                 :            :     // Test some awful edge cases that hopefully no user will ever exercise.
#     573                 :          2 :     TestArgsManager testArgs;
#     574                 :            : 
#     575                 :            :     // Params test
#     576                 :          2 :     const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY);
#     577                 :          2 :     const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
#     578                 :          2 :     const char *argv_test[] = {"ignored", "-nofoo", "-foo", "-nobar=0"};
#     579                 :          2 :     testArgs.SetupArgs({foo, bar});
#     580                 :          2 :     std::string error;
#     581                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(4, (char**)argv_test, error));
#     582                 :            : 
#     583                 :            :     // This was passed twice, second one overrides the negative setting.
#     584                 :          2 :     BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
#     585                 :          2 :     BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "");
#     586                 :            : 
#     587                 :            :     // A double negative is a positive, and not marked as negated.
#     588                 :          2 :     BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
#     589                 :          2 :     BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");
#     590                 :            : 
#     591                 :            :     // Config test
#     592                 :          2 :     const char *conf_test = "nofoo=1\nfoo=1\nnobar=0\n";
#     593                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
#     594                 :          2 :     testArgs.ReadConfigString(conf_test);
#     595                 :            : 
#     596                 :            :     // This was passed twice, second one overrides the negative setting,
#     597                 :            :     // and the value.
#     598                 :          2 :     BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
#     599                 :          2 :     BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "1");
#     600                 :            : 
#     601                 :            :     // A double negative is a positive, and does not count as negated.
#     602                 :          2 :     BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
#     603                 :          2 :     BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");
#     604                 :            : 
#     605                 :            :     // Combined test
#     606                 :          2 :     const char *combo_test_args[] = {"ignored", "-nofoo", "-bar"};
#     607                 :          2 :     const char *combo_test_conf = "foo=1\nnobar=1\n";
#     608                 :          2 :     BOOST_CHECK(testArgs.ParseParameters(3, (char**)combo_test_args, error));
#     609                 :          2 :     testArgs.ReadConfigString(combo_test_conf);
#     610                 :            : 
#     611                 :            :     // Command line overrides, but doesn't erase old setting
#     612                 :          2 :     BOOST_CHECK(testArgs.IsArgNegated("-foo"));
#     613                 :          2 :     BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "0");
#     614                 :          2 :     BOOST_CHECK(testArgs.GetArgs("-foo").size() == 0);
#     615                 :            : 
#     616                 :            :     // Command line overrides, but doesn't erase old setting
#     617                 :          2 :     BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
#     618                 :          2 :     BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "");
#     619                 :          2 :     BOOST_CHECK(testArgs.GetArgs("-bar").size() == 1
#     620                 :          2 :                 && testArgs.GetArgs("-bar").front() == "");
#     621                 :          2 : }
#     622                 :            : 
#     623                 :            : BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
#     624                 :          2 : {
#     625                 :          2 :     const char *str_config =
#     626                 :          2 :        "a=\n"
#     627                 :          2 :        "b=1\n"
#     628                 :          2 :        "ccc=argument\n"
#     629                 :          2 :        "ccc=multiple\n"
#     630                 :          2 :        "d=e\n"
#     631                 :          2 :        "nofff=1\n"
#     632                 :          2 :        "noggg=0\n"
#     633                 :          2 :        "h=1\n"
#     634                 :          2 :        "noh=1\n"
#     635                 :          2 :        "noi=1\n"
#     636                 :          2 :        "i=1\n"
#     637                 :          2 :        "sec1.ccc=extend1\n"
#     638                 :          2 :        "\n"
#     639                 :          2 :        "[sec1]\n"
#     640                 :          2 :        "ccc=extend2\n"
#     641                 :          2 :        "d=eee\n"
#     642                 :          2 :        "h=1\n"
#     643                 :          2 :        "[sec2]\n"
#     644                 :          2 :        "ccc=extend3\n"
#     645                 :          2 :        "iii=2\n";
#     646                 :            : 
#     647                 :          2 :     TestArgsManager test_args;
#     648                 :          2 :     LOCK(test_args.cs_args);
#     649                 :          2 :     const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
#     650                 :          2 :     const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
#     651                 :          2 :     const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);
#     652                 :          2 :     const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
#     653                 :          2 :     const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);
#     654                 :          2 :     const auto fff = std::make_pair("-fff", ArgsManager::ALLOW_ANY);
#     655                 :          2 :     const auto ggg = std::make_pair("-ggg", ArgsManager::ALLOW_ANY);
#     656                 :          2 :     const auto h = std::make_pair("-h", ArgsManager::ALLOW_ANY);
#     657                 :          2 :     const auto i = std::make_pair("-i", ArgsManager::ALLOW_ANY);
#     658                 :          2 :     const auto iii = std::make_pair("-iii", ArgsManager::ALLOW_ANY);
#     659                 :          2 :     test_args.SetupArgs({a, b, ccc, d, e, fff, ggg, h, i, iii});
#     660                 :            : 
#     661                 :          2 :     test_args.ReadConfigString(str_config);
#     662                 :            :     // expectation: a, b, ccc, d, fff, ggg, h, i end up in map
#     663                 :            :     // so do sec1.ccc, sec1.d, sec1.h, sec2.ccc, sec2.iii
#     664                 :            : 
#     665                 :          2 :     BOOST_CHECK(test_args.m_settings.command_line_options.empty());
#     666                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config.size() == 3);
#     667                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].size() == 8);
#     668                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config["sec1"].size() == 3);
#     669                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config["sec2"].size() == 2);
#     670                 :            : 
#     671                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("a"));
#     672                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("b"));
#     673                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("ccc"));
#     674                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("d"));
#     675                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("fff"));
#     676                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("ggg"));
#     677                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("h"));
#     678                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config[""].count("i"));
#     679                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config["sec1"].count("ccc"));
#     680                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config["sec1"].count("h"));
#     681                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config["sec2"].count("ccc"));
#     682                 :          2 :     BOOST_CHECK(test_args.m_settings.ro_config["sec2"].count("iii"));
#     683                 :            : 
#     684                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-a"));
#     685                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-b"));
#     686                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-ccc"));
#     687                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-d"));
#     688                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-fff"));
#     689                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-ggg"));
#     690                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-h"));
#     691                 :          2 :     BOOST_CHECK(test_args.IsArgSet("-i"));
#     692                 :          2 :     BOOST_CHECK(!test_args.IsArgSet("-zzz"));
#     693                 :          2 :     BOOST_CHECK(!test_args.IsArgSet("-iii"));
#     694                 :            : 
#     695                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");
#     696                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");
#     697                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-ccc", "xxx"), "argument");
#     698                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-d", "xxx"), "e");
#     699                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");
#     700                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");
#     701                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-h", "xxx"), "0");
#     702                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-i", "xxx"), "1");
#     703                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");
#     704                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");
#     705                 :            : 
#     706         [ +  + ]:          4 :     for (const bool def : {false, true}) {
#     707                 :          4 :         BOOST_CHECK(test_args.GetBoolArg("-a", def));
#     708                 :          4 :         BOOST_CHECK(test_args.GetBoolArg("-b", def));
#     709                 :          4 :         BOOST_CHECK(!test_args.GetBoolArg("-ccc", def));
#     710                 :          4 :         BOOST_CHECK(!test_args.GetBoolArg("-d", def));
#     711                 :          4 :         BOOST_CHECK(!test_args.GetBoolArg("-fff", def));
#     712                 :          4 :         BOOST_CHECK(test_args.GetBoolArg("-ggg", def));
#     713                 :          4 :         BOOST_CHECK(!test_args.GetBoolArg("-h", def));
#     714                 :          4 :         BOOST_CHECK(test_args.GetBoolArg("-i", def));
#     715                 :          4 :         BOOST_CHECK(test_args.GetBoolArg("-zzz", def) == def);
#     716                 :          4 :         BOOST_CHECK(test_args.GetBoolArg("-iii", def) == def);
#     717                 :          4 :     }
#     718                 :            : 
#     719                 :          2 :     BOOST_CHECK(test_args.GetArgs("-a").size() == 1
#     720                 :          2 :                 && test_args.GetArgs("-a").front() == "");
#     721                 :          2 :     BOOST_CHECK(test_args.GetArgs("-b").size() == 1
#     722                 :          2 :                 && test_args.GetArgs("-b").front() == "1");
#     723                 :          2 :     BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2
#     724                 :          2 :                 && test_args.GetArgs("-ccc").front() == "argument"
#     725                 :          2 :                 && test_args.GetArgs("-ccc").back() == "multiple");
#     726                 :          2 :     BOOST_CHECK(test_args.GetArgs("-fff").size() == 0);
#     727                 :          2 :     BOOST_CHECK(test_args.GetArgs("-nofff").size() == 0);
#     728                 :          2 :     BOOST_CHECK(test_args.GetArgs("-ggg").size() == 1
#     729                 :          2 :                 && test_args.GetArgs("-ggg").front() == "1");
#     730                 :          2 :     BOOST_CHECK(test_args.GetArgs("-noggg").size() == 0);
#     731                 :          2 :     BOOST_CHECK(test_args.GetArgs("-h").size() == 0);
#     732                 :          2 :     BOOST_CHECK(test_args.GetArgs("-noh").size() == 0);
#     733                 :          2 :     BOOST_CHECK(test_args.GetArgs("-i").size() == 1
#     734                 :          2 :                 && test_args.GetArgs("-i").front() == "1");
#     735                 :          2 :     BOOST_CHECK(test_args.GetArgs("-noi").size() == 0);
#     736                 :          2 :     BOOST_CHECK(test_args.GetArgs("-zzz").size() == 0);
#     737                 :            : 
#     738                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-a"));
#     739                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-b"));
#     740                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-ccc"));
#     741                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-d"));
#     742                 :          2 :     BOOST_CHECK(test_args.IsArgNegated("-fff"));
#     743                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-ggg"));
#     744                 :          2 :     BOOST_CHECK(test_args.IsArgNegated("-h")); // last setting takes precedence
#     745                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-i")); // last setting takes precedence
#     746                 :          2 :     BOOST_CHECK(!test_args.IsArgNegated("-zzz"));
#     747                 :            : 
#     748                 :            :     // Test sections work
#     749                 :          2 :     test_args.SelectConfigNetwork("sec1");
#     750                 :            : 
#     751                 :            :     // same as original
#     752                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");
#     753                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");
#     754                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");
#     755                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");
#     756                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");
#     757                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");
#     758                 :            :     // d is overridden
#     759                 :          2 :     BOOST_CHECK(test_args.GetArg("-d", "xxx") == "eee");
#     760                 :            :     // section-specific setting
#     761                 :          2 :     BOOST_CHECK(test_args.GetArg("-h", "xxx") == "1");
#     762                 :            :     // section takes priority for multiple values
#     763                 :          2 :     BOOST_CHECK(test_args.GetArg("-ccc", "xxx") == "extend1");
#     764                 :            :     // check multiple values works
#     765                 :          2 :     const std::vector<std::string> sec1_ccc_expected = {"extend1","extend2","argument","multiple"};
#     766                 :          2 :     const auto& sec1_ccc_res = test_args.GetArgs("-ccc");
#     767                 :          2 :     BOOST_CHECK_EQUAL_COLLECTIONS(sec1_ccc_res.begin(), sec1_ccc_res.end(), sec1_ccc_expected.begin(), sec1_ccc_expected.end());
#     768                 :            : 
#     769                 :          2 :     test_args.SelectConfigNetwork("sec2");
#     770                 :            : 
#     771                 :            :     // same as original
#     772                 :          2 :     BOOST_CHECK(test_args.GetArg("-a", "xxx") == "");
#     773                 :          2 :     BOOST_CHECK(test_args.GetArg("-b", "xxx") == "1");
#     774                 :          2 :     BOOST_CHECK(test_args.GetArg("-d", "xxx") == "e");
#     775                 :          2 :     BOOST_CHECK(test_args.GetArg("-fff", "xxx") == "0");
#     776                 :          2 :     BOOST_CHECK(test_args.GetArg("-ggg", "xxx") == "1");
#     777                 :          2 :     BOOST_CHECK(test_args.GetArg("-zzz", "xxx") == "xxx");
#     778                 :          2 :     BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
#     779                 :            :     // section-specific setting
#     780                 :          2 :     BOOST_CHECK(test_args.GetArg("-iii", "xxx") == "2");
#     781                 :            :     // section takes priority for multiple values
#     782                 :          2 :     BOOST_CHECK(test_args.GetArg("-ccc", "xxx") == "extend3");
#     783                 :            :     // check multiple values works
#     784                 :          2 :     const std::vector<std::string> sec2_ccc_expected = {"extend3","argument","multiple"};
#     785                 :          2 :     const auto& sec2_ccc_res = test_args.GetArgs("-ccc");
#     786                 :          2 :     BOOST_CHECK_EQUAL_COLLECTIONS(sec2_ccc_res.begin(), sec2_ccc_res.end(), sec2_ccc_expected.begin(), sec2_ccc_expected.end());
#     787                 :            : 
#     788                 :            :     // Test section only options
#     789                 :            : 
#     790                 :          2 :     test_args.SetNetworkOnlyArg("-d");
#     791                 :          2 :     test_args.SetNetworkOnlyArg("-ccc");
#     792                 :          2 :     test_args.SetNetworkOnlyArg("-h");
#     793                 :            : 
#     794                 :          2 :     test_args.SelectConfigNetwork(CBaseChainParams::MAIN);
#     795                 :          2 :     BOOST_CHECK(test_args.GetArg("-d", "xxx") == "e");
#     796                 :          2 :     BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2);
#     797                 :          2 :     BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
#     798                 :            : 
#     799                 :          2 :     test_args.SelectConfigNetwork("sec1");
#     800                 :          2 :     BOOST_CHECK(test_args.GetArg("-d", "xxx") == "eee");
#     801                 :          2 :     BOOST_CHECK(test_args.GetArgs("-d").size() == 1);
#     802                 :          2 :     BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2);
#     803                 :          2 :     BOOST_CHECK(test_args.GetArg("-h", "xxx") == "1");
#     804                 :            : 
#     805                 :          2 :     test_args.SelectConfigNetwork("sec2");
#     806                 :          2 :     BOOST_CHECK(test_args.GetArg("-d", "xxx") == "xxx");
#     807                 :          2 :     BOOST_CHECK(test_args.GetArgs("-d").size() == 0);
#     808                 :          2 :     BOOST_CHECK(test_args.GetArgs("-ccc").size() == 1);
#     809                 :          2 :     BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
#     810                 :          2 : }
#     811                 :            : 
#     812                 :            : BOOST_AUTO_TEST_CASE(util_GetArg)
#     813                 :          2 : {
#     814                 :          2 :     TestArgsManager testArgs;
#     815                 :          2 :     LOCK(testArgs.cs_args);
#     816                 :          2 :     testArgs.m_settings.command_line_options.clear();
#     817                 :          2 :     testArgs.m_settings.command_line_options["strtest1"] = {"string..."};
#     818                 :            :     // strtest2 undefined on purpose
#     819                 :          2 :     testArgs.m_settings.command_line_options["inttest1"] = {"12345"};
#     820                 :          2 :     testArgs.m_settings.command_line_options["inttest2"] = {"81985529216486895"};
#     821                 :            :     // inttest3 undefined on purpose
#     822                 :          2 :     testArgs.m_settings.command_line_options["booltest1"] = {""};
#     823                 :            :     // booltest2 undefined on purpose
#     824                 :          2 :     testArgs.m_settings.command_line_options["booltest3"] = {"0"};
#     825                 :          2 :     testArgs.m_settings.command_line_options["booltest4"] = {"1"};
#     826                 :            : 
#     827                 :            :     // priorities
#     828                 :          2 :     testArgs.m_settings.command_line_options["pritest1"] = {"a", "b"};
#     829                 :          2 :     testArgs.m_settings.ro_config[""]["pritest2"] = {"a", "b"};
#     830                 :          2 :     testArgs.m_settings.command_line_options["pritest3"] = {"a"};
#     831                 :          2 :     testArgs.m_settings.ro_config[""]["pritest3"] = {"b"};
#     832                 :          2 :     testArgs.m_settings.command_line_options["pritest4"] = {"a","b"};
#     833                 :          2 :     testArgs.m_settings.ro_config[""]["pritest4"] = {"c","d"};
#     834                 :            : 
#     835                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string...");
#     836                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default");
#     837                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest1", -1), 12345);
#     838                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest2", -1), 81985529216486895LL);
#     839                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest3", -1), -1);
#     840                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true);
#     841                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false);
#     842                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false);
#     843                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true);
#     844                 :            : 
#     845                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetArg("pritest1", "default"), "b");
#     846                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetArg("pritest2", "default"), "a");
#     847                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetArg("pritest3", "default"), "a");
#     848                 :          2 :     BOOST_CHECK_EQUAL(testArgs.GetArg("pritest4", "default"), "b");
#     849                 :          2 : }
#     850                 :            : 
#     851                 :            : BOOST_AUTO_TEST_CASE(util_GetChainName)
#     852                 :          2 : {
#     853                 :          2 :     TestArgsManager test_args;
#     854                 :          2 :     const auto testnet = std::make_pair("-testnet", ArgsManager::ALLOW_ANY);
#     855                 :          2 :     const auto regtest = std::make_pair("-regtest", ArgsManager::ALLOW_ANY);
#     856                 :          2 :     test_args.SetupArgs({testnet, regtest});
#     857                 :            : 
#     858                 :          2 :     const char* argv_testnet[] = {"cmd", "-testnet"};
#     859                 :          2 :     const char* argv_regtest[] = {"cmd", "-regtest"};
#     860                 :          2 :     const char* argv_test_no_reg[] = {"cmd", "-testnet", "-noregtest"};
#     861                 :          2 :     const char* argv_both[] = {"cmd", "-testnet", "-regtest"};
#     862                 :            : 
#     863                 :            :     // equivalent to "-testnet"
#     864                 :            :     // regtest in testnet section is ignored
#     865                 :          2 :     const char* testnetconf = "testnet=1\nregtest=0\n[test]\nregtest=1";
#     866                 :          2 :     std::string error;
#     867                 :            : 
#     868                 :          2 :     BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
#     869                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "main");
#     870                 :            : 
#     871                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
#     872                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     873                 :            : 
#     874                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
#     875                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "regtest");
#     876                 :            : 
#     877                 :          2 :     BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
#     878                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     879                 :            : 
#     880                 :          2 :     BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
#     881                 :          2 :     BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
#     882                 :            : 
#     883                 :          2 :     BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
#     884                 :          2 :     test_args.ReadConfigString(testnetconf);
#     885                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     886                 :            : 
#     887                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
#     888                 :          2 :     test_args.ReadConfigString(testnetconf);
#     889                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     890                 :            : 
#     891                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
#     892                 :          2 :     test_args.ReadConfigString(testnetconf);
#     893                 :          2 :     BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
#     894                 :            : 
#     895                 :          2 :     BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
#     896                 :          2 :     test_args.ReadConfigString(testnetconf);
#     897                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     898                 :            : 
#     899                 :          2 :     BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
#     900                 :          2 :     test_args.ReadConfigString(testnetconf);
#     901                 :          2 :     BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
#     902                 :            : 
#     903                 :            :     // check setting the network to test (and thus making
#     904                 :            :     // [test] regtest=1 potentially relevant) doesn't break things
#     905                 :          2 :     test_args.SelectConfigNetwork("test");
#     906                 :            : 
#     907                 :          2 :     BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
#     908                 :          2 :     test_args.ReadConfigString(testnetconf);
#     909                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     910                 :            : 
#     911                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
#     912                 :          2 :     test_args.ReadConfigString(testnetconf);
#     913                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     914                 :            : 
#     915                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
#     916                 :          2 :     test_args.ReadConfigString(testnetconf);
#     917                 :          2 :     BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
#     918                 :            : 
#     919                 :          2 :     BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_test_no_reg, error));
#     920                 :          2 :     test_args.ReadConfigString(testnetconf);
#     921                 :          2 :     BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
#     922                 :            : 
#     923                 :          2 :     BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
#     924                 :          2 :     test_args.ReadConfigString(testnetconf);
#     925                 :          2 :     BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
#     926                 :          2 : }
#     927                 :            : 
#     928                 :            : // Test different ways settings can be merged, and verify results. This test can
#     929                 :            : // be used to confirm that updates to settings code don't change behavior
#     930                 :            : // unintentionally.
#     931                 :            : //
#     932                 :            : // The test covers:
#     933                 :            : //
#     934                 :            : // - Combining different setting actions. Possible actions are: configuring a
#     935                 :            : //   setting, negating a setting (adding "-no" prefix), and configuring/negating
#     936                 :            : //   settings in a network section (adding "main." or "test." prefixes).
#     937                 :            : //
#     938                 :            : // - Combining settings from command line arguments and a config file.
#     939                 :            : //
#     940                 :            : // - Combining SoftSet and ForceSet calls.
#     941                 :            : //
#     942                 :            : // - Testing "main" and "test" network values to make sure settings from network
#     943                 :            : //   sections are applied and to check for mainnet-specific behaviors like
#     944                 :            : //   inheriting settings from the default section.
#     945                 :            : //
#     946                 :            : // - Testing network-specific settings like "-wallet", that may be ignored
#     947                 :            : //   outside a network section, and non-network specific settings like "-server"
#     948                 :            : //   that aren't sensitive to the network.
#     949                 :            : //
#     950                 :            : struct ArgsMergeTestingSetup : public BasicTestingSetup {
#     951                 :            :     //! Max number of actions to sequence together. Can decrease this when
#     952                 :            :     //! debugging to make test results easier to understand.
#     953                 :            :     static constexpr int MAX_ACTIONS = 3;
#     954                 :            : 
#     955                 :            :     enum Action { NONE, SET, NEGATE, SECTION_SET, SECTION_NEGATE };
#     956                 :            :     using ActionList = Action[MAX_ACTIONS];
#     957                 :            : 
#     958                 :            :     //! Enumerate all possible test configurations.
#     959                 :            :     template <typename Fn>
#     960                 :            :     void ForEachMergeSetup(Fn&& fn)
#     961                 :          2 :     {
#     962                 :          2 :         ActionList arg_actions = {};
#     963                 :            :         // command_line_options do not have sections. Only iterate over SET and NEGATE
#     964                 :         14 :         ForEachNoDup(arg_actions, SET, NEGATE, [&] {
#     965                 :         14 :             ActionList conf_actions = {};
#     966                 :        742 :             ForEachNoDup(conf_actions, SET, SECTION_NEGATE, [&] {
#     967         [ +  + ]:       1484 :                 for (bool soft_set : {false, true}) {
#     968         [ +  + ]:       2968 :                     for (bool force_set : {false, true}) {
#     969         [ +  + ]:       8904 :                         for (const std::string& section : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET}) {
#     970         [ +  + ]:      26712 :                             for (const std::string& network : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET}) {
#     971         [ +  + ]:      53424 :                                 for (bool net_specific : {false, true}) {
#     972                 :      53424 :                                     fn(arg_actions, conf_actions, soft_set, force_set, section, network, net_specific);
#     973                 :      53424 :                                 }
#     974                 :      26712 :                             }
#     975                 :       8904 :                         }
#     976                 :       2968 :                     }
#     977                 :       1484 :                 }
#     978                 :        742 :             });
#     979                 :         14 :         });
#     980                 :          2 :     }
#     981                 :            : 
#     982                 :            :     //! Translate actions into a list of <key>=<value> setting strings.
#     983                 :            :     std::vector<std::string> GetValues(const ActionList& actions,
#     984                 :            :         const std::string& section,
#     985                 :            :         const std::string& name,
#     986                 :            :         const std::string& value_prefix)
#     987                 :     106848 :     {
#     988                 :     106848 :         std::vector<std::string> values;
#     989                 :     106848 :         int suffix = 0;
#     990         [ +  + ]:     283968 :         for (Action action : actions) {
#     991         [ +  + ]:     283968 :             if (action == NONE) break;
#     992                 :     228672 :             std::string prefix;
#     993 [ +  + ][ +  + ]:     228672 :             if (action == SECTION_SET || action == SECTION_NEGATE) prefix = section + ".";
#     994 [ +  + ][ +  + ]:     228672 :             if (action == SET || action == SECTION_SET) {
#     995         [ +  + ]:     343008 :                 for (int i = 0; i < 2; ++i) {
#     996                 :     228672 :                     values.push_back(prefix + name + "=" + value_prefix + ToString(++suffix));
#     997                 :     228672 :                 }
#     998                 :     114336 :             }
#     999 [ +  + ][ +  + ]:     228672 :             if (action == NEGATE || action == SECTION_NEGATE) {
#    1000                 :     114336 :                 values.push_back(prefix + "no" + name + "=1");
#    1001                 :     114336 :             }
#    1002                 :     228672 :         }
#    1003                 :     106848 :         return values;
#    1004                 :     106848 :     }
#    1005                 :            : };
#    1006                 :            : 
#    1007                 :            : // Regression test covering different ways config settings can be merged. The
#    1008                 :            : // test parses and merges settings, representing the results as strings that get
#    1009                 :            : // compared against an expected hash. To debug, the result strings can be dumped
#    1010                 :            : // to a file (see comments below).
#    1011                 :            : BOOST_FIXTURE_TEST_CASE(util_ArgsMerge, ArgsMergeTestingSetup)
#    1012                 :          2 : {
#    1013                 :          2 :     CHash256 out_sha;
#    1014                 :          2 :     FILE* out_file = nullptr;
#    1015         [ -  + ]:          2 :     if (const char* out_path = getenv("ARGS_MERGE_TEST_OUT")) {
#    1016                 :          0 :         out_file = fsbridge::fopen(out_path, "w");
#    1017         [ #  # ]:          0 :         if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
#    1018                 :          0 :     }
#    1019                 :            : 
#    1020                 :          2 :     ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions, bool soft_set, bool force_set,
#    1021                 :      53424 :                           const std::string& section, const std::string& network, bool net_specific) {
#    1022                 :      53424 :         TestArgsManager parser;
#    1023                 :      53424 :         LOCK(parser.cs_args);
#    1024                 :            : 
#    1025                 :      53424 :         std::string desc = "net=";
#    1026                 :      53424 :         desc += network;
#    1027                 :      53424 :         parser.m_network = network;
#    1028                 :            : 
#    1029         [ +  + ]:      53424 :         const std::string& name = net_specific ? "wallet" : "server";
#    1030                 :      53424 :         const std::string key = "-" + name;
#    1031                 :      53424 :         parser.AddArg(key, name, ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
#    1032         [ +  + ]:      53424 :         if (net_specific) parser.SetNetworkOnlyArg(key);
#    1033                 :            : 
#    1034                 :      53424 :         auto args = GetValues(arg_actions, section, name, "a");
#    1035                 :      53424 :         std::vector<const char*> argv = {"ignored"};
#    1036         [ +  + ]:     137376 :         for (auto& arg : args) {
#    1037                 :     137376 :             arg.insert(0, "-");
#    1038                 :     137376 :             desc += " ";
#    1039                 :     137376 :             desc += arg;
#    1040                 :     137376 :             argv.push_back(arg.c_str());
#    1041                 :     137376 :         }
#    1042                 :      53424 :         std::string error;
#    1043                 :      53424 :         BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
#    1044                 :      53424 :         BOOST_CHECK_EQUAL(error, "");
#    1045                 :            : 
#    1046                 :      53424 :         std::string conf;
#    1047         [ +  + ]:     205632 :         for (auto& conf_val : GetValues(conf_actions, section, name, "c")) {
#    1048                 :     205632 :             desc += " ";
#    1049                 :     205632 :             desc += conf_val;
#    1050                 :     205632 :             conf += conf_val;
#    1051                 :     205632 :             conf += "\n";
#    1052                 :     205632 :         }
#    1053                 :      53424 :         std::istringstream conf_stream(conf);
#    1054                 :      53424 :         BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
#    1055                 :      53424 :         BOOST_CHECK_EQUAL(error, "");
#    1056                 :            : 
#    1057         [ +  + ]:      53424 :         if (soft_set) {
#    1058                 :      26712 :             desc += " soft";
#    1059                 :      26712 :             parser.SoftSetArg(key, "soft1");
#    1060                 :      26712 :             parser.SoftSetArg(key, "soft2");
#    1061                 :      26712 :         }
#    1062                 :            : 
#    1063         [ +  + ]:      53424 :         if (force_set) {
#    1064                 :      26712 :             desc += " force";
#    1065                 :      26712 :             parser.ForceSetArg(key, "force1");
#    1066                 :      26712 :             parser.ForceSetArg(key, "force2");
#    1067                 :      26712 :         }
#    1068                 :            : 
#    1069                 :      53424 :         desc += " || ";
#    1070                 :            : 
#    1071         [ +  + ]:      53424 :         if (!parser.IsArgSet(key)) {
#    1072                 :        376 :             desc += "unset";
#    1073                 :        376 :             BOOST_CHECK(!parser.IsArgNegated(key));
#    1074                 :        376 :             BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "default");
#    1075                 :        376 :             BOOST_CHECK(parser.GetArgs(key).empty());
#    1076         [ +  + ]:      53048 :         } else if (parser.IsArgNegated(key)) {
#    1077                 :      13176 :             desc += "negated";
#    1078                 :      13176 :             BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "0");
#    1079                 :      13176 :             BOOST_CHECK(parser.GetArgs(key).empty());
#    1080                 :      39872 :         } else {
#    1081                 :      39872 :             desc += parser.GetArg(key, "default");
#    1082                 :      39872 :             desc += " |";
#    1083         [ +  + ]:      89232 :             for (const auto& arg : parser.GetArgs(key)) {
#    1084                 :      89232 :                 desc += " ";
#    1085                 :      89232 :                 desc += arg;
#    1086                 :      89232 :             }
#    1087                 :      39872 :         }
#    1088                 :            : 
#    1089                 :      53424 :         std::set<std::string> ignored = parser.GetUnsuitableSectionOnlyArgs();
#    1090         [ +  + ]:      53424 :         if (!ignored.empty()) {
#    1091                 :       1692 :             desc += " | ignored";
#    1092         [ +  + ]:       1692 :             for (const auto& arg : ignored) {
#    1093                 :       1692 :                 desc += " ";
#    1094                 :       1692 :                 desc += arg;
#    1095                 :       1692 :             }
#    1096                 :       1692 :         }
#    1097                 :            : 
#    1098                 :      53424 :         desc += "\n";
#    1099                 :            : 
#    1100                 :      53424 :         out_sha.Write(MakeUCharSpan(desc));
#    1101         [ -  + ]:      53424 :         if (out_file) {
#    1102                 :          0 :             BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
#    1103                 :          0 :         }
#    1104                 :      53424 :     });
#    1105                 :            : 
#    1106         [ -  + ]:          2 :     if (out_file) {
#    1107         [ #  # ]:          0 :         if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
#    1108                 :          0 :         out_file = nullptr;
#    1109                 :          0 :     }
#    1110                 :            : 
#    1111                 :          2 :     unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
#    1112                 :          2 :     out_sha.Finalize(out_sha_bytes);
#    1113                 :          2 :     std::string out_sha_hex = HexStr(out_sha_bytes);
#    1114                 :            : 
#    1115                 :            :     // If check below fails, should manually dump the results with:
#    1116                 :            :     //
#    1117                 :            :     //   ARGS_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ArgsMerge
#    1118                 :            :     //
#    1119                 :            :     // And verify diff against previous results to make sure the changes are expected.
#    1120                 :            :     //
#    1121                 :            :     // Results file is formatted like:
#    1122                 :            :     //
#    1123                 :            :     //   <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
#    1124                 :          2 :     BOOST_CHECK_EQUAL(out_sha_hex, "d1e436c1cd510d0ec44d5205d4b4e3bee6387d316e0075c58206cb16603f3d82");
#    1125                 :          2 : }
#    1126                 :            : 
#    1127                 :            : // Similar test as above, but for ArgsManager::GetChainName function.
#    1128                 :            : struct ChainMergeTestingSetup : public BasicTestingSetup {
#    1129                 :            :     static constexpr int MAX_ACTIONS = 2;
#    1130                 :            : 
#    1131                 :            :     enum Action { NONE, ENABLE_TEST, DISABLE_TEST, NEGATE_TEST, ENABLE_REG, DISABLE_REG, NEGATE_REG };
#    1132                 :            :     using ActionList = Action[MAX_ACTIONS];
#    1133                 :            : 
#    1134                 :            :     //! Enumerate all possible test configurations.
#    1135                 :            :     template <typename Fn>
#    1136                 :            :     void ForEachMergeSetup(Fn&& fn)
#    1137                 :          2 :     {
#    1138                 :          2 :         ActionList arg_actions = {};
#    1139                 :         74 :         ForEachNoDup(arg_actions, ENABLE_TEST, NEGATE_REG, [&] {
#    1140                 :         74 :             ActionList conf_actions = {};
#    1141                 :       2738 :             ForEachNoDup(conf_actions, ENABLE_TEST, NEGATE_REG, [&] { fn(arg_actions, conf_actions); });
#    1142                 :         74 :         });
#    1143                 :          2 :     }
#    1144                 :            : };
#    1145                 :            : 
#    1146                 :            : BOOST_FIXTURE_TEST_CASE(util_ChainMerge, ChainMergeTestingSetup)
#    1147                 :          2 : {
#    1148                 :          2 :     CHash256 out_sha;
#    1149                 :          2 :     FILE* out_file = nullptr;
#    1150         [ -  + ]:          2 :     if (const char* out_path = getenv("CHAIN_MERGE_TEST_OUT")) {
#    1151                 :          0 :         out_file = fsbridge::fopen(out_path, "w");
#    1152         [ #  # ]:          0 :         if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
#    1153                 :          0 :     }
#    1154                 :            : 
#    1155                 :       2738 :     ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions) {
#    1156                 :       2738 :         TestArgsManager parser;
#    1157                 :       2738 :         LOCK(parser.cs_args);
#    1158                 :       2738 :         parser.AddArg("-regtest", "regtest", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
#    1159                 :       2738 :         parser.AddArg("-testnet", "testnet", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
#    1160                 :            : 
#    1161         [ +  + ]:      10804 :         auto arg = [](Action action) { return action == ENABLE_TEST  ? "-testnet=1"   :
#    1162         [ +  + ]:      10804 :                                               action == DISABLE_TEST ? "-testnet=0"   :
#    1163         [ +  + ]:       9176 :                                               action == NEGATE_TEST  ? "-notestnet=1" :
#    1164         [ +  + ]:       7548 :                                               action == ENABLE_REG   ? "-regtest=1"   :
#    1165         [ +  + ]:       5920 :                                               action == DISABLE_REG  ? "-regtest=0"   :
#    1166         [ +  + ]:       4292 :                                               action == NEGATE_REG   ? "-noregtest=1" : nullptr; };
#    1167                 :            : 
#    1168                 :       2738 :         std::string desc;
#    1169                 :       2738 :         std::vector<const char*> argv = {"ignored"};
#    1170         [ +  + ]:       5402 :         for (Action action : arg_actions) {
#    1171                 :       5402 :             const char* argstr = arg(action);
#    1172         [ +  + ]:       5402 :             if (!argstr) break;
#    1173                 :       4884 :             argv.push_back(argstr);
#    1174                 :       4884 :             desc += " ";
#    1175                 :       4884 :             desc += argv.back();
#    1176                 :       4884 :         }
#    1177                 :       2738 :         std::string error;
#    1178                 :       2738 :         BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
#    1179                 :       2738 :         BOOST_CHECK_EQUAL(error, "");
#    1180                 :            : 
#    1181                 :       2738 :         std::string conf;
#    1182         [ +  + ]:       5402 :         for (Action action : conf_actions) {
#    1183                 :       5402 :             const char* argstr = arg(action);
#    1184         [ +  + ]:       5402 :             if (!argstr) break;
#    1185                 :       4884 :             desc += " ";
#    1186                 :       4884 :             desc += argstr + 1;
#    1187                 :       4884 :             conf += argstr + 1;
#    1188                 :       4884 :             conf += "\n";
#    1189                 :       4884 :         }
#    1190                 :       2738 :         std::istringstream conf_stream(conf);
#    1191                 :       2738 :         BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
#    1192                 :       2738 :         BOOST_CHECK_EQUAL(error, "");
#    1193                 :            : 
#    1194                 :       2738 :         desc += " || ";
#    1195                 :       2738 :         try {
#    1196                 :       2738 :             desc += parser.GetChainName();
#    1197                 :       2738 :         } catch (const std::runtime_error& e) {
#    1198                 :        364 :             desc += "error: ";
#    1199                 :        364 :             desc += e.what();
#    1200                 :        364 :         }
#    1201                 :       2738 :         desc += "\n";
#    1202                 :            : 
#    1203                 :       2738 :         out_sha.Write(MakeUCharSpan(desc));
#    1204         [ -  + ]:       2738 :         if (out_file) {
#    1205                 :          0 :             BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
#    1206                 :          0 :         }
#    1207                 :       2738 :     });
#    1208                 :            : 
#    1209         [ -  + ]:          2 :     if (out_file) {
#    1210         [ #  # ]:          0 :         if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
#    1211                 :          0 :         out_file = nullptr;
#    1212                 :          0 :     }
#    1213                 :            : 
#    1214                 :          2 :     unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
#    1215                 :          2 :     out_sha.Finalize(out_sha_bytes);
#    1216                 :          2 :     std::string out_sha_hex = HexStr(out_sha_bytes);
#    1217                 :            : 
#    1218                 :            :     // If check below fails, should manually dump the results with:
#    1219                 :            :     //
#    1220                 :            :     //   CHAIN_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ChainMerge
#    1221                 :            :     //
#    1222                 :            :     // And verify diff against previous results to make sure the changes are expected.
#    1223                 :            :     //
#    1224                 :            :     // Results file is formatted like:
#    1225                 :            :     //
#    1226                 :            :     //   <input> || <output>
#    1227                 :          2 :     BOOST_CHECK_EQUAL(out_sha_hex, "f263493e300023b6509963887444c41386f44b63bc30047eb8402e8c1144854c");
#    1228                 :          2 : }
#    1229                 :            : 
#    1230                 :            : BOOST_AUTO_TEST_CASE(util_ReadWriteSettings)
#    1231                 :          2 : {
#    1232                 :            :     // Test writing setting.
#    1233                 :          2 :     TestArgsManager args1;
#    1234                 :          2 :     args1.ForceSetArg("-datadir", fs::PathToString(m_path_root));
#    1235                 :          2 :     args1.LockSettings([&](util::Settings& settings) { settings.rw_settings["name"] = "value"; });
#    1236                 :          2 :     args1.WriteSettingsFile();
#    1237                 :            : 
#    1238                 :            :     // Test reading setting.
#    1239                 :          2 :     TestArgsManager args2;
#    1240                 :          2 :     args2.ForceSetArg("-datadir", fs::PathToString(m_path_root));
#    1241                 :          2 :     args2.ReadSettingsFile();
#    1242                 :          2 :     args2.LockSettings([&](util::Settings& settings) { BOOST_CHECK_EQUAL(settings.rw_settings["name"].get_str(), "value"); });
#    1243                 :            : 
#    1244                 :            :     // Test error logging, and remove previously written setting.
#    1245                 :          2 :     {
#    1246                 :          2 :         ASSERT_DEBUG_LOG("Failed renaming settings file");
#    1247                 :          2 :         fs::remove(args1.GetDataDirBase() / "settings.json");
#    1248                 :          2 :         fs::create_directory(args1.GetDataDirBase() / "settings.json");
#    1249                 :          2 :         args2.WriteSettingsFile();
#    1250                 :          2 :         fs::remove(args1.GetDataDirBase() / "settings.json");
#    1251                 :          2 :     }
#    1252                 :          2 : }
#    1253                 :            : 
#    1254                 :            : BOOST_AUTO_TEST_CASE(util_FormatMoney)
#    1255                 :          2 : {
#    1256                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
#    1257                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
#    1258                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00");
#    1259                 :            : 
#    1260                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
#    1261                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
#    1262                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
#    1263                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
#    1264                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
#    1265                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
#    1266                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
#    1267                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
#    1268                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00");
#    1269                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10");
#    1270                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
#    1271                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
#    1272                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
#    1273                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
#    1274                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
#    1275                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
#    1276                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
#    1277                 :            : 
#    1278                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807");
#    1279                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806");
#    1280                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805");
#    1281                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804");
#    1282                 :            :     // ...
#    1283                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805");
#    1284                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806");
#    1285                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807");
#    1286                 :          2 :     BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808");
#    1287                 :          2 : }
#    1288                 :            : 
#    1289                 :            : BOOST_AUTO_TEST_CASE(util_ParseMoney)
#    1290                 :          2 : {
#    1291                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
#    1292                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney(".").value(), 0);
#    1293                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.").value(), 0);
#    1294                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney(".0").value(), 0);
#    1295                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney(".6789").value(), 6789'0000);
#    1296                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("12345.").value(), COIN * 12345);
#    1297                 :            : 
#    1298                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
#    1299                 :            : 
#    1300                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
#    1301                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
#    1302                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
#    1303                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
#    1304                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
#    1305                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
#    1306                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
#    1307                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN);
#    1308                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN);
#    1309                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("   1").value(), COIN);
#    1310                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("1   ").value(), COIN);
#    1311                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("  1 ").value(), COIN);
#    1312                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
#    1313                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
#    1314                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
#    1315                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
#    1316                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
#    1317                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
#    1318                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
#    1319                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000);
#    1320                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000);
#    1321                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000);
#    1322                 :          2 :     BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
#    1323                 :            : 
#    1324                 :            :     // Parsing amount that cannot be represented should fail
#    1325                 :          2 :     BOOST_CHECK(!ParseMoney("100000000.00"));
#    1326                 :          2 :     BOOST_CHECK(!ParseMoney("0.000000001"));
#    1327                 :            : 
#    1328                 :            :     // Parsing empty string should fail
#    1329                 :          2 :     BOOST_CHECK(!ParseMoney(""));
#    1330                 :          2 :     BOOST_CHECK(!ParseMoney(" "));
#    1331                 :          2 :     BOOST_CHECK(!ParseMoney("  "));
#    1332                 :            : 
#    1333                 :            :     // Parsing two numbers should fail
#    1334                 :          2 :     BOOST_CHECK(!ParseMoney(".."));
#    1335                 :          2 :     BOOST_CHECK(!ParseMoney("0..0"));
#    1336                 :          2 :     BOOST_CHECK(!ParseMoney("1 2"));
#    1337                 :          2 :     BOOST_CHECK(!ParseMoney(" 1 2 "));
#    1338                 :          2 :     BOOST_CHECK(!ParseMoney(" 1.2 3 "));
#    1339                 :          2 :     BOOST_CHECK(!ParseMoney(" 1 2.3 "));
#    1340                 :            : 
#    1341                 :            :     // Embedded whitespace should fail
#    1342                 :          2 :     BOOST_CHECK(!ParseMoney(" -1 .2  "));
#    1343                 :          2 :     BOOST_CHECK(!ParseMoney("  1 .2  "));
#    1344                 :          2 :     BOOST_CHECK(!ParseMoney(" +1 .2  "));
#    1345                 :            : 
#    1346                 :            :     // Attempted 63 bit overflow should fail
#    1347                 :          2 :     BOOST_CHECK(!ParseMoney("92233720368.54775808"));
#    1348                 :            : 
#    1349                 :            :     // Parsing negative amounts must fail
#    1350                 :          2 :     BOOST_CHECK(!ParseMoney("-1"));
#    1351                 :            : 
#    1352                 :            :     // Parsing strings with embedded NUL characters should fail
#    1353                 :          2 :     BOOST_CHECK(!ParseMoney("\0-1"s));
#    1354                 :          2 :     BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR));
#    1355                 :          2 :     BOOST_CHECK(!ParseMoney("1\0"s));
#    1356                 :          2 : }
#    1357                 :            : 
#    1358                 :            : BOOST_AUTO_TEST_CASE(util_IsHex)
#    1359                 :          2 : {
#    1360                 :          2 :     BOOST_CHECK(IsHex("00"));
#    1361                 :          2 :     BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
#    1362                 :          2 :     BOOST_CHECK(IsHex("ff"));
#    1363                 :          2 :     BOOST_CHECK(IsHex("FF"));
#    1364                 :            : 
#    1365                 :          2 :     BOOST_CHECK(!IsHex(""));
#    1366                 :          2 :     BOOST_CHECK(!IsHex("0"));
#    1367                 :          2 :     BOOST_CHECK(!IsHex("a"));
#    1368                 :          2 :     BOOST_CHECK(!IsHex("eleven"));
#    1369                 :          2 :     BOOST_CHECK(!IsHex("00xx00"));
#    1370                 :          2 :     BOOST_CHECK(!IsHex("0x0000"));
#    1371                 :          2 : }
#    1372                 :            : 
#    1373                 :            : BOOST_AUTO_TEST_CASE(util_IsHexNumber)
#    1374                 :          2 : {
#    1375                 :          2 :     BOOST_CHECK(IsHexNumber("0x0"));
#    1376                 :          2 :     BOOST_CHECK(IsHexNumber("0"));
#    1377                 :          2 :     BOOST_CHECK(IsHexNumber("0x10"));
#    1378                 :          2 :     BOOST_CHECK(IsHexNumber("10"));
#    1379                 :          2 :     BOOST_CHECK(IsHexNumber("0xff"));
#    1380                 :          2 :     BOOST_CHECK(IsHexNumber("ff"));
#    1381                 :          2 :     BOOST_CHECK(IsHexNumber("0xFfa"));
#    1382                 :          2 :     BOOST_CHECK(IsHexNumber("Ffa"));
#    1383                 :          2 :     BOOST_CHECK(IsHexNumber("0x00112233445566778899aabbccddeeffAABBCCDDEEFF"));
#    1384                 :          2 :     BOOST_CHECK(IsHexNumber("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
#    1385                 :            : 
#    1386                 :          2 :     BOOST_CHECK(!IsHexNumber(""));   // empty string not allowed
#    1387                 :          2 :     BOOST_CHECK(!IsHexNumber("0x")); // empty string after prefix not allowed
#    1388                 :          2 :     BOOST_CHECK(!IsHexNumber("0x0 ")); // no spaces at end,
#    1389                 :          2 :     BOOST_CHECK(!IsHexNumber(" 0x0")); // or beginning,
#    1390                 :          2 :     BOOST_CHECK(!IsHexNumber("0x 0")); // or middle,
#    1391                 :          2 :     BOOST_CHECK(!IsHexNumber(" "));    // etc.
#    1392                 :          2 :     BOOST_CHECK(!IsHexNumber("0x0ga")); // invalid character
#    1393                 :          2 :     BOOST_CHECK(!IsHexNumber("x0"));    // broken prefix
#    1394                 :          2 :     BOOST_CHECK(!IsHexNumber("0x0x00")); // two prefixes not allowed
#    1395                 :            : 
#    1396                 :          2 : }
#    1397                 :            : 
#    1398                 :            : BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
#    1399                 :          2 : {
#    1400                 :          2 :     SeedInsecureRand(SeedRand::ZEROS);
#    1401         [ +  + ]:         20 :     for (int mod=2;mod<11;mod++)
#    1402                 :         18 :     {
#    1403                 :         18 :         int mask = 1;
#    1404                 :            :         // Really rough binomial confidence approximation.
#    1405                 :         18 :         int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
#    1406                 :            :         //mask is 2^ceil(log2(mod))-1
#    1407         [ +  + ]:         50 :         while(mask<mod-1)mask=(mask<<1)+1;
#    1408                 :            : 
#    1409                 :         18 :         int count = 0;
#    1410                 :            :         //How often does it get a zero from the uniform range [0,mod)?
#    1411         [ +  + ]:     180018 :         for (int i = 0; i < 10000; i++) {
#    1412                 :     180000 :             uint32_t rval;
#    1413                 :     235652 :             do{
#    1414                 :     235652 :                 rval=InsecureRand32()&mask;
#    1415         [ +  + ]:     235652 :             }while(rval>=(uint32_t)mod);
#    1416                 :     180000 :             count += rval==0;
#    1417                 :     180000 :         }
#    1418                 :         18 :         BOOST_CHECK(count<=10000/mod+err);
#    1419                 :         18 :         BOOST_CHECK(count>=10000/mod-err);
#    1420                 :         18 :     }
#    1421                 :          2 : }
#    1422                 :            : 
#    1423                 :            : BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
#    1424                 :          2 : {
#    1425                 :          2 :     BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
#    1426                 :          2 :     BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
#    1427                 :          2 :     BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
#    1428                 :          2 :     BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
#    1429                 :          2 :     BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
#    1430                 :          2 :     BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
#    1431                 :          2 :     BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
#    1432                 :          2 : }
#    1433                 :            : 
#    1434                 :            : /* Test strprintf formatting directives.
#    1435                 :            :  * Put a string before and after to ensure sanity of element sizes on stack. */
#    1436                 :            : #define B "check_prefix"
#    1437                 :            : #define E "check_postfix"
#    1438                 :            : BOOST_AUTO_TEST_CASE(strprintf_numbers)
#    1439                 :          2 : {
#    1440                 :          2 :     int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
#    1441                 :          2 :     uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
#    1442                 :          2 :     BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
#    1443                 :          2 :     BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
#    1444                 :          2 :     BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
#    1445                 :            : 
#    1446                 :          2 :     size_t st = 12345678; /* unsigned size_t test value */
#    1447                 :          2 :     ssize_t sst = -12345678; /* signed size_t test value */
#    1448                 :          2 :     BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
#    1449                 :          2 :     BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
#    1450                 :          2 :     BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
#    1451                 :            : 
#    1452                 :          2 :     ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
#    1453                 :          2 :     ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
#    1454                 :          2 :     BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
#    1455                 :          2 :     BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
#    1456                 :          2 :     BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
#    1457                 :          2 : }
#    1458                 :            : #undef B
#    1459                 :            : #undef E
#    1460                 :            : 
#    1461                 :            : /* Check for mingw/wine issue #3494
#    1462                 :            :  * Remove this test before time.ctime(0xffffffff) == 'Sun Feb  7 07:28:15 2106'
#    1463                 :            :  */
#    1464                 :            : BOOST_AUTO_TEST_CASE(gettime)
#    1465                 :          2 : {
#    1466                 :          2 :     BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0);
#    1467                 :          2 : }
#    1468                 :            : 
#    1469                 :            : BOOST_AUTO_TEST_CASE(util_time_GetTime)
#    1470                 :          2 : {
#    1471                 :          2 :     SetMockTime(111);
#    1472                 :            :     // Check that mock time does not change after a sleep
#    1473         [ +  + ]:          4 :     for (const auto& num_sleep : {0, 1}) {
#    1474                 :          4 :         UninterruptibleSleep(std::chrono::milliseconds{num_sleep});
#    1475                 :          4 :         BOOST_CHECK_EQUAL(111, GetTime()); // Deprecated time getter
#    1476                 :          4 :         BOOST_CHECK_EQUAL(111, GetTime<std::chrono::seconds>().count());
#    1477                 :          4 :         BOOST_CHECK_EQUAL(111000, GetTime<std::chrono::milliseconds>().count());
#    1478                 :          4 :         BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count());
#    1479                 :          4 :     }
#    1480                 :            : 
#    1481                 :          2 :     SetMockTime(0);
#    1482                 :            :     // Check that system time changes after a sleep
#    1483                 :          2 :     const auto ms_0 = GetTime<std::chrono::milliseconds>();
#    1484                 :          2 :     const auto us_0 = GetTime<std::chrono::microseconds>();
#    1485                 :          2 :     UninterruptibleSleep(std::chrono::milliseconds{1});
#    1486                 :          2 :     BOOST_CHECK(ms_0 < GetTime<std::chrono::milliseconds>());
#    1487                 :          2 :     BOOST_CHECK(us_0 < GetTime<std::chrono::microseconds>());
#    1488                 :          2 : }
#    1489                 :            : 
#    1490                 :            : BOOST_AUTO_TEST_CASE(test_IsDigit)
#    1491                 :          2 : {
#    1492                 :          2 :     BOOST_CHECK_EQUAL(IsDigit('0'), true);
#    1493                 :          2 :     BOOST_CHECK_EQUAL(IsDigit('1'), true);
#    1494                 :          2 :     BOOST_CHECK_EQUAL(IsDigit('8'), true);
#    1495                 :          2 :     BOOST_CHECK_EQUAL(IsDigit('9'), true);
#    1496                 :            : 
#    1497                 :          2 :     BOOST_CHECK_EQUAL(IsDigit('0' - 1), false);
#    1498                 :          2 :     BOOST_CHECK_EQUAL(IsDigit('9' + 1), false);
#    1499                 :          2 :     BOOST_CHECK_EQUAL(IsDigit(0), false);
#    1500                 :          2 :     BOOST_CHECK_EQUAL(IsDigit(1), false);
#    1501                 :          2 :     BOOST_CHECK_EQUAL(IsDigit(8), false);
#    1502                 :          2 :     BOOST_CHECK_EQUAL(IsDigit(9), false);
#    1503                 :          2 : }
#    1504                 :            : 
#    1505                 :            : /* Check for overflow */
#    1506                 :            : template <typename T>
#    1507                 :            : static void TestAddMatrixOverflow()
#    1508                 :          4 : {
#    1509                 :          4 :     constexpr T MAXI{std::numeric_limits<T>::max()};
#    1510                 :          4 :     BOOST_CHECK(!CheckedAdd(T{1}, MAXI));
#    1511                 :          4 :     BOOST_CHECK(!CheckedAdd(MAXI, MAXI));
#    1512                 :          4 :     BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI));
#    1513                 :          4 :     BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(MAXI, MAXI));
#    1514                 :            : 
#    1515                 :          4 :     BOOST_CHECK_EQUAL(0, CheckedAdd(T{0}, T{0}).value());
#    1516                 :          4 :     BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{0}, MAXI).value());
#    1517                 :          4 :     BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{1}, MAXI - 1).value());
#    1518                 :          4 :     BOOST_CHECK_EQUAL(MAXI - 1, CheckedAdd(T{1}, MAXI - 2).value());
#    1519                 :          4 :     BOOST_CHECK_EQUAL(0, SaturatingAdd(T{0}, T{0}));
#    1520                 :          4 :     BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{0}, MAXI));
#    1521                 :          4 :     BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI - 1));
#    1522                 :          4 :     BOOST_CHECK_EQUAL(MAXI - 1, SaturatingAdd(T{1}, MAXI - 2));
#    1523                 :          4 : }
#    1524                 :            : 
#    1525                 :            : /* Check for overflow or underflow */
#    1526                 :            : template <typename T>
#    1527                 :            : static void TestAddMatrix()
#    1528                 :          2 : {
#    1529                 :          2 :     TestAddMatrixOverflow<T>();
#    1530                 :          2 :     constexpr T MINI{std::numeric_limits<T>::min()};
#    1531                 :          2 :     constexpr T MAXI{std::numeric_limits<T>::max()};
#    1532                 :          2 :     BOOST_CHECK(!CheckedAdd(T{-1}, MINI));
#    1533                 :          2 :     BOOST_CHECK(!CheckedAdd(MINI, MINI));
#    1534                 :          2 :     BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI));
#    1535                 :          2 :     BOOST_CHECK_EQUAL(MINI, SaturatingAdd(MINI, MINI));
#    1536                 :            : 
#    1537                 :          2 :     BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{0}, MINI).value());
#    1538                 :          2 :     BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{-1}, MINI + 1).value());
#    1539                 :          2 :     BOOST_CHECK_EQUAL(-1, CheckedAdd(MINI, MAXI).value());
#    1540                 :          2 :     BOOST_CHECK_EQUAL(MINI + 1, CheckedAdd(T{-1}, MINI + 2).value());
#    1541                 :          2 :     BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{0}, MINI));
#    1542                 :          2 :     BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI + 1));
#    1543                 :          2 :     BOOST_CHECK_EQUAL(MINI + 1, SaturatingAdd(T{-1}, MINI + 2));
#    1544                 :          2 :     BOOST_CHECK_EQUAL(-1, SaturatingAdd(MINI, MAXI));
#    1545                 :          2 : }
#    1546                 :            : 
#    1547                 :            : BOOST_AUTO_TEST_CASE(util_overflow)
#    1548                 :          2 : {
#    1549                 :          2 :     TestAddMatrixOverflow<unsigned>();
#    1550                 :          2 :     TestAddMatrix<signed>();
#    1551                 :          2 : }
#    1552                 :            : 
#    1553                 :            : BOOST_AUTO_TEST_CASE(test_ParseInt32)
#    1554                 :          2 : {
#    1555                 :          2 :     int32_t n;
#    1556                 :            :     // Valid values
#    1557                 :          2 :     BOOST_CHECK(ParseInt32("1234", nullptr));
#    1558                 :          2 :     BOOST_CHECK(ParseInt32("0", &n) && n == 0);
#    1559                 :          2 :     BOOST_CHECK(ParseInt32("1234", &n) && n == 1234);
#    1560                 :          2 :     BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal
#    1561                 :          2 :     BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647);
#    1562                 :          2 :     BOOST_CHECK(ParseInt32("-2147483648", &n) && n == (-2147483647 - 1)); // (-2147483647 - 1) equals INT_MIN
#    1563                 :          2 :     BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
#    1564                 :          2 :     BOOST_CHECK(ParseInt32("00000000000000001234", &n) && n == 1234);
#    1565                 :          2 :     BOOST_CHECK(ParseInt32("-00000000000000001234", &n) && n == -1234);
#    1566                 :          2 :     BOOST_CHECK(ParseInt32("00000000000000000000", &n) && n == 0);
#    1567                 :          2 :     BOOST_CHECK(ParseInt32("-00000000000000000000", &n) && n == 0);
#    1568                 :            :     // Invalid values
#    1569                 :          2 :     BOOST_CHECK(!ParseInt32("", &n));
#    1570                 :          2 :     BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside
#    1571                 :          2 :     BOOST_CHECK(!ParseInt32("1 ", &n));
#    1572                 :          2 :     BOOST_CHECK(!ParseInt32("++1", &n));
#    1573                 :          2 :     BOOST_CHECK(!ParseInt32("+-1", &n));
#    1574                 :          2 :     BOOST_CHECK(!ParseInt32("-+1", &n));
#    1575                 :          2 :     BOOST_CHECK(!ParseInt32("--1", &n));
#    1576                 :          2 :     BOOST_CHECK(!ParseInt32("1a", &n));
#    1577                 :          2 :     BOOST_CHECK(!ParseInt32("aap", &n));
#    1578                 :          2 :     BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
#    1579                 :          2 :     BOOST_CHECK(!ParseInt32(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
#    1580                 :            :     // Overflow and underflow
#    1581                 :          2 :     BOOST_CHECK(!ParseInt32("-2147483649", nullptr));
#    1582                 :          2 :     BOOST_CHECK(!ParseInt32("2147483648", nullptr));
#    1583                 :          2 :     BOOST_CHECK(!ParseInt32("-32482348723847471234", nullptr));
#    1584                 :          2 :     BOOST_CHECK(!ParseInt32("32482348723847471234", nullptr));
#    1585                 :          2 : }
#    1586                 :            : 
#    1587                 :            : template <typename T>
#    1588                 :            : static void RunToIntegralTests()
#    1589                 :         16 : {
#    1590                 :         16 :     BOOST_CHECK(!ToIntegral<T>(STRING_WITH_EMBEDDED_NULL_CHAR));
#    1591                 :         16 :     BOOST_CHECK(!ToIntegral<T>(" 1"));
#    1592                 :         16 :     BOOST_CHECK(!ToIntegral<T>("1 "));
#    1593                 :         16 :     BOOST_CHECK(!ToIntegral<T>("1a"));
#    1594                 :         16 :     BOOST_CHECK(!ToIntegral<T>("1.1"));
#    1595                 :         16 :     BOOST_CHECK(!ToIntegral<T>("1.9"));
#    1596                 :         16 :     BOOST_CHECK(!ToIntegral<T>("+01.9"));
#    1597                 :         16 :     BOOST_CHECK(!ToIntegral<T>("-"));
#    1598                 :         16 :     BOOST_CHECK(!ToIntegral<T>("+"));
#    1599                 :         16 :     BOOST_CHECK(!ToIntegral<T>(" -1"));
#    1600                 :         16 :     BOOST_CHECK(!ToIntegral<T>("-1 "));
#    1601                 :         16 :     BOOST_CHECK(!ToIntegral<T>(" -1 "));
#    1602                 :         16 :     BOOST_CHECK(!ToIntegral<T>("+1"));
#    1603                 :         16 :     BOOST_CHECK(!ToIntegral<T>(" +1"));
#    1604                 :         16 :     BOOST_CHECK(!ToIntegral<T>(" +1 "));
#    1605                 :         16 :     BOOST_CHECK(!ToIntegral<T>("+-1"));
#    1606                 :         16 :     BOOST_CHECK(!ToIntegral<T>("-+1"));
#    1607                 :         16 :     BOOST_CHECK(!ToIntegral<T>("++1"));
#    1608                 :         16 :     BOOST_CHECK(!ToIntegral<T>("--1"));
#    1609                 :         16 :     BOOST_CHECK(!ToIntegral<T>(""));
#    1610                 :         16 :     BOOST_CHECK(!ToIntegral<T>("aap"));
#    1611                 :         16 :     BOOST_CHECK(!ToIntegral<T>("0x1"));
#    1612                 :         16 :     BOOST_CHECK(!ToIntegral<T>("-32482348723847471234"));
#    1613                 :         16 :     BOOST_CHECK(!ToIntegral<T>("32482348723847471234"));
#    1614                 :         16 : }
#    1615                 :            : 
#    1616                 :            : BOOST_AUTO_TEST_CASE(test_ToIntegral)
#    1617                 :          2 : {
#    1618                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("1234").value(), 1'234);
#    1619                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("0").value(), 0);
#    1620                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("01234").value(), 1'234);
#    1621                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000001234").value(), 1'234);
#    1622                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000001234").value(), -1'234);
#    1623                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000000000").value(), 0);
#    1624                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000000000").value(), 0);
#    1625                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1234").value(), -1'234);
#    1626                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1").value(), -1);
#    1627                 :            : 
#    1628                 :          2 :     RunToIntegralTests<uint64_t>();
#    1629                 :          2 :     RunToIntegralTests<int64_t>();
#    1630                 :          2 :     RunToIntegralTests<uint32_t>();
#    1631                 :          2 :     RunToIntegralTests<int32_t>();
#    1632                 :          2 :     RunToIntegralTests<uint16_t>();
#    1633                 :          2 :     RunToIntegralTests<int16_t>();
#    1634                 :          2 :     RunToIntegralTests<uint8_t>();
#    1635                 :          2 :     RunToIntegralTests<int8_t>();
#    1636                 :            : 
#    1637                 :          2 :     BOOST_CHECK(!ToIntegral<int64_t>("-9223372036854775809"));
#    1638                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int64_t>("-9223372036854775808").value(), -9'223'372'036'854'775'807LL - 1LL);
#    1639                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int64_t>("9223372036854775807").value(), 9'223'372'036'854'775'807);
#    1640                 :          2 :     BOOST_CHECK(!ToIntegral<int64_t>("9223372036854775808"));
#    1641                 :            : 
#    1642                 :          2 :     BOOST_CHECK(!ToIntegral<uint64_t>("-1"));
#    1643                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("0").value(), 0U);
#    1644                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("18446744073709551615").value(), 18'446'744'073'709'551'615ULL);
#    1645                 :          2 :     BOOST_CHECK(!ToIntegral<uint64_t>("18446744073709551616"));
#    1646                 :            : 
#    1647                 :          2 :     BOOST_CHECK(!ToIntegral<int32_t>("-2147483649"));
#    1648                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-2147483648").value(), -2'147'483'648LL);
#    1649                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int32_t>("2147483647").value(), 2'147'483'647);
#    1650                 :          2 :     BOOST_CHECK(!ToIntegral<int32_t>("2147483648"));
#    1651                 :            : 
#    1652                 :          2 :     BOOST_CHECK(!ToIntegral<uint32_t>("-1"));
#    1653                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("0").value(), 0U);
#    1654                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("4294967295").value(), 4'294'967'295U);
#    1655                 :          2 :     BOOST_CHECK(!ToIntegral<uint32_t>("4294967296"));
#    1656                 :            : 
#    1657                 :          2 :     BOOST_CHECK(!ToIntegral<int16_t>("-32769"));
#    1658                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int16_t>("-32768").value(), -32'768);
#    1659                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int16_t>("32767").value(), 32'767);
#    1660                 :          2 :     BOOST_CHECK(!ToIntegral<int16_t>("32768"));
#    1661                 :            : 
#    1662                 :          2 :     BOOST_CHECK(!ToIntegral<uint16_t>("-1"));
#    1663                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("0").value(), 0U);
#    1664                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("65535").value(), 65'535U);
#    1665                 :          2 :     BOOST_CHECK(!ToIntegral<uint16_t>("65536"));
#    1666                 :            : 
#    1667                 :          2 :     BOOST_CHECK(!ToIntegral<int8_t>("-129"));
#    1668                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int8_t>("-128").value(), -128);
#    1669                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<int8_t>("127").value(), 127);
#    1670                 :          2 :     BOOST_CHECK(!ToIntegral<int8_t>("128"));
#    1671                 :            : 
#    1672                 :          2 :     BOOST_CHECK(!ToIntegral<uint8_t>("-1"));
#    1673                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("0").value(), 0U);
#    1674                 :          2 :     BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("255").value(), 255U);
#    1675                 :          2 :     BOOST_CHECK(!ToIntegral<uint8_t>("256"));
#    1676                 :          2 : }
#    1677                 :            : 
#    1678                 :            : int64_t atoi64_legacy(const std::string& str)
#    1679                 :         16 : {
#    1680                 :         16 :     return strtoll(str.c_str(), nullptr, 10);
#    1681                 :         16 : }
#    1682                 :            : 
#    1683                 :            : BOOST_AUTO_TEST_CASE(test_LocaleIndependentAtoi)
#    1684                 :          2 : {
#    1685                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1234"), 1'234);
#    1686                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0"), 0);
#    1687                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("01234"), 1'234);
#    1688                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1234"), -1'234);
#    1689                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" 1"), 1);
#    1690                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1 "), 1);
#    1691                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1a"), 1);
#    1692                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.1"), 1);
#    1693                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.9"), 1);
#    1694                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+01.9"), 1);
#    1695                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1"), -1);
#    1696                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1"), -1);
#    1697                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1 "), -1);
#    1698                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1 "), -1);
#    1699                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+1"), 1);
#    1700                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1"), 1);
#    1701                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1 "), 1);
#    1702                 :            : 
#    1703                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+-1"), 0);
#    1704                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-+1"), 0);
#    1705                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("++1"), 0);
#    1706                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("--1"), 0);
#    1707                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(""), 0);
#    1708                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("aap"), 0);
#    1709                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0x1"), 0);
#    1710                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-32482348723847471234"), -2'147'483'647 - 1);
#    1711                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("32482348723847471234"), 2'147'483'647);
#    1712                 :            : 
#    1713                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775809"), -9'223'372'036'854'775'807LL - 1LL);
#    1714                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775808"), -9'223'372'036'854'775'807LL - 1LL);
#    1715                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775807"), 9'223'372'036'854'775'807);
#    1716                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775808"), 9'223'372'036'854'775'807);
#    1717                 :            : 
#    1718                 :          2 :     std::map<std::string, int64_t> atoi64_test_pairs = {
#    1719                 :          2 :         {"-9223372036854775809", std::numeric_limits<int64_t>::min()},
#    1720                 :          2 :         {"-9223372036854775808", -9'223'372'036'854'775'807LL - 1LL},
#    1721                 :          2 :         {"9223372036854775807", 9'223'372'036'854'775'807},
#    1722                 :          2 :         {"9223372036854775808", std::numeric_limits<int64_t>::max()},
#    1723                 :          2 :         {"+-", 0},
#    1724                 :          2 :         {"0x1", 0},
#    1725                 :          2 :         {"ox1", 0},
#    1726                 :          2 :         {"", 0},
#    1727                 :          2 :     };
#    1728                 :            : 
#    1729         [ +  + ]:         16 :     for (const auto& pair : atoi64_test_pairs) {
#    1730                 :         16 :         BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), pair.second);
#    1731                 :         16 :     }
#    1732                 :            : 
#    1733                 :            :     // Ensure legacy compatibility with previous versions of Bitcoin Core's atoi64
#    1734         [ +  + ]:         16 :     for (const auto& pair : atoi64_test_pairs) {
#    1735                 :         16 :         BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), atoi64_legacy(pair.first));
#    1736                 :         16 :     }
#    1737                 :            : 
#    1738                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("-1"), 0U);
#    1739                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("0"), 0U);
#    1740                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551615"), 18'446'744'073'709'551'615ULL);
#    1741                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551616"), 18'446'744'073'709'551'615ULL);
#    1742                 :            : 
#    1743                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483649"), -2'147'483'648LL);
#    1744                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483648"), -2'147'483'648LL);
#    1745                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483647"), 2'147'483'647);
#    1746                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483648"), 2'147'483'647);
#    1747                 :            : 
#    1748                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("-1"), 0U);
#    1749                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("0"), 0U);
#    1750                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967295"), 4'294'967'295U);
#    1751                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967296"), 4'294'967'295U);
#    1752                 :            : 
#    1753                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32769"), -32'768);
#    1754                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32768"), -32'768);
#    1755                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32767"), 32'767);
#    1756                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32768"), 32'767);
#    1757                 :            : 
#    1758                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("-1"), 0U);
#    1759                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("0"), 0U);
#    1760                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65535"), 65'535U);
#    1761                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65536"), 65'535U);
#    1762                 :            : 
#    1763                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-129"), -128);
#    1764                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-128"), -128);
#    1765                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("127"), 127);
#    1766                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("128"), 127);
#    1767                 :            : 
#    1768                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("-1"), 0U);
#    1769                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("0"), 0U);
#    1770                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("255"), 255U);
#    1771                 :          2 :     BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("256"), 255U);
#    1772                 :          2 : }
#    1773                 :            : 
#    1774                 :            : BOOST_AUTO_TEST_CASE(test_ParseInt64)
#    1775                 :          2 : {
#    1776                 :          2 :     int64_t n;
#    1777                 :            :     // Valid values
#    1778                 :          2 :     BOOST_CHECK(ParseInt64("1234", nullptr));
#    1779                 :          2 :     BOOST_CHECK(ParseInt64("0", &n) && n == 0LL);
#    1780                 :          2 :     BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL);
#    1781                 :          2 :     BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal
#    1782                 :          2 :     BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL);
#    1783                 :          2 :     BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL);
#    1784                 :          2 :     BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == (int64_t)9223372036854775807);
#    1785                 :          2 :     BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == (int64_t)-9223372036854775807-1);
#    1786                 :          2 :     BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL);
#    1787                 :            :     // Invalid values
#    1788                 :          2 :     BOOST_CHECK(!ParseInt64("", &n));
#    1789                 :          2 :     BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside
#    1790                 :          2 :     BOOST_CHECK(!ParseInt64("1 ", &n));
#    1791                 :          2 :     BOOST_CHECK(!ParseInt64("1a", &n));
#    1792                 :          2 :     BOOST_CHECK(!ParseInt64("aap", &n));
#    1793                 :          2 :     BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex
#    1794                 :          2 :     BOOST_CHECK(!ParseInt64(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
#    1795                 :            :     // Overflow and underflow
#    1796                 :          2 :     BOOST_CHECK(!ParseInt64("-9223372036854775809", nullptr));
#    1797                 :          2 :     BOOST_CHECK(!ParseInt64("9223372036854775808", nullptr));
#    1798                 :          2 :     BOOST_CHECK(!ParseInt64("-32482348723847471234", nullptr));
#    1799                 :          2 :     BOOST_CHECK(!ParseInt64("32482348723847471234", nullptr));
#    1800                 :          2 : }
#    1801                 :            : 
#    1802                 :            : BOOST_AUTO_TEST_CASE(test_ParseUInt8)
#    1803                 :          2 : {
#    1804                 :          2 :     uint8_t n;
#    1805                 :            :     // Valid values
#    1806                 :          2 :     BOOST_CHECK(ParseUInt8("255", nullptr));
#    1807                 :          2 :     BOOST_CHECK(ParseUInt8("0", &n) && n == 0);
#    1808                 :          2 :     BOOST_CHECK(ParseUInt8("255", &n) && n == 255);
#    1809                 :          2 :     BOOST_CHECK(ParseUInt8("0255", &n) && n == 255); // no octal
#    1810                 :          2 :     BOOST_CHECK(ParseUInt8("255", &n) && n == static_cast<uint8_t>(255));
#    1811                 :          2 :     BOOST_CHECK(ParseUInt8("+255", &n) && n == 255);
#    1812                 :          2 :     BOOST_CHECK(ParseUInt8("00000000000000000012", &n) && n == 12);
#    1813                 :          2 :     BOOST_CHECK(ParseUInt8("00000000000000000000", &n) && n == 0);
#    1814                 :            :     // Invalid values
#    1815                 :          2 :     BOOST_CHECK(!ParseUInt8("-00000000000000000000", &n));
#    1816                 :          2 :     BOOST_CHECK(!ParseUInt8("", &n));
#    1817                 :          2 :     BOOST_CHECK(!ParseUInt8(" 1", &n)); // no padding inside
#    1818                 :          2 :     BOOST_CHECK(!ParseUInt8(" -1", &n));
#    1819                 :          2 :     BOOST_CHECK(!ParseUInt8("++1", &n));
#    1820                 :          2 :     BOOST_CHECK(!ParseUInt8("+-1", &n));
#    1821                 :          2 :     BOOST_CHECK(!ParseUInt8("-+1", &n));
#    1822                 :          2 :     BOOST_CHECK(!ParseUInt8("--1", &n));
#    1823                 :          2 :     BOOST_CHECK(!ParseUInt8("-1", &n));
#    1824                 :          2 :     BOOST_CHECK(!ParseUInt8("1 ", &n));
#    1825                 :          2 :     BOOST_CHECK(!ParseUInt8("1a", &n));
#    1826                 :          2 :     BOOST_CHECK(!ParseUInt8("aap", &n));
#    1827                 :          2 :     BOOST_CHECK(!ParseUInt8("0x1", &n)); // no hex
#    1828                 :          2 :     BOOST_CHECK(!ParseUInt8(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
#    1829                 :            :     // Overflow and underflow
#    1830                 :          2 :     BOOST_CHECK(!ParseUInt8("-255", &n));
#    1831                 :          2 :     BOOST_CHECK(!ParseUInt8("256", &n));
#    1832                 :          2 :     BOOST_CHECK(!ParseUInt8("-123", &n));
#    1833                 :          2 :     BOOST_CHECK(!ParseUInt8("-123", nullptr));
#    1834                 :          2 :     BOOST_CHECK(!ParseUInt8("256", nullptr));
#    1835                 :          2 : }
#    1836                 :            : 
#    1837                 :            : BOOST_AUTO_TEST_CASE(test_ParseUInt16)
#    1838                 :          2 : {
#    1839                 :          2 :     uint16_t n;
#    1840                 :            :     // Valid values
#    1841                 :          2 :     BOOST_CHECK(ParseUInt16("1234", nullptr));
#    1842                 :          2 :     BOOST_CHECK(ParseUInt16("0", &n) && n == 0);
#    1843                 :          2 :     BOOST_CHECK(ParseUInt16("1234", &n) && n == 1234);
#    1844                 :          2 :     BOOST_CHECK(ParseUInt16("01234", &n) && n == 1234); // no octal
#    1845                 :          2 :     BOOST_CHECK(ParseUInt16("65535", &n) && n == static_cast<uint16_t>(65535));
#    1846                 :          2 :     BOOST_CHECK(ParseUInt16("+65535", &n) && n == 65535);
#    1847                 :          2 :     BOOST_CHECK(ParseUInt16("00000000000000000012", &n) && n == 12);
#    1848                 :          2 :     BOOST_CHECK(ParseUInt16("00000000000000000000", &n) && n == 0);
#    1849                 :            :     // Invalid values
#    1850                 :          2 :     BOOST_CHECK(!ParseUInt16("-00000000000000000000", &n));
#    1851                 :          2 :     BOOST_CHECK(!ParseUInt16("", &n));
#    1852                 :          2 :     BOOST_CHECK(!ParseUInt16(" 1", &n)); // no padding inside
#    1853                 :          2 :     BOOST_CHECK(!ParseUInt16(" -1", &n));
#    1854                 :          2 :     BOOST_CHECK(!ParseUInt16("++1", &n));
#    1855                 :          2 :     BOOST_CHECK(!ParseUInt16("+-1", &n));
#    1856                 :          2 :     BOOST_CHECK(!ParseUInt16("-+1", &n));
#    1857                 :          2 :     BOOST_CHECK(!ParseUInt16("--1", &n));
#    1858                 :          2 :     BOOST_CHECK(!ParseUInt16("-1", &n));
#    1859                 :          2 :     BOOST_CHECK(!ParseUInt16("1 ", &n));
#    1860                 :          2 :     BOOST_CHECK(!ParseUInt16("1a", &n));
#    1861                 :          2 :     BOOST_CHECK(!ParseUInt16("aap", &n));
#    1862                 :          2 :     BOOST_CHECK(!ParseUInt16("0x1", &n)); // no hex
#    1863                 :          2 :     BOOST_CHECK(!ParseUInt16(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
#    1864                 :            :     // Overflow and underflow
#    1865                 :          2 :     BOOST_CHECK(!ParseUInt16("-65535", &n));
#    1866                 :          2 :     BOOST_CHECK(!ParseUInt16("65536", &n));
#    1867                 :          2 :     BOOST_CHECK(!ParseUInt16("-123", &n));
#    1868                 :          2 :     BOOST_CHECK(!ParseUInt16("-123", nullptr));
#    1869                 :          2 :     BOOST_CHECK(!ParseUInt16("65536", nullptr));
#    1870                 :          2 : }
#    1871                 :            : 
#    1872                 :            : BOOST_AUTO_TEST_CASE(test_ParseUInt32)
#    1873                 :          2 : {
#    1874                 :          2 :     uint32_t n;
#    1875                 :            :     // Valid values
#    1876                 :          2 :     BOOST_CHECK(ParseUInt32("1234", nullptr));
#    1877                 :          2 :     BOOST_CHECK(ParseUInt32("0", &n) && n == 0);
#    1878                 :          2 :     BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234);
#    1879                 :          2 :     BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal
#    1880                 :          2 :     BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647);
#    1881                 :          2 :     BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648);
#    1882                 :          2 :     BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295);
#    1883                 :          2 :     BOOST_CHECK(ParseUInt32("+1234", &n) && n == 1234);
#    1884                 :          2 :     BOOST_CHECK(ParseUInt32("00000000000000001234", &n) && n == 1234);
#    1885                 :          2 :     BOOST_CHECK(ParseUInt32("00000000000000000000", &n) && n == 0);
#    1886                 :            :     // Invalid values
#    1887                 :          2 :     BOOST_CHECK(!ParseUInt32("-00000000000000000000", &n));
#    1888                 :          2 :     BOOST_CHECK(!ParseUInt32("", &n));
#    1889                 :          2 :     BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside
#    1890                 :          2 :     BOOST_CHECK(!ParseUInt32(" -1", &n));
#    1891                 :          2 :     BOOST_CHECK(!ParseUInt32("++1", &n));
#    1892                 :          2 :     BOOST_CHECK(!ParseUInt32("+-1", &n));
#    1893                 :          2 :     BOOST_CHECK(!ParseUInt32("-+1", &n));
#    1894                 :          2 :     BOOST_CHECK(!ParseUInt32("--1", &n));
#    1895                 :          2 :     BOOST_CHECK(!ParseUInt32("-1", &n));
#    1896                 :          2 :     BOOST_CHECK(!ParseUInt32("1 ", &n));
#    1897                 :          2 :     BOOST_CHECK(!ParseUInt32("1a", &n));
#    1898                 :          2 :     BOOST_CHECK(!ParseUInt32("aap", &n));
#    1899                 :          2 :     BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
#    1900                 :          2 :     BOOST_CHECK(!ParseUInt32(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
#    1901                 :            :     // Overflow and underflow
#    1902                 :          2 :     BOOST_CHECK(!ParseUInt32("-2147483648", &n));
#    1903                 :          2 :     BOOST_CHECK(!ParseUInt32("4294967296", &n));
#    1904                 :          2 :     BOOST_CHECK(!ParseUInt32("-1234", &n));
#    1905                 :          2 :     BOOST_CHECK(!ParseUInt32("-32482348723847471234", nullptr));
#    1906                 :          2 :     BOOST_CHECK(!ParseUInt32("32482348723847471234", nullptr));
#    1907                 :          2 : }
#    1908                 :            : 
#    1909                 :            : BOOST_AUTO_TEST_CASE(test_ParseUInt64)
#    1910                 :          2 : {
#    1911                 :          2 :     uint64_t n;
#    1912                 :            :     // Valid values
#    1913                 :          2 :     BOOST_CHECK(ParseUInt64("1234", nullptr));
#    1914                 :          2 :     BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL);
#    1915                 :          2 :     BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL);
#    1916                 :          2 :     BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal
#    1917                 :          2 :     BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL);
#    1918                 :          2 :     BOOST_CHECK(ParseUInt64("9223372036854775807", &n) && n == 9223372036854775807ULL);
#    1919                 :          2 :     BOOST_CHECK(ParseUInt64("9223372036854775808", &n) && n == 9223372036854775808ULL);
#    1920                 :          2 :     BOOST_CHECK(ParseUInt64("18446744073709551615", &n) && n == 18446744073709551615ULL);
#    1921                 :            :     // Invalid values
#    1922                 :          2 :     BOOST_CHECK(!ParseUInt64("", &n));
#    1923                 :          2 :     BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside
#    1924                 :          2 :     BOOST_CHECK(!ParseUInt64(" -1", &n));
#    1925                 :          2 :     BOOST_CHECK(!ParseUInt64("1 ", &n));
#    1926                 :          2 :     BOOST_CHECK(!ParseUInt64("1a", &n));
#    1927                 :          2 :     BOOST_CHECK(!ParseUInt64("aap", &n));
#    1928                 :          2 :     BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex
#    1929                 :          2 :     BOOST_CHECK(!ParseUInt64(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
#    1930                 :            :     // Overflow and underflow
#    1931                 :          2 :     BOOST_CHECK(!ParseUInt64("-9223372036854775809", nullptr));
#    1932                 :          2 :     BOOST_CHECK(!ParseUInt64("18446744073709551616", nullptr));
#    1933                 :          2 :     BOOST_CHECK(!ParseUInt64("-32482348723847471234", nullptr));
#    1934                 :          2 :     BOOST_CHECK(!ParseUInt64("-2147483648", &n));
#    1935                 :          2 :     BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n));
#    1936                 :          2 :     BOOST_CHECK(!ParseUInt64("-1234", &n));
#    1937                 :          2 : }
#    1938                 :            : 
#    1939                 :            : BOOST_AUTO_TEST_CASE(test_FormatParagraph)
#    1940                 :          2 : {
#    1941                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
#    1942                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
#    1943                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test");
#    1944                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
#    1945                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
#    1946                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest");
#    1947                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n    test");
#    1948                 :            : 
#    1949                 :            :     // Make sure we don't indent a fully-new line following a too-long line ending
#    1950                 :          2 :     BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n    test\nabc");
#    1951                 :            : 
#    1952                 :          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");
#    1953                 :            : 
#    1954                 :            :     // Test wrap length is exact
#    1955                 :          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");
#    1956                 :          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");
#    1957                 :            :     // Indent should be included in length of lines
#    1958                 :          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");
#    1959                 :            : 
#    1960                 :          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.");
#    1961                 :          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.");
#    1962                 :          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.");
#    1963                 :          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.");
#    1964                 :          2 : }
#    1965                 :            : 
#    1966                 :            : BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
#    1967                 :          2 : {
#    1968                 :          2 :     std::vector<std::string> comments;
#    1969                 :          2 :     comments.push_back(std::string("comment1"));
#    1970                 :          2 :     std::vector<std::string> comments2;
#    1971                 :          2 :     comments2.push_back(std::string("comment1"));
#    1972                 :          2 :     comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
#    1973                 :          2 :     BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:9.99.0/"));
#    1974                 :          2 :     BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:9.99.0(comment1)/"));
#    1975                 :          2 :     BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:9.99.0(comment1; Comment2; .,_?@-; )/"));
#    1976                 :          2 : }
#    1977                 :            : 
#    1978                 :            : BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
#    1979                 :          2 : {
#    1980                 :          2 :     int64_t amount = 0;
#    1981                 :          2 :     BOOST_CHECK(ParseFixedPoint("0", 8, &amount));
#    1982                 :          2 :     BOOST_CHECK_EQUAL(amount, 0LL);
#    1983                 :          2 :     BOOST_CHECK(ParseFixedPoint("1", 8, &amount));
#    1984                 :          2 :     BOOST_CHECK_EQUAL(amount, 100000000LL);
#    1985                 :          2 :     BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount));
#    1986                 :          2 :     BOOST_CHECK_EQUAL(amount, 0LL);
#    1987                 :          2 :     BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount));
#    1988                 :          2 :     BOOST_CHECK_EQUAL(amount, -10000000LL);
#    1989                 :          2 :     BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount));
#    1990                 :          2 :     BOOST_CHECK_EQUAL(amount, 110000000LL);
#    1991                 :          2 :     BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount));
#    1992                 :          2 :     BOOST_CHECK_EQUAL(amount, 110000000LL);
#    1993                 :          2 :     BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount));
#    1994                 :          2 :     BOOST_CHECK_EQUAL(amount, 1100000000LL);
#    1995                 :          2 :     BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount));
#    1996                 :          2 :     BOOST_CHECK_EQUAL(amount, 11000000LL);
#    1997                 :          2 :     BOOST_CHECK(ParseFixedPoint("1000", 8, &amount));
#    1998                 :          2 :     BOOST_CHECK_EQUAL(amount, 100000000000LL);
#    1999                 :          2 :     BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount));
#    2000                 :          2 :     BOOST_CHECK_EQUAL(amount, -100000000000LL);
#    2001                 :          2 :     BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount));
#    2002                 :          2 :     BOOST_CHECK_EQUAL(amount, 1LL);
#    2003                 :          2 :     BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount));
#    2004                 :          2 :     BOOST_CHECK_EQUAL(amount, 1LL);
#    2005                 :          2 :     BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount));
#    2006                 :          2 :     BOOST_CHECK_EQUAL(amount, -1LL);
#    2007                 :          2 :     BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount));
#    2008                 :          2 :     BOOST_CHECK_EQUAL(amount, 100000000000000001LL);
#    2009                 :          2 :     BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount));
#    2010                 :          2 :     BOOST_CHECK_EQUAL(amount, 999999999999999999LL);
#    2011                 :          2 :     BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount));
#    2012                 :          2 :     BOOST_CHECK_EQUAL(amount, -999999999999999999LL);
#    2013                 :            : 
#    2014                 :          2 :     BOOST_CHECK(!ParseFixedPoint("", 8, &amount));
#    2015                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-", 8, &amount));
#    2016                 :          2 :     BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount));
#    2017                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount));
#    2018                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount));
#    2019                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount));
#    2020                 :          2 :     BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount));
#    2021                 :          2 :     BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount));
#    2022                 :          2 :     BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount));
#    2023                 :          2 :     BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount));
#    2024                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount));
#    2025                 :          2 :     BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount));
#    2026                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount));
#    2027                 :          2 :     BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount));
#    2028                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount));
#    2029                 :          2 :     BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount));
#    2030                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount));
#    2031                 :          2 :     BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount));
#    2032                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount));
#    2033                 :          2 :     BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount));
#    2034                 :          2 :     BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount));
#    2035                 :          2 :     BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount));
#    2036                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount));
#    2037                 :          2 :     BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount));
#    2038                 :          2 :     BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
#    2039                 :          2 :     BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
#    2040                 :          2 :     BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));
#    2041                 :            : 
#    2042                 :            :     // Test with 3 decimal places for fee rates in sat/vB.
#    2043                 :          2 :     BOOST_CHECK(ParseFixedPoint("0.001", 3, &amount));
#    2044                 :          2 :     BOOST_CHECK_EQUAL(amount, CAmount{1});
#    2045                 :          2 :     BOOST_CHECK(!ParseFixedPoint("0.0009", 3, &amount));
#    2046                 :          2 :     BOOST_CHECK(!ParseFixedPoint("31.00100001", 3, &amount));
#    2047                 :          2 :     BOOST_CHECK(!ParseFixedPoint("31.0011", 3, &amount));
#    2048                 :          2 :     BOOST_CHECK(!ParseFixedPoint("31.99999999", 3, &amount));
#    2049                 :          2 :     BOOST_CHECK(!ParseFixedPoint("31.999999999999999999999", 3, &amount));
#    2050                 :          2 : }
#    2051                 :            : 
#    2052                 :            : static void TestOtherThread(fs::path dirname, std::string lockname, bool *result)
#    2053                 :          1 : {
#    2054                 :          1 :     *result = LockDirectory(dirname, lockname);
#    2055                 :          1 : }
#    2056                 :            : 
#    2057                 :            : #ifndef WIN32 // Cannot do this test on WIN32 due to lack of fork()
#    2058                 :            : static constexpr char LockCommand = 'L';
#    2059                 :            : static constexpr char UnlockCommand = 'U';
#    2060                 :            : static constexpr char ExitCommand = 'X';
#    2061                 :            : 
#    2062                 :            : [[noreturn]] static void TestOtherProcess(fs::path dirname, std::string lockname, int fd)
#    2063                 :          1 : {
#    2064                 :          1 :     char ch;
#    2065                 :          5 :     while (true) {
#    2066                 :          5 :         int rv = read(fd, &ch, 1); // Wait for command
#    2067                 :          5 :         assert(rv == 1);
#    2068                 :          0 :         switch(ch) {
#    2069         [ +  + ]:          3 :         case LockCommand:
#    2070                 :          3 :             ch = LockDirectory(dirname, lockname);
#    2071                 :          3 :             rv = write(fd, &ch, 1);
#    2072                 :          3 :             assert(rv == 1);
#    2073                 :          0 :             break;
#    2074         [ +  + ]:          1 :         case UnlockCommand:
#    2075                 :          1 :             ReleaseDirectoryLocks();
#    2076                 :          1 :             ch = true; // Always succeeds
#    2077                 :          1 :             rv = write(fd, &ch, 1);
#    2078                 :          1 :             assert(rv == 1);
#    2079                 :          0 :             break;
#    2080         [ +  + ]:          1 :         case ExitCommand:
#    2081                 :          1 :             close(fd);
#    2082                 :          1 :             exit(0);
#    2083         [ -  + ]:          1 :         default:
#    2084                 :          1 :             assert(0);
#    2085                 :          5 :         }
#    2086                 :          5 :     }
#    2087                 :          1 : }
#    2088                 :            : #endif
#    2089                 :            : 
#    2090                 :            : BOOST_AUTO_TEST_CASE(test_LockDirectory)
#    2091                 :          2 : {
#    2092                 :          2 :     fs::path dirname = m_args.GetDataDirBase() / "lock_dir";
#    2093                 :          2 :     const std::string lockname = ".lock";
#    2094                 :          2 : #ifndef WIN32
#    2095                 :            :     // Revert SIGCHLD to default, otherwise boost.test will catch and fail on
#    2096                 :            :     // it: there is BOOST_TEST_IGNORE_SIGCHLD but that only works when defined
#    2097                 :            :     // at build-time of the boost library
#    2098                 :          2 :     void (*old_handler)(int) = signal(SIGCHLD, SIG_DFL);
#    2099                 :            : 
#    2100                 :            :     // Fork another process for testing before creating the lock, so that we
#    2101                 :            :     // won't fork while holding the lock (which might be undefined, and is not
#    2102                 :            :     // relevant as test case as that is avoided with -daemonize).
#    2103                 :          2 :     int fd[2];
#    2104                 :          2 :     BOOST_CHECK_EQUAL(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0);
#    2105                 :          2 :     pid_t pid = fork();
#    2106         [ +  + ]:          2 :     if (!pid) {
#    2107                 :          1 :         BOOST_CHECK_EQUAL(close(fd[1]), 0); // Child: close parent end
#    2108                 :          1 :         TestOtherProcess(dirname, lockname, fd[0]);
#    2109                 :          1 :     }
#    2110                 :          2 :     BOOST_CHECK_EQUAL(close(fd[0]), 0); // Parent: close child end
#    2111                 :          2 : #endif
#    2112                 :            :     // Lock on non-existent directory should fail
#    2113                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), false);
#    2114                 :            : 
#    2115                 :          2 :     fs::create_directories(dirname);
#    2116                 :            : 
#    2117                 :            :     // Probing lock on new directory should succeed
#    2118                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
#    2119                 :            : 
#    2120                 :            :     // Persistent lock on new directory should succeed
#    2121                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), true);
#    2122                 :            : 
#    2123                 :            :     // Another lock on the directory from the same thread should succeed
#    2124                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), true);
#    2125                 :            : 
#    2126                 :            :     // Another lock on the directory from a different thread within the same process should succeed
#    2127                 :          2 :     bool threadresult;
#    2128                 :          2 :     std::thread thr(TestOtherThread, dirname, lockname, &threadresult);
#    2129                 :          2 :     thr.join();
#    2130                 :          2 :     BOOST_CHECK_EQUAL(threadresult, true);
#    2131                 :          2 : #ifndef WIN32
#    2132                 :            :     // Try to acquire lock in child process while we're holding it, this should fail.
#    2133                 :          2 :     char ch;
#    2134                 :          2 :     BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
#    2135                 :          2 :     BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
#    2136                 :          2 :     BOOST_CHECK_EQUAL((bool)ch, false);
#    2137                 :            : 
#    2138                 :            :     // Give up our lock
#    2139                 :          2 :     ReleaseDirectoryLocks();
#    2140                 :            :     // Probing lock from our side now should succeed, but not hold on to the lock.
#    2141                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
#    2142                 :            : 
#    2143                 :            :     // Try to acquire the lock in the child process, this should be successful.
#    2144                 :          2 :     BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
#    2145                 :          2 :     BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
#    2146                 :          2 :     BOOST_CHECK_EQUAL((bool)ch, true);
#    2147                 :            : 
#    2148                 :            :     // When we try to probe the lock now, it should fail.
#    2149                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), false);
#    2150                 :            : 
#    2151                 :            :     // Unlock the lock in the child process
#    2152                 :          2 :     BOOST_CHECK_EQUAL(write(fd[1], &UnlockCommand, 1), 1);
#    2153                 :          2 :     BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
#    2154                 :          2 :     BOOST_CHECK_EQUAL((bool)ch, true);
#    2155                 :            : 
#    2156                 :            :     // When we try to probe the lock now, it should succeed.
#    2157                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
#    2158                 :            : 
#    2159                 :            :     // Re-lock the lock in the child process, then wait for it to exit, check
#    2160                 :            :     // successful return. After that, we check that exiting the process
#    2161                 :            :     // has released the lock as we would expect by probing it.
#    2162                 :          2 :     int processstatus;
#    2163                 :          2 :     BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
#    2164                 :          2 :     BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1);
#    2165                 :          2 :     BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid);
#    2166                 :          2 :     BOOST_CHECK_EQUAL(processstatus, 0);
#    2167                 :          2 :     BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
#    2168                 :            : 
#    2169                 :            :     // Restore SIGCHLD
#    2170                 :          2 :     signal(SIGCHLD, old_handler);
#    2171                 :          2 :     BOOST_CHECK_EQUAL(close(fd[1]), 0); // Close our side of the socketpair
#    2172                 :          2 : #endif
#    2173                 :            :     // Clean up
#    2174                 :          2 :     ReleaseDirectoryLocks();
#    2175                 :          2 :     fs::remove_all(dirname);
#    2176                 :          2 : }
#    2177                 :            : 
#    2178                 :            : BOOST_AUTO_TEST_CASE(test_DirIsWritable)
#    2179                 :          1 : {
#    2180                 :            :     // Should be able to write to the data dir.
#    2181                 :          1 :     fs::path tmpdirname = m_args.GetDataDirBase();
#    2182                 :          1 :     BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
#    2183                 :            : 
#    2184                 :            :     // Should not be able to write to a non-existent dir.
#    2185                 :          1 :     tmpdirname = GetUniquePath(tmpdirname);
#    2186                 :          1 :     BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), false);
#    2187                 :            : 
#    2188                 :          1 :     fs::create_directory(tmpdirname);
#    2189                 :            :     // Should be able to write to it now.
#    2190                 :          1 :     BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
#    2191                 :          1 :     fs::remove(tmpdirname);
#    2192                 :          1 : }
#    2193                 :            : 
#    2194                 :            : BOOST_AUTO_TEST_CASE(test_ToLower)
#    2195                 :          1 : {
#    2196                 :          1 :     BOOST_CHECK_EQUAL(ToLower('@'), '@');
#    2197                 :          1 :     BOOST_CHECK_EQUAL(ToLower('A'), 'a');
#    2198                 :          1 :     BOOST_CHECK_EQUAL(ToLower('Z'), 'z');
#    2199                 :          1 :     BOOST_CHECK_EQUAL(ToLower('['), '[');
#    2200                 :          1 :     BOOST_CHECK_EQUAL(ToLower(0), 0);
#    2201                 :          1 :     BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
#    2202                 :            : 
#    2203                 :          1 :     BOOST_CHECK_EQUAL(ToLower(""), "");
#    2204                 :          1 :     BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl");
#    2205                 :          1 :     BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff");
#    2206                 :          1 : }
#    2207                 :            : 
#    2208                 :            : BOOST_AUTO_TEST_CASE(test_ToUpper)
#    2209                 :          1 : {
#    2210                 :          1 :     BOOST_CHECK_EQUAL(ToUpper('`'), '`');
#    2211                 :          1 :     BOOST_CHECK_EQUAL(ToUpper('a'), 'A');
#    2212                 :          1 :     BOOST_CHECK_EQUAL(ToUpper('z'), 'Z');
#    2213                 :          1 :     BOOST_CHECK_EQUAL(ToUpper('{'), '{');
#    2214                 :          1 :     BOOST_CHECK_EQUAL(ToUpper(0), 0);
#    2215                 :          1 :     BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
#    2216                 :            : 
#    2217                 :          1 :     BOOST_CHECK_EQUAL(ToUpper(""), "");
#    2218                 :          1 :     BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL");
#    2219                 :          1 :     BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff");
#    2220                 :          1 : }
#    2221                 :            : 
#    2222                 :            : BOOST_AUTO_TEST_CASE(test_Capitalize)
#    2223                 :          1 : {
#    2224                 :          1 :     BOOST_CHECK_EQUAL(Capitalize(""), "");
#    2225                 :          1 :     BOOST_CHECK_EQUAL(Capitalize("bitcoin"), "Bitcoin");
#    2226                 :          1 :     BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff");
#    2227                 :          1 : }
#    2228                 :            : 
#    2229                 :            : static std::string SpanToStr(const Span<const char>& span)
#    2230                 :         28 : {
#    2231                 :         28 :     return std::string(span.begin(), span.end());
#    2232                 :         28 : }
#    2233                 :            : 
#    2234                 :            : BOOST_AUTO_TEST_CASE(test_spanparsing)
#    2235                 :          1 : {
#    2236                 :          1 :     using namespace spanparsing;
#    2237                 :          1 :     std::string input;
#    2238                 :          1 :     Span<const char> sp;
#    2239                 :          1 :     bool success;
#    2240                 :            : 
#    2241                 :            :     // Const(...): parse a constant, update span to skip it if successful
#    2242                 :          1 :     input = "MilkToastHoney";
#    2243                 :          1 :     sp = input;
#    2244                 :          1 :     success = Const("", sp); // empty
#    2245                 :          1 :     BOOST_CHECK(success);
#    2246                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
#    2247                 :            : 
#    2248                 :          1 :     success = Const("Milk", sp);
#    2249                 :          1 :     BOOST_CHECK(success);
#    2250                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
#    2251                 :            : 
#    2252                 :          1 :     success = Const("Bread", sp);
#    2253                 :          1 :     BOOST_CHECK(!success);
#    2254                 :            : 
#    2255                 :          1 :     success = Const("Toast", sp);
#    2256                 :          1 :     BOOST_CHECK(success);
#    2257                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
#    2258                 :            : 
#    2259                 :          1 :     success = Const("Honeybadger", sp);
#    2260                 :          1 :     BOOST_CHECK(!success);
#    2261                 :            : 
#    2262                 :          1 :     success = Const("Honey", sp);
#    2263                 :          1 :     BOOST_CHECK(success);
#    2264                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "");
#    2265                 :            : 
#    2266                 :            :     // Func(...): parse a function call, update span to argument if successful
#    2267                 :          1 :     input = "Foo(Bar(xy,z()))";
#    2268                 :          1 :     sp = input;
#    2269                 :            : 
#    2270                 :          1 :     success = Func("FooBar", sp);
#    2271                 :          1 :     BOOST_CHECK(!success);
#    2272                 :            : 
#    2273                 :          1 :     success = Func("Foo(", sp);
#    2274                 :          1 :     BOOST_CHECK(!success);
#    2275                 :            : 
#    2276                 :          1 :     success = Func("Foo", sp);
#    2277                 :          1 :     BOOST_CHECK(success);
#    2278                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "Bar(xy,z())");
#    2279                 :            : 
#    2280                 :          1 :     success = Func("Bar", sp);
#    2281                 :          1 :     BOOST_CHECK(success);
#    2282                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "xy,z()");
#    2283                 :            : 
#    2284                 :          1 :     success = Func("xy", sp);
#    2285                 :          1 :     BOOST_CHECK(!success);
#    2286                 :            : 
#    2287                 :            :     // Expr(...): return expression that span begins with, update span to skip it
#    2288                 :          1 :     Span<const char> result;
#    2289                 :            : 
#    2290                 :          1 :     input = "(n*(n-1))/2";
#    2291                 :          1 :     sp = input;
#    2292                 :          1 :     result = Expr(sp);
#    2293                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2");
#    2294                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), "");
#    2295                 :            : 
#    2296                 :          1 :     input = "foo,bar";
#    2297                 :          1 :     sp = input;
#    2298                 :          1 :     result = Expr(sp);
#    2299                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(result), "foo");
#    2300                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar");
#    2301                 :            : 
#    2302                 :          1 :     input = "(aaaaa,bbbbb()),c";
#    2303                 :          1 :     sp = input;
#    2304                 :          1 :     result = Expr(sp);
#    2305                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())");
#    2306                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), ",c");
#    2307                 :            : 
#    2308                 :          1 :     input = "xyz)foo";
#    2309                 :          1 :     sp = input;
#    2310                 :          1 :     result = Expr(sp);
#    2311                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(result), "xyz");
#    2312                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo");
#    2313                 :            : 
#    2314                 :          1 :     input = "((a),(b),(c)),xxx";
#    2315                 :          1 :     sp = input;
#    2316                 :          1 :     result = Expr(sp);
#    2317                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))");
#    2318                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
#    2319                 :            : 
#    2320                 :            :     // Split(...): split a string on every instance of sep, return vector
#    2321                 :          1 :     std::vector<Span<const char>> results;
#    2322                 :            : 
#    2323                 :          1 :     input = "xxx";
#    2324                 :          1 :     results = Split(input, 'x');
#    2325                 :          1 :     BOOST_CHECK_EQUAL(results.size(), 4U);
#    2326                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
#    2327                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[1]), "");
#    2328                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[2]), "");
#    2329                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
#    2330                 :            : 
#    2331                 :          1 :     input = "one#two#three";
#    2332                 :          1 :     results = Split(input, '-');
#    2333                 :          1 :     BOOST_CHECK_EQUAL(results.size(), 1U);
#    2334                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three");
#    2335                 :            : 
#    2336                 :          1 :     input = "one#two#three";
#    2337                 :          1 :     results = Split(input, '#');
#    2338                 :          1 :     BOOST_CHECK_EQUAL(results.size(), 3U);
#    2339                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one");
#    2340                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two");
#    2341                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
#    2342                 :            : 
#    2343                 :          1 :     input = "*foo*bar*";
#    2344                 :          1 :     results = Split(input, '*');
#    2345                 :          1 :     BOOST_CHECK_EQUAL(results.size(), 4U);
#    2346                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
#    2347                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo");
#    2348                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar");
#    2349                 :          1 :     BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
#    2350                 :          1 : }
#    2351                 :            : 
#    2352                 :            : BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
#    2353                 :          1 : {
#    2354                 :            :     // ASCII and UTF-8 must pass through unaltered.
#    2355                 :          1 :     BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
#    2356                 :            :     // Newlines must pass through unaltered.
#    2357                 :          1 :     BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
#    2358                 :            :     // Other control characters are escaped in C syntax.
#    2359                 :          1 :     BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
#    2360                 :            :     // Embedded NULL characters are escaped too.
#    2361                 :          1 :     const std::string NUL("O\x00O", 3);
#    2362                 :          1 :     BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
#    2363                 :          1 : }
#    2364                 :            : 
#    2365                 :            : namespace {
#    2366                 :            : 
#    2367                 :            : struct Tracker
#    2368                 :            : {
#    2369                 :            :     //! Points to the original object (possibly itself) we moved/copied from
#    2370                 :            :     const Tracker* origin;
#    2371                 :            :     //! How many copies where involved between the original object and this one (moves are not counted)
#    2372                 :            :     int copies;
#    2373                 :            : 
#    2374                 :          3 :     Tracker() noexcept : origin(this), copies(0) {}
#    2375                 :         10 :     Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
#    2376                 :         13 :     Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
#    2377                 :            :     Tracker& operator=(const Tracker& t) noexcept
#    2378                 :          0 :     {
#    2379                 :          0 :         origin = t.origin;
#    2380                 :          0 :         copies = t.copies + 1;
#    2381                 :          0 :         return *this;
#    2382                 :          0 :     }
#    2383                 :            : };
#    2384                 :            : 
#    2385                 :            : }
#    2386                 :            : 
#    2387                 :            : BOOST_AUTO_TEST_CASE(test_tracked_vector)
#    2388                 :          1 : {
#    2389                 :          1 :     Tracker t1;
#    2390                 :          1 :     Tracker t2;
#    2391                 :          1 :     Tracker t3;
#    2392                 :            : 
#    2393                 :          1 :     BOOST_CHECK(t1.origin == &t1);
#    2394                 :          1 :     BOOST_CHECK(t2.origin == &t2);
#    2395                 :          1 :     BOOST_CHECK(t3.origin == &t3);
#    2396                 :            : 
#    2397                 :          1 :     auto v1 = Vector(t1);
#    2398                 :          1 :     BOOST_CHECK_EQUAL(v1.size(), 1U);
#    2399                 :          1 :     BOOST_CHECK(v1[0].origin == &t1);
#    2400                 :          1 :     BOOST_CHECK_EQUAL(v1[0].copies, 1);
#    2401                 :            : 
#    2402                 :          1 :     auto v2 = Vector(std::move(t2));
#    2403                 :          1 :     BOOST_CHECK_EQUAL(v2.size(), 1U);
#    2404                 :          1 :     BOOST_CHECK(v2[0].origin == &t2);
#    2405                 :          1 :     BOOST_CHECK_EQUAL(v2[0].copies, 0);
#    2406                 :            : 
#    2407                 :          1 :     auto v3 = Vector(t1, std::move(t2));
#    2408                 :          1 :     BOOST_CHECK_EQUAL(v3.size(), 2U);
#    2409                 :          1 :     BOOST_CHECK(v3[0].origin == &t1);
#    2410                 :          1 :     BOOST_CHECK(v3[1].origin == &t2);
#    2411                 :          1 :     BOOST_CHECK_EQUAL(v3[0].copies, 1);
#    2412                 :          1 :     BOOST_CHECK_EQUAL(v3[1].copies, 0);
#    2413                 :            : 
#    2414                 :          1 :     auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
#    2415                 :          1 :     BOOST_CHECK_EQUAL(v4.size(), 3U);
#    2416                 :          1 :     BOOST_CHECK(v4[0].origin == &t1);
#    2417                 :          1 :     BOOST_CHECK(v4[1].origin == &t2);
#    2418                 :          1 :     BOOST_CHECK(v4[2].origin == &t3);
#    2419                 :          1 :     BOOST_CHECK_EQUAL(v4[0].copies, 1);
#    2420                 :          1 :     BOOST_CHECK_EQUAL(v4[1].copies, 1);
#    2421                 :          1 :     BOOST_CHECK_EQUAL(v4[2].copies, 0);
#    2422                 :            : 
#    2423                 :          1 :     auto v5 = Cat(v1, v4);
#    2424                 :          1 :     BOOST_CHECK_EQUAL(v5.size(), 4U);
#    2425                 :          1 :     BOOST_CHECK(v5[0].origin == &t1);
#    2426                 :          1 :     BOOST_CHECK(v5[1].origin == &t1);
#    2427                 :          1 :     BOOST_CHECK(v5[2].origin == &t2);
#    2428                 :          1 :     BOOST_CHECK(v5[3].origin == &t3);
#    2429                 :          1 :     BOOST_CHECK_EQUAL(v5[0].copies, 2);
#    2430                 :          1 :     BOOST_CHECK_EQUAL(v5[1].copies, 2);
#    2431                 :          1 :     BOOST_CHECK_EQUAL(v5[2].copies, 2);
#    2432                 :          1 :     BOOST_CHECK_EQUAL(v5[3].copies, 1);
#    2433                 :            : 
#    2434                 :          1 :     auto v6 = Cat(std::move(v1), v3);
#    2435                 :          1 :     BOOST_CHECK_EQUAL(v6.size(), 3U);
#    2436                 :          1 :     BOOST_CHECK(v6[0].origin == &t1);
#    2437                 :          1 :     BOOST_CHECK(v6[1].origin == &t1);
#    2438                 :          1 :     BOOST_CHECK(v6[2].origin == &t2);
#    2439                 :          1 :     BOOST_CHECK_EQUAL(v6[0].copies, 1);
#    2440                 :          1 :     BOOST_CHECK_EQUAL(v6[1].copies, 2);
#    2441                 :          1 :     BOOST_CHECK_EQUAL(v6[2].copies, 1);
#    2442                 :            : 
#    2443                 :          1 :     auto v7 = Cat(v2, std::move(v4));
#    2444                 :          1 :     BOOST_CHECK_EQUAL(v7.size(), 4U);
#    2445                 :          1 :     BOOST_CHECK(v7[0].origin == &t2);
#    2446                 :          1 :     BOOST_CHECK(v7[1].origin == &t1);
#    2447                 :          1 :     BOOST_CHECK(v7[2].origin == &t2);
#    2448                 :          1 :     BOOST_CHECK(v7[3].origin == &t3);
#    2449                 :          1 :     BOOST_CHECK_EQUAL(v7[0].copies, 1);
#    2450                 :          1 :     BOOST_CHECK_EQUAL(v7[1].copies, 1);
#    2451                 :          1 :     BOOST_CHECK_EQUAL(v7[2].copies, 1);
#    2452                 :          1 :     BOOST_CHECK_EQUAL(v7[3].copies, 0);
#    2453                 :            : 
#    2454                 :          1 :     auto v8 = Cat(std::move(v2), std::move(v3));
#    2455                 :          1 :     BOOST_CHECK_EQUAL(v8.size(), 3U);
#    2456                 :          1 :     BOOST_CHECK(v8[0].origin == &t2);
#    2457                 :          1 :     BOOST_CHECK(v8[1].origin == &t1);
#    2458                 :          1 :     BOOST_CHECK(v8[2].origin == &t2);
#    2459                 :          1 :     BOOST_CHECK_EQUAL(v8[0].copies, 0);
#    2460                 :          1 :     BOOST_CHECK_EQUAL(v8[1].copies, 1);
#    2461                 :          1 :     BOOST_CHECK_EQUAL(v8[2].copies, 0);
#    2462                 :          1 : }
#    2463                 :            : 
#    2464                 :            : BOOST_AUTO_TEST_CASE(message_sign)
#    2465                 :          1 : {
#    2466                 :          1 :     const std::array<unsigned char, 32> privkey_bytes = {
#    2467                 :            :         // just some random data
#    2468                 :            :         // derived address from this private key: 15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs
#    2469                 :          1 :         0xD9, 0x7F, 0x51, 0x08, 0xF1, 0x1C, 0xDA, 0x6E,
#    2470                 :          1 :         0xEE, 0xBA, 0xAA, 0x42, 0x0F, 0xEF, 0x07, 0x26,
#    2471                 :          1 :         0xB1, 0xF8, 0x98, 0x06, 0x0B, 0x98, 0x48, 0x9F,
#    2472                 :          1 :         0xA3, 0x09, 0x84, 0x63, 0xC0, 0x03, 0x28, 0x66
#    2473                 :          1 :     };
#    2474                 :            : 
#    2475                 :          1 :     const std::string message = "Trust no one";
#    2476                 :            : 
#    2477                 :          1 :     const std::string expected_signature =
#    2478                 :          1 :         "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=";
#    2479                 :            : 
#    2480                 :          1 :     CKey privkey;
#    2481                 :          1 :     std::string generated_signature;
#    2482                 :            : 
#    2483                 :          1 :     BOOST_REQUIRE_MESSAGE(!privkey.IsValid(),
#    2484                 :          1 :         "Confirm the private key is invalid");
#    2485                 :            : 
#    2486                 :          1 :     BOOST_CHECK_MESSAGE(!MessageSign(privkey, message, generated_signature),
#    2487                 :          1 :         "Sign with an invalid private key");
#    2488                 :            : 
#    2489                 :          1 :     privkey.Set(privkey_bytes.begin(), privkey_bytes.end(), true);
#    2490                 :            : 
#    2491                 :          1 :     BOOST_REQUIRE_MESSAGE(privkey.IsValid(),
#    2492                 :          1 :         "Confirm the private key is valid");
#    2493                 :            : 
#    2494                 :          1 :     BOOST_CHECK_MESSAGE(MessageSign(privkey, message, generated_signature),
#    2495                 :          1 :         "Sign with a valid private key");
#    2496                 :            : 
#    2497                 :          1 :     BOOST_CHECK_EQUAL(expected_signature, generated_signature);
#    2498                 :          1 : }
#    2499                 :            : 
#    2500                 :            : BOOST_AUTO_TEST_CASE(message_verify)
#    2501                 :          1 : {
#    2502                 :          1 :     BOOST_CHECK_EQUAL(
#    2503                 :          1 :         MessageVerify(
#    2504                 :          1 :             "invalid address",
#    2505                 :          1 :             "signature should be irrelevant",
#    2506                 :          1 :             "message too"),
#    2507                 :          1 :         MessageVerificationResult::ERR_INVALID_ADDRESS);
#    2508                 :            : 
#    2509                 :          1 :     BOOST_CHECK_EQUAL(
#    2510                 :          1 :         MessageVerify(
#    2511                 :          1 :             "3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
#    2512                 :          1 :             "signature should be irrelevant",
#    2513                 :          1 :             "message too"),
#    2514                 :          1 :         MessageVerificationResult::ERR_ADDRESS_NO_KEY);
#    2515                 :            : 
#    2516                 :          1 :     BOOST_CHECK_EQUAL(
#    2517                 :          1 :         MessageVerify(
#    2518                 :          1 :             "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
#    2519                 :          1 :             "invalid signature, not in base64 encoding",
#    2520                 :          1 :             "message should be irrelevant"),
#    2521                 :          1 :         MessageVerificationResult::ERR_MALFORMED_SIGNATURE);
#    2522                 :            : 
#    2523                 :          1 :     BOOST_CHECK_EQUAL(
#    2524                 :          1 :         MessageVerify(
#    2525                 :          1 :             "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
#    2526                 :          1 :             "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
#    2527                 :          1 :             "message should be irrelevant"),
#    2528                 :          1 :         MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED);
#    2529                 :            : 
#    2530                 :          1 :     BOOST_CHECK_EQUAL(
#    2531                 :          1 :         MessageVerify(
#    2532                 :          1 :             "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
#    2533                 :          1 :             "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
#    2534                 :          1 :             "I never signed this"),
#    2535                 :          1 :         MessageVerificationResult::ERR_NOT_SIGNED);
#    2536                 :            : 
#    2537                 :          1 :     BOOST_CHECK_EQUAL(
#    2538                 :          1 :         MessageVerify(
#    2539                 :          1 :             "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
#    2540                 :          1 :             "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
#    2541                 :          1 :             "Trust no one"),
#    2542                 :          1 :         MessageVerificationResult::OK);
#    2543                 :            : 
#    2544                 :          1 :     BOOST_CHECK_EQUAL(
#    2545                 :          1 :         MessageVerify(
#    2546                 :          1 :             "11canuhp9X2NocwCq7xNrQYTmUgZAnLK3",
#    2547                 :          1 :             "IIcaIENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzIAaHRtbCeDZINyavx14=",
#    2548                 :          1 :             "Trust me"),
#    2549                 :          1 :         MessageVerificationResult::OK);
#    2550                 :          1 : }
#    2551                 :            : 
#    2552                 :            : BOOST_AUTO_TEST_CASE(message_hash)
#    2553                 :          1 : {
#    2554                 :          1 :     const std::string unsigned_tx = "...";
#    2555                 :          1 :     const std::string prefixed_message =
#    2556                 :          1 :         std::string(1, (char)MESSAGE_MAGIC.length()) +
#    2557                 :          1 :         MESSAGE_MAGIC +
#    2558                 :          1 :         std::string(1, (char)unsigned_tx.length()) +
#    2559                 :          1 :         unsigned_tx;
#    2560                 :            : 
#    2561                 :          1 :     const uint256 signature_hash = Hash(unsigned_tx);
#    2562                 :          1 :     const uint256 message_hash1 = Hash(prefixed_message);
#    2563                 :          1 :     const uint256 message_hash2 = MessageHash(unsigned_tx);
#    2564                 :            : 
#    2565                 :          1 :     BOOST_CHECK_EQUAL(message_hash1, message_hash2);
#    2566                 :          1 :     BOOST_CHECK_NE(message_hash1, signature_hash);
#    2567                 :          1 : }
#    2568                 :            : 
#    2569                 :            : BOOST_AUTO_TEST_CASE(remove_prefix)
#    2570                 :          1 : {
#    2571                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("./util/system.h", "./"), "util/system.h");
#    2572                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("foo", "foo"), "");
#    2573                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o");
#    2574                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("foo", "f"), "oo");
#    2575                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo");
#    2576                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("fo", "foo"), "fo");
#    2577                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f");
#    2578                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("", "foo"), "");
#    2579                 :          1 :     BOOST_CHECK_EQUAL(RemovePrefix("", ""), "");
#    2580                 :          1 : }
#    2581                 :            : 
#    2582                 :            : BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
#    2583                 :          1 : {
#    2584                 :          1 :     auto noop = ByteUnit::NOOP;
#    2585                 :            : 
#    2586                 :            :     // no multiplier
#    2587                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("1", noop).value(), 1);
#    2588                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("0", noop).value(), 0);
#    2589                 :            : 
#    2590                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("1k", noop).value(), 1000ULL);
#    2591                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("1K", noop).value(), 1ULL << 10);
#    2592                 :            : 
#    2593                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("2m", noop).value(), 2'000'000ULL);
#    2594                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2ULL << 20);
#    2595                 :            : 
#    2596                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("3g", noop).value(), 3'000'000'000ULL);
#    2597                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("3G", noop).value(), 3ULL << 30);
#    2598                 :            : 
#    2599                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("4t", noop).value(), 4'000'000'000'000ULL);
#    2600                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("4T", noop).value(), 4ULL << 40);
#    2601                 :            : 
#    2602                 :            :     // check default multiplier
#    2603                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("5", ByteUnit::K).value(), 5ULL << 10);
#    2604                 :            : 
#    2605                 :            :     // NaN
#    2606                 :          1 :     BOOST_CHECK(!ParseByteUnits("", noop));
#    2607                 :          1 :     BOOST_CHECK(!ParseByteUnits("foo", noop));
#    2608                 :            : 
#    2609                 :            :     // whitespace
#    2610                 :          1 :     BOOST_CHECK(!ParseByteUnits("123m ", noop));
#    2611                 :          1 :     BOOST_CHECK(!ParseByteUnits(" 123m", noop));
#    2612                 :            : 
#    2613                 :            :     // no +-
#    2614                 :          1 :     BOOST_CHECK(!ParseByteUnits("-123m", noop));
#    2615                 :          1 :     BOOST_CHECK(!ParseByteUnits("+123m", noop));
#    2616                 :            : 
#    2617                 :            :     // zero padding
#    2618                 :          1 :     BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20ULL << 20);
#    2619                 :            : 
#    2620                 :            :     // fractions not allowed
#    2621                 :          1 :     BOOST_CHECK(!ParseByteUnits("0.5T", noop));
#    2622                 :            : 
#    2623                 :            :     // overflow
#    2624                 :          1 :     BOOST_CHECK(!ParseByteUnits("18446744073709551615g", noop));
#    2625                 :            : 
#    2626                 :            :     // invalid unit
#    2627                 :          1 :     BOOST_CHECK(!ParseByteUnits("1x", noop));
#    2628                 :          1 : }
#    2629                 :            : 
#    2630                 :            : BOOST_AUTO_TEST_CASE(util_ReadBinaryFile)
#    2631                 :          1 : {
#    2632                 :          1 :     fs::path tmpfolder = m_args.GetDataDirBase();
#    2633                 :          1 :     fs::path tmpfile = tmpfolder / "read_binary.dat";
#    2634                 :          1 :     std::string expected_text;
#    2635         [ +  + ]:         31 :     for (int i = 0; i < 30; i++) {
#    2636                 :         30 :         expected_text += "0123456789";
#    2637                 :         30 :     }
#    2638                 :          1 :     {
#    2639                 :          1 :         std::ofstream file{tmpfile};
#    2640                 :          1 :         file << expected_text;
#    2641                 :          1 :     }
#    2642                 :          1 :     {
#    2643                 :            :         // read all contents in file
#    2644                 :          1 :         auto [valid, text] = ReadBinaryFile(tmpfile);
#    2645                 :          1 :         BOOST_CHECK(valid);
#    2646                 :          1 :         BOOST_CHECK_EQUAL(text, expected_text);
#    2647                 :          1 :     }
#    2648                 :          1 :     {
#    2649                 :            :         // read half contents in file
#    2650                 :          1 :         auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2);
#    2651                 :          1 :         BOOST_CHECK(valid);
#    2652                 :          1 :         BOOST_CHECK_EQUAL(text, expected_text.substr(0, expected_text.size() / 2));
#    2653                 :          1 :     }
#    2654                 :          1 :     {
#    2655                 :            :         // read from non-existent file
#    2656                 :          1 :         fs::path invalid_file = tmpfolder / "invalid_binary.dat";
#    2657                 :          1 :         auto [valid, text] = ReadBinaryFile(invalid_file);
#    2658                 :          1 :         BOOST_CHECK(!valid);
#    2659                 :          1 :         BOOST_CHECK(text.empty());
#    2660                 :          1 :     }
#    2661                 :          1 : }
#    2662                 :            : 
#    2663                 :            : BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
#    2664                 :          1 : {
#    2665                 :          1 :     fs::path tmpfolder = m_args.GetDataDirBase();
#    2666                 :          1 :     fs::path tmpfile = tmpfolder / "write_binary.dat";
#    2667                 :          1 :     std::string expected_text = "bitcoin";
#    2668                 :          1 :     auto valid = WriteBinaryFile(tmpfile, expected_text);
#    2669                 :          1 :     std::string actual_text;
#    2670                 :          1 :     std::ifstream file{tmpfile};
#    2671                 :          1 :     file >> actual_text;
#    2672                 :          1 :     BOOST_CHECK(valid);
#    2673                 :          1 :     BOOST_CHECK_EQUAL(actual_text, expected_text);
#    2674                 :          1 : }
#    2675                 :            : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a