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