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