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__anonff3dab6b0b11::Tracker1988 Tracker() noexcept : origin(this), copies(0) {}
Tracker__anonff3dab6b0b11::Tracker1989 Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
Tracker__anonff3dab6b0b11::Tracker1990 Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
operator =__anonff3dab6b0b11::Tracker1991 Tracker& operator=(const Tracker& t) noexcept
1992 {
1993 origin = t.origin;
1994 copies = t.copies + 1;
1995 return *this;
1996 }
operator =__anonff3dab6b0b11::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