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