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