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