Bitcoin Core 31.99.0
P2P Digital Currency
util_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-present 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 <clientversion.h>
7#include <compat/compat.h>
8#include <hash.h>
9#include <key.h>
10#include <script/parsing.h>
11#include <span.h>
12#include <sync.h>
13#include <test/util/common.h>
14#include <test/util/random.h>
16#include <test/util/time.h>
17#include <uint256.h>
18#include <univalue.h>
19#include <util/bitdeque.h>
20#include <util/byte_units.h>
21#include <util/fs.h>
22#include <util/fs_helpers.h>
23#include <util/moneystr.h>
24#include <util/overflow.h>
25#include <util/readwritefile.h>
26#include <util/strencodings.h>
27#include <util/string.h>
28#include <util/time.h>
29#include <util/tokenbucket.h>
30#include <util/vector.h>
31
32#include <array>
33#include <cmath>
34#include <cstdint>
35#include <cstring>
36#include <fstream>
37#include <limits>
38#include <map>
39#include <optional>
40#include <string>
41#include <thread>
42#include <type_traits>
43#include <utility>
44#include <vector>
45
46#include <sys/types.h>
47
48#ifndef WIN32
49#include <sys/wait.h>
50#endif
51
52#include <boost/test/unit_test.hpp>
53
54using namespace std::literals;
55using namespace util::hex_literals;
57using util::Join;
61using util::Split;
65
66static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s};
67
68/* defined in logging.cpp */
69namespace BCLog {
70 std::string LogEscapeMessage(std::string_view str);
71}
72
74
75namespace {
76class NoCopyOrMove
77{
78public:
79 int i;
80 explicit NoCopyOrMove(int i) : i{i} { }
81
82 NoCopyOrMove() = delete;
83 NoCopyOrMove(const NoCopyOrMove&) = delete;
84 NoCopyOrMove(NoCopyOrMove&&) = delete;
85 NoCopyOrMove& operator=(const NoCopyOrMove&) = delete;
86 NoCopyOrMove& operator=(NoCopyOrMove&&) = delete;
87
88 operator bool() const { return i != 0; }
89
90 int get_ip1() { return i + 1; }
91 bool test()
92 {
93 // Check that Assume can be used within a lambda and still call methods
94 [&]() { Assume(get_ip1()); }();
95 return Assume(get_ip1() != 5);
96 }
97};
98} // namespace
99
101{
102 // Check that Assert can forward
103 const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2));
104 // Check that Assert works on lvalues and rvalues
105 const int two = *Assert(p_two);
106 Assert(two == 2);
107 Assert(true);
108 // Check that Assume can be used as unary expression
109 const bool result{Assume(two == 2)};
110 Assert(result);
111
112 // Check that Assert doesn't require copy/move
113 NoCopyOrMove x{9};
114 Assert(x).i += 3;
115 Assert(x).test();
116
117 // Check nested Asserts
118 BOOST_CHECK_EQUAL(Assert((Assert(x).test() ? 3 : 0)), 3);
119
120 // Check -Wdangling-gsl does not trigger when copying the int. (It would
121 // trigger on "const int&")
122 const int nine{*Assert(std::optional<int>{9})};
123 BOOST_CHECK_EQUAL(9, nine);
124}
125
126BOOST_AUTO_TEST_CASE(util_criticalsection)
127{
129
130 do {
131 LOCK(cs);
132 break;
133
134 BOOST_ERROR("break was swallowed!");
135 } while(0);
136
137 do {
138 TRY_LOCK(cs, lockTest);
139 if (lockTest) {
140 BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
141 break;
142 }
143
144 BOOST_ERROR("break was swallowed!");
145 } while(0);
146}
147
148constexpr char HEX_PARSE_INPUT[] = "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f";
149constexpr uint8_t HEX_PARSE_OUTPUT[] = {
150 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
151 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
152 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
153 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
154 0x5f
155};
156static_assert((sizeof(HEX_PARSE_INPUT) - 1) == 2 * sizeof(HEX_PARSE_OUTPUT));
158{
159 std::vector<unsigned char> result;
160
161 // Basic test vector
162 std::vector<unsigned char> expected(std::begin(HEX_PARSE_OUTPUT), std::end(HEX_PARSE_OUTPUT));
163 constexpr std::array<std::byte, 65> hex_literal_array{operator""_hex<util::detail::Hex(HEX_PARSE_INPUT)>()};
164 auto hex_literal_span{MakeUCharSpan(hex_literal_array)};
165 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end());
166
167 const std::vector<std::byte> hex_literal_vector{operator""_hex_v<util::detail::Hex(HEX_PARSE_INPUT)>()};
168 auto hex_literal_vec_span = MakeUCharSpan(hex_literal_vector);
169 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_vec_span.begin(), hex_literal_vec_span.end(), expected.begin(), expected.end());
170
171 constexpr std::array<uint8_t, 65> hex_literal_array_uint8{operator""_hex_u8<util::detail::Hex(HEX_PARSE_INPUT)>()};
172 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_array_uint8.begin(), hex_literal_array_uint8.end(), expected.begin(), expected.end());
173
174 result = operator""_hex_v_u8<util::detail::Hex(HEX_PARSE_INPUT)>();
175 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
176
177 result = ParseHex(HEX_PARSE_INPUT);
178 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
179
180 result = TryParseHex<uint8_t>(HEX_PARSE_INPUT).value();
181 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
182
183 // Spaces between bytes must be supported
184 expected = {0x12, 0x34, 0x56, 0x78};
185 result = ParseHex("12 34 56 78");
186 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
187 result = TryParseHex<uint8_t>("12 34 56 78").value();
188 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
189
190 // Leading space must be supported
191 expected = {0x89, 0x34, 0x56, 0x78};
192 result = ParseHex(" 89 34 56 78");
193 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
194 result = TryParseHex<uint8_t>(" 89 34 56 78").value();
195 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
196
197 // Mixed case and spaces are supported
198 expected = {0xff, 0xaa};
199 result = ParseHex(" Ff aA ");
200 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
201 result = TryParseHex<uint8_t>(" Ff aA ").value();
202 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
203
204 // Empty string is supported
205 static_assert(""_hex.empty());
206 static_assert(""_hex_u8.empty());
207 BOOST_CHECK_EQUAL(""_hex_v.size(), 0);
208 BOOST_CHECK_EQUAL(""_hex_v_u8.size(), 0);
209 BOOST_CHECK_EQUAL(ParseHex("").size(), 0);
210 BOOST_CHECK_EQUAL(TryParseHex<uint8_t>("").value().size(), 0);
211
212 // Spaces between nibbles is treated as invalid
213 BOOST_CHECK_EQUAL(ParseHex("AAF F").size(), 0);
214 BOOST_CHECK(!TryParseHex("AAF F").has_value());
215
216 // Embedded null is treated as invalid
217 const std::string with_embedded_null{" 11 "s
218 " \0 "
219 " 22 "s};
220 BOOST_CHECK_EQUAL(with_embedded_null.size(), 11);
221 BOOST_CHECK_EQUAL(ParseHex(with_embedded_null).size(), 0);
222 BOOST_CHECK(!TryParseHex(with_embedded_null).has_value());
223
224 // Non-hex is treated as invalid
225 BOOST_CHECK_EQUAL(ParseHex("1234 invalid 1234").size(), 0);
226 BOOST_CHECK(!TryParseHex("1234 invalid 1234").has_value());
227
228 // Truncated input is treated as invalid
229 BOOST_CHECK_EQUAL(ParseHex("12 3").size(), 0);
230 BOOST_CHECK(!TryParseHex("12 3").has_value());
231}
232
233BOOST_AUTO_TEST_CASE(consteval_hex_digit)
234{
239}
240
242{
244 BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.last(0)), "");
245 BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.first(0)), "");
246
247 {
248 constexpr std::string_view out_exp{"04678afdb0"};
249 constexpr std::span in_s{HEX_PARSE_OUTPUT, out_exp.size() / 2};
250 const std::span<const uint8_t> in_u{MakeUCharSpan(in_s)};
251 const std::span<const std::byte> in_b{MakeByteSpan(in_s)};
252
253 BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
254 BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
255 BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
256 }
257
258 {
259 auto input = std::string();
260 for (size_t i=0; i<256; ++i) {
261 input.push_back(static_cast<char>(i));
262 }
263
264 auto hex = HexStr(input);
265 BOOST_TEST_REQUIRE(hex.size() == 512);
266 static constexpr auto hexmap = std::string_view("0123456789abcdef");
267 for (size_t i = 0; i < 256; ++i) {
268 auto upper = hexmap.find(hex[i * 2]);
269 auto lower = hexmap.find(hex[i * 2 + 1]);
270 BOOST_TEST_REQUIRE(upper != std::string_view::npos);
271 BOOST_TEST_REQUIRE(lower != std::string_view::npos);
272 BOOST_TEST_REQUIRE(i == upper*16 + lower);
273 }
274 }
275}
276
277BOOST_AUTO_TEST_CASE(span_write_bytes)
278{
279 std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}};
280 const auto mut_bytes{MakeWritableByteSpan(mut_arr)};
281 mut_bytes[1] = std::byte{0x11};
282 BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa);
283 BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11);
284}
285
287{
288 // Normal version
289 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), "");
290 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo");
291 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar");
292
293 // Version with unary operator
294 const auto op_upper = [](const std::string& s) { return ToUpper(s); };
295 BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), "");
296 BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO");
297 BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR");
298}
299
300BOOST_AUTO_TEST_CASE(util_ReplaceAll)
301{
302 const std::string original("A test \"%s\" string '%s'.");
303 auto test_replaceall = [&original](const std::string& search, const std::string& substitute, const std::string& expected) {
304 auto test = original;
305 ReplaceAll(test, search, substitute);
306 BOOST_CHECK_EQUAL(test, expected);
307 };
308
309 test_replaceall("", "foo", original);
310 test_replaceall(original, "foo", "foo");
311 test_replaceall("%s", "foo", "A test \"foo\" string 'foo'.");
312 test_replaceall("\"", "foo", "A test foo%sfoo string '%s'.");
313 test_replaceall("'", "foo", "A test \"%s\" string foo%sfoo.");
314}
315
316BOOST_AUTO_TEST_CASE(util_TrimString)
317{
318 BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar");
319 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");
320 BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar");
321 BOOST_CHECK_EQUAL(TrimStringView("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n ");
322 BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar");
323 BOOST_CHECK_EQUAL(TrimStringView("foo bar", "fobar"), " ");
324 BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7));
325 BOOST_CHECK_EQUAL(TrimStringView(std::string(" foo ", 5)), std::string("foo", 3));
326 BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2));
327 BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6));
328 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));
329 BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), "");
330}
331
332BOOST_AUTO_TEST_CASE(util_ParseISO8601DateTime)
333{
334 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1969-12-31T23:59:59Z").value(), -1);
335 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z").value(), 0);
336 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:01Z").value(), 1);
337 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:01Z").value(), 946684801);
338 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z").value(), 1317425777);
339 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2100-12-31T23:59:59Z").value(), 4133980799);
340 BOOST_CHECK_EQUAL(ParseISO8601DateTime("9999-12-31T23:59:59Z").value(), 253402300799);
341
342 // Accept edge-cases, where the time overflows. They are not produced by
343 // FormatISO8601DateTime, so this can be changed in the future, if needed.
344 // For now, keep compatibility with the previous implementation.
345 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:00:00Z").value(), 947041200);
346 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:99:00Z").value(), 946690740);
347 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:99Z").value(), 946684899);
348 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:99:99Z").value(), 947047239);
349
350 // Reject date overflows.
351 BOOST_CHECK(!ParseISO8601DateTime("2000-99-01T00:00:00Z"));
352 BOOST_CHECK(!ParseISO8601DateTime("2000-01-99T00:00:00Z"));
353
354 // Reject out-of-range years
355 BOOST_CHECK(!ParseISO8601DateTime("32768-12-31T23:59:59Z"));
356 BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T23:59:59Z"));
357 BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T00:00:00Z"));
358 BOOST_CHECK(!ParseISO8601DateTime("999-12-31T00:00:00Z"));
359
360 // Reject invalid format
361 const std::string valid{"2000-01-01T00:00:01Z"};
362 BOOST_CHECK(ParseISO8601DateTime(valid).has_value());
363 for (auto mut{0U}; mut < valid.size(); ++mut) {
364 std::string invalid{valid};
365 invalid[mut] = 'a';
367 }
368}
369
370BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime)
371{
372 BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z");
373 BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z");
374
375 BOOST_CHECK_EQUAL(FormatISO8601DateTime(-1), "1969-12-31T23:59:59Z");
376 BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z");
377 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1), "1970-01-01T00:00:01Z");
378 BOOST_CHECK_EQUAL(FormatISO8601DateTime(946684801), "2000-01-01T00:00:01Z");
379 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
380 BOOST_CHECK_EQUAL(FormatISO8601DateTime(4133980799), "2100-12-31T23:59:59Z");
381 BOOST_CHECK_EQUAL(FormatISO8601DateTime(253402300799), "9999-12-31T23:59:59Z");
382}
383
384BOOST_AUTO_TEST_CASE(util_FormatISO8601Date)
385{
386 BOOST_CHECK_EQUAL(FormatISO8601Date(971890963199), "32767-12-31");
387 BOOST_CHECK_EQUAL(FormatISO8601Date(971890876800), "32767-12-31");
388
389 BOOST_CHECK_EQUAL(FormatISO8601Date(0), "1970-01-01");
390 BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30");
391}
392
393
394BOOST_AUTO_TEST_CASE(util_FormatRFC1123DateTime)
395{
396 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(std::numeric_limits<int64_t>::max()), "");
397 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(253402300800), "");
398 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(253402300799), "Fri, 31 Dec 9999 23:59:59 GMT");
399 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(253402214400), "Fri, 31 Dec 9999 00:00:00 GMT");
400 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(1717429609), "Mon, 03 Jun 2024 15:46:49 GMT");
401 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(0), "Thu, 01 Jan 1970 00:00:00 GMT");
402 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-1), "Wed, 31 Dec 1969 23:59:59 GMT");
403 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-1717429609), "Sat, 31 Jul 1915 08:13:11 GMT");
404 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-62167219200), "Sat, 01 Jan 0000 00:00:00 GMT");
405 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-62167219201), "");
406}
407
408BOOST_AUTO_TEST_CASE(util_FormatMoney)
409{
410 BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
411 BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
413
414 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
415 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
416 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
417 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
418 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
419 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
420 BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
421 BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
424 BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
425 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
426 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
427 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
428 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
429 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
430 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
431
432 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807");
433 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806");
434 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805");
435 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804");
436 // ...
437 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805");
438 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806");
439 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807");
440 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808");
441}
442
443BOOST_AUTO_TEST_CASE(util_ParseMoney)
444{
445 BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
446 BOOST_CHECK_EQUAL(ParseMoney(".").value(), 0);
447 BOOST_CHECK_EQUAL(ParseMoney("0.").value(), 0);
448 BOOST_CHECK_EQUAL(ParseMoney(".0").value(), 0);
449 BOOST_CHECK_EQUAL(ParseMoney(".6789").value(), 6789'0000);
450 BOOST_CHECK_EQUAL(ParseMoney("12345.").value(), COIN * 12345);
451
452 BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
453
454 BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
455 BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
456 BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
457 BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
458 BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
459 BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
460 BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
461 BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN);
462 BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN);
463 BOOST_CHECK_EQUAL(ParseMoney(" 1").value(), COIN);
464 BOOST_CHECK_EQUAL(ParseMoney("1 ").value(), COIN);
465 BOOST_CHECK_EQUAL(ParseMoney(" 1 ").value(), COIN);
466 BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
467 BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
468 BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
469 BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
470 BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
471 BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
472 BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
473 BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000);
474 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000);
475 BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000);
476 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
477
478 // Parsing amount that cannot be represented should fail
479 BOOST_CHECK(!ParseMoney("100000000.00"));
480 BOOST_CHECK(!ParseMoney("0.000000001"));
481
482 // Parsing empty string should fail
484 BOOST_CHECK(!ParseMoney(" "));
485 BOOST_CHECK(!ParseMoney(" "));
486
487 // Parsing two numbers should fail
488 BOOST_CHECK(!ParseMoney(".."));
489 BOOST_CHECK(!ParseMoney("0..0"));
490 BOOST_CHECK(!ParseMoney("1 2"));
491 BOOST_CHECK(!ParseMoney(" 1 2 "));
492 BOOST_CHECK(!ParseMoney(" 1.2 3 "));
493 BOOST_CHECK(!ParseMoney(" 1 2.3 "));
494
495 // Embedded whitespace should fail
496 BOOST_CHECK(!ParseMoney(" -1 .2 "));
497 BOOST_CHECK(!ParseMoney(" 1 .2 "));
498 BOOST_CHECK(!ParseMoney(" +1 .2 "));
499
500 // Attempted 63 bit overflow should fail
501 BOOST_CHECK(!ParseMoney("92233720368.54775808"));
502
503 // Parsing negative amounts must fail
504 BOOST_CHECK(!ParseMoney("-1"));
505
506 // Parsing strings with embedded NUL characters should fail
507 BOOST_CHECK(!ParseMoney("\0-1"s));
509 BOOST_CHECK(!ParseMoney("1\0"s));
510}
511
513{
514 BOOST_CHECK(IsHex("00"));
515 BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
516 BOOST_CHECK(IsHex("ff"));
517 BOOST_CHECK(IsHex("FF"));
518
519 BOOST_CHECK(!IsHex(""));
520 BOOST_CHECK(!IsHex("0"));
521 BOOST_CHECK(!IsHex("a"));
522 BOOST_CHECK(!IsHex("eleven"));
523 BOOST_CHECK(!IsHex("00xx00"));
524 BOOST_CHECK(!IsHex("0x0000"));
525}
526
527BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
528{
529 SeedRandomForTest(SeedRand::ZEROS);
530 for (int mod=2;mod<11;mod++)
531 {
532 int mask = 1;
533 // Really rough binomial confidence approximation.
534 int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
535 //mask is 2^ceil(log2(mod))-1
536 while(mask<mod-1)mask=(mask<<1)+1;
537
538 int count = 0;
539 //How often does it get a zero from the uniform range [0,mod)?
540 for (int i = 0; i < 10000; i++) {
541 uint32_t rval;
542 do{
543 rval=m_rng.rand32()&mask;
544 }while(rval>=(uint32_t)mod);
545 count += rval==0;
546 }
547 BOOST_CHECK(count<=10000/mod+err);
548 BOOST_CHECK(count>=10000/mod-err);
549 }
550}
551
552BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
553{
554 BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
555 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
556 BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
557 BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
558 BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
559 BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
560 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
561}
562
563/* Test strprintf formatting directives.
564 * Put a string before and after to ensure sanity of element sizes on stack. */
565#define B "check_prefix"
566#define E "check_postfix"
567BOOST_AUTO_TEST_CASE(strprintf_numbers)
568{
569 int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
570 uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
571 BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
572 BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
573 BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
574
575 size_t st = 12345678; /* unsigned size_t test value */
576 ssize_t sst = -12345678; /* signed size_t test value */
577 BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
578 BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
579 BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
580
581 ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
582 ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
583 BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
584 BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
585 BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
586}
587#undef B
588#undef E
589
591{
592 FakeNodeClock clock{111s};
593 // Check that mock time does not change after a sleep
594 for (const auto& num_sleep : {0ms, 1ms}) {
595 UninterruptibleSleep(num_sleep);
596 BOOST_CHECK_EQUAL(111, GetTime()); // Deprecated time getter
597 BOOST_CHECK_EQUAL(111, Now<NodeSeconds>().time_since_epoch().count());
598 BOOST_CHECK_EQUAL(111, TicksSinceEpoch<std::chrono::seconds>(NodeClock::now()));
599 BOOST_CHECK_EQUAL(111, TicksSinceEpoch<SecondsDouble>(Now<NodeSeconds>()));
600 BOOST_CHECK_EQUAL(111, GetTime<std::chrono::seconds>().count());
601 BOOST_CHECK_EQUAL(111000, GetTime<std::chrono::milliseconds>().count());
602 BOOST_CHECK_EQUAL(111000, TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()));
603 BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count());
604 }
605}
606
607BOOST_AUTO_TEST_CASE(util_ticksseconds)
608{
614}
615
617{
618 BOOST_CHECK_EQUAL(IsDigit('0'), true);
619 BOOST_CHECK_EQUAL(IsDigit('1'), true);
620 BOOST_CHECK_EQUAL(IsDigit('8'), true);
621 BOOST_CHECK_EQUAL(IsDigit('9'), true);
622
623 BOOST_CHECK_EQUAL(IsDigit('0' - 1), false);
624 BOOST_CHECK_EQUAL(IsDigit('9' + 1), false);
625 BOOST_CHECK_EQUAL(IsDigit(0), false);
626 BOOST_CHECK_EQUAL(IsDigit(1), false);
627 BOOST_CHECK_EQUAL(IsDigit(8), false);
628 BOOST_CHECK_EQUAL(IsDigit(9), false);
629}
630
631/* Check for overflow */
632template <typename T>
634{
635 constexpr T MAXI{std::numeric_limits<T>::max()};
636 BOOST_CHECK(!CheckedAdd(T{1}, MAXI));
637 BOOST_CHECK(!CheckedAdd(MAXI, MAXI));
638 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI));
639 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(MAXI, MAXI));
640
641 BOOST_CHECK_EQUAL(0, CheckedAdd(T{0}, T{0}).value());
642 BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{0}, MAXI).value());
643 BOOST_CHECK_EQUAL(MAXI, CheckedAdd(T{1}, MAXI - 1).value());
644 BOOST_CHECK_EQUAL(MAXI - 1, CheckedAdd(T{1}, MAXI - 2).value());
646 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{0}, MAXI));
647 BOOST_CHECK_EQUAL(MAXI, SaturatingAdd(T{1}, MAXI - 1));
648 BOOST_CHECK_EQUAL(MAXI - 1, SaturatingAdd(T{1}, MAXI - 2));
649}
650
651/* Check for overflow or underflow */
652template <typename T>
653static void TestAddMatrix()
654{
655 TestAddMatrixOverflow<T>();
656 constexpr T MINI{std::numeric_limits<T>::min()};
657 constexpr T MAXI{std::numeric_limits<T>::max()};
658 BOOST_CHECK(!CheckedAdd(T{-1}, MINI));
659 BOOST_CHECK(!CheckedAdd(MINI, MINI));
660 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI));
661 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(MINI, MINI));
662
663 BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{0}, MINI).value());
664 BOOST_CHECK_EQUAL(MINI, CheckedAdd(T{-1}, MINI + 1).value());
665 BOOST_CHECK_EQUAL(-1, CheckedAdd(MINI, MAXI).value());
666 BOOST_CHECK_EQUAL(MINI + 1, CheckedAdd(T{-1}, MINI + 2).value());
667 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{0}, MINI));
668 BOOST_CHECK_EQUAL(MINI, SaturatingAdd(T{-1}, MINI + 1));
669 BOOST_CHECK_EQUAL(MINI + 1, SaturatingAdd(T{-1}, MINI + 2));
670 BOOST_CHECK_EQUAL(-1, SaturatingAdd(MINI, MAXI));
671}
672
674{
675 TestAddMatrixOverflow<unsigned>();
676 TestAddMatrix<signed>();
677}
678
679template <typename T>
681{
683 BOOST_CHECK(!ToIntegral<T>(" 1"));
684 BOOST_CHECK(!ToIntegral<T>("1 "));
685 BOOST_CHECK(!ToIntegral<T>("1a"));
686 BOOST_CHECK(!ToIntegral<T>("1.1"));
687 BOOST_CHECK(!ToIntegral<T>("1.9"));
688 BOOST_CHECK(!ToIntegral<T>("+01.9"));
689 BOOST_CHECK(!ToIntegral<T>("-"));
690 BOOST_CHECK(!ToIntegral<T>("+"));
691 BOOST_CHECK(!ToIntegral<T>(" -1"));
692 BOOST_CHECK(!ToIntegral<T>("-1 "));
693 BOOST_CHECK(!ToIntegral<T>(" -1 "));
694 BOOST_CHECK(!ToIntegral<T>("+1"));
695 BOOST_CHECK(!ToIntegral<T>(" +1"));
696 BOOST_CHECK(!ToIntegral<T>(" +1 "));
697 BOOST_CHECK(!ToIntegral<T>("+-1"));
698 BOOST_CHECK(!ToIntegral<T>("-+1"));
699 BOOST_CHECK(!ToIntegral<T>("++1"));
700 BOOST_CHECK(!ToIntegral<T>("--1"));
701 BOOST_CHECK(!ToIntegral<T>(""));
702 BOOST_CHECK(!ToIntegral<T>("aap"));
703 BOOST_CHECK(!ToIntegral<T>("0x1"));
704 BOOST_CHECK(!ToIntegral<T>("-32482348723847471234"));
705 BOOST_CHECK(!ToIntegral<T>("32482348723847471234"));
706}
707
708BOOST_AUTO_TEST_CASE(test_ToIntegral)
709{
710 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("1234").value(), 1'234);
711 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("0").value(), 0);
712 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("01234").value(), 1'234);
713 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000001234").value(), 1'234);
714 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000001234").value(), -1'234);
715 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000000000").value(), 0);
716 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000000000").value(), 0);
717 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1234").value(), -1'234);
718 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1").value(), -1);
719
720 RunToIntegralTests<uint64_t>();
721 RunToIntegralTests<int64_t>();
722 RunToIntegralTests<uint32_t>();
723 RunToIntegralTests<int32_t>();
724 RunToIntegralTests<uint16_t>();
725 RunToIntegralTests<int16_t>();
726 RunToIntegralTests<uint8_t>();
727 RunToIntegralTests<int8_t>();
728
729 BOOST_CHECK(!ToIntegral<int64_t>("-9223372036854775809"));
730 BOOST_CHECK_EQUAL(ToIntegral<int64_t>("-9223372036854775808").value(), -9'223'372'036'854'775'807LL - 1LL);
731 BOOST_CHECK_EQUAL(ToIntegral<int64_t>("9223372036854775807").value(), 9'223'372'036'854'775'807);
732 BOOST_CHECK(!ToIntegral<int64_t>("9223372036854775808"));
733
734 BOOST_CHECK(!ToIntegral<uint64_t>("-1"));
735 BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("0").value(), 0U);
736 BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("18446744073709551615").value(), 18'446'744'073'709'551'615ULL);
737 BOOST_CHECK(!ToIntegral<uint64_t>("18446744073709551616"));
738
739 BOOST_CHECK(!ToIntegral<int32_t>("-2147483649"));
740 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-2147483648").value(), -2'147'483'648LL);
741 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("2147483647").value(), 2'147'483'647);
742 BOOST_CHECK(!ToIntegral<int32_t>("2147483648"));
743
744 BOOST_CHECK(!ToIntegral<uint32_t>("-1"));
745 BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("0").value(), 0U);
746 BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("4294967295").value(), 4'294'967'295U);
747 BOOST_CHECK(!ToIntegral<uint32_t>("4294967296"));
748
749 BOOST_CHECK(!ToIntegral<int16_t>("-32769"));
750 BOOST_CHECK_EQUAL(ToIntegral<int16_t>("-32768").value(), -32'768);
751 BOOST_CHECK_EQUAL(ToIntegral<int16_t>("32767").value(), 32'767);
752 BOOST_CHECK(!ToIntegral<int16_t>("32768"));
753
754 BOOST_CHECK(!ToIntegral<uint16_t>("-1"));
755 BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("0").value(), 0U);
756 BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("65535").value(), 65'535U);
757 BOOST_CHECK(!ToIntegral<uint16_t>("65536"));
758
759 BOOST_CHECK(!ToIntegral<int8_t>("-129"));
760 BOOST_CHECK_EQUAL(ToIntegral<int8_t>("-128").value(), -128);
761 BOOST_CHECK_EQUAL(ToIntegral<int8_t>("127").value(), 127);
762 BOOST_CHECK(!ToIntegral<int8_t>("128"));
763
764 BOOST_CHECK(!ToIntegral<uint8_t>("-1"));
765 BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("0").value(), 0U);
766 BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("255").value(), 255U);
767 BOOST_CHECK(!ToIntegral<uint8_t>("256"));
768}
769
770int64_t atoi64_legacy(const std::string& str)
771{
772 return strtoll(str.c_str(), nullptr, 10);
773}
774
775BOOST_AUTO_TEST_CASE(test_LocaleIndependentAtoi)
776{
777 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1234"), 1'234);
778 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0"), 0);
779 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("01234"), 1'234);
780 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1234"), -1'234);
781 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" 1"), 1);
782 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1 "), 1);
783 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1a"), 1);
784 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.1"), 1);
785 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.9"), 1);
786 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+01.9"), 1);
787 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1"), -1);
788 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1"), -1);
789 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1 "), -1);
790 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1 "), -1);
791 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+1"), 1);
792 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1"), 1);
793 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1 "), 1);
794
795 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+-1"), 0);
796 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-+1"), 0);
797 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("++1"), 0);
798 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("--1"), 0);
799 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(""), 0);
800 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("aap"), 0);
801 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0x1"), 0);
802 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-32482348723847471234"), -2'147'483'647 - 1);
803 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("32482348723847471234"), 2'147'483'647);
804
805 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775809"), -9'223'372'036'854'775'807LL - 1LL);
806 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775808"), -9'223'372'036'854'775'807LL - 1LL);
807 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775807"), 9'223'372'036'854'775'807);
808 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775808"), 9'223'372'036'854'775'807);
809
810 std::map<std::string, int64_t> atoi64_test_pairs = {
811 {"-9223372036854775809", std::numeric_limits<int64_t>::min()},
812 {"-9223372036854775808", -9'223'372'036'854'775'807LL - 1LL},
813 {"9223372036854775807", 9'223'372'036'854'775'807},
814 {"9223372036854775808", std::numeric_limits<int64_t>::max()},
815 {"+-", 0},
816 {"0x1", 0},
817 {"ox1", 0},
818 {"", 0},
819 };
820
821 for (const auto& pair : atoi64_test_pairs) {
822 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), pair.second);
823 }
824
825 // Ensure legacy compatibility with previous versions of Bitcoin Core's atoi64
826 for (const auto& pair : atoi64_test_pairs) {
827 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>(pair.first), atoi64_legacy(pair.first));
828 }
829
830 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("-1"), 0U);
831 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("0"), 0U);
832 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551615"), 18'446'744'073'709'551'615ULL);
833 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551616"), 18'446'744'073'709'551'615ULL);
834
835 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483649"), -2'147'483'648LL);
836 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483648"), -2'147'483'648LL);
837 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483647"), 2'147'483'647);
838 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483648"), 2'147'483'647);
839
840 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("-1"), 0U);
841 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("0"), 0U);
842 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967295"), 4'294'967'295U);
843 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967296"), 4'294'967'295U);
844
845 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32769"), -32'768);
846 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32768"), -32'768);
847 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32767"), 32'767);
848 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32768"), 32'767);
849
850 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("-1"), 0U);
851 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("0"), 0U);
852 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65535"), 65'535U);
853 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65536"), 65'535U);
854
855 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-129"), -128);
856 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-128"), -128);
857 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("127"), 127);
858 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("128"), 127);
859
860 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("-1"), 0U);
861 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("0"), 0U);
862 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("255"), 255U);
863 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("256"), 255U);
864}
865
866BOOST_AUTO_TEST_CASE(test_ToIntegralHex)
867{
868 std::optional<uint64_t> n;
869 // Valid values
870 n = ToIntegral<uint64_t>("1234", 16);
871 BOOST_CHECK_EQUAL(*n, 0x1234);
872 n = ToIntegral<uint64_t>("a", 16);
873 BOOST_CHECK_EQUAL(*n, 0xA);
874 n = ToIntegral<uint64_t>("0000000a", 16);
875 BOOST_CHECK_EQUAL(*n, 0xA);
876 n = ToIntegral<uint64_t>("100", 16);
877 BOOST_CHECK_EQUAL(*n, 0x100);
878 n = ToIntegral<uint64_t>("DEADbeef", 16);
879 BOOST_CHECK_EQUAL(*n, 0xDEADbeef);
880 n = ToIntegral<uint64_t>("FfFfFfFf", 16);
881 BOOST_CHECK_EQUAL(*n, 0xFfFfFfFf);
882 n = ToIntegral<uint64_t>("123456789", 16);
883 BOOST_CHECK_EQUAL(*n, 0x123456789ULL);
884 n = ToIntegral<uint64_t>("0", 16);
885 BOOST_CHECK_EQUAL(*n, 0);
886 n = ToIntegral<uint64_t>("FfFfFfFfFfFfFfFf", 16);
887 BOOST_CHECK_EQUAL(*n, 0xFfFfFfFfFfFfFfFfULL);
888 BOOST_CHECK_EQUAL(*ToIntegral<int64_t>("-1", 16), -1);
889 // Invalid values
890 BOOST_CHECK(!ToIntegral<uint64_t>("", 16));
891 BOOST_CHECK(!ToIntegral<uint64_t>("-1", 16));
892 BOOST_CHECK(!ToIntegral<uint64_t>("10 00", 16));
893 BOOST_CHECK(!ToIntegral<uint64_t>("1 ", 16));
894 BOOST_CHECK(!ToIntegral<uint64_t>("0xAB", 16));
895 BOOST_CHECK(!ToIntegral<uint64_t>("FfFfFfFfFfFfFfFf0", 16));
896}
897
898BOOST_AUTO_TEST_CASE(test_FormatParagraph)
899{
900 BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
901 BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
902 BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test");
903 BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
904 BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
905 BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest");
906 BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
907
908 // Make sure we don't indent a fully-new line following a too-long line ending
909 BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n test\nabc");
910
911 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");
912
913 // Test wrap length is exact
914 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");
915 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");
916 // Indent should be included in length of lines
917 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");
918
919 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.");
920 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.");
921 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.");
922 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.");
923}
924
925BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
926{
927 std::vector<std::string> comments;
928 comments.emplace_back("comment1");
929 std::vector<std::string> comments2;
930 comments2.emplace_back("comment1");
931 comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
932 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:9.99.0/"));
933 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:9.99.0(comment1)/"));
934 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:9.99.0(comment1; Comment2; .,_?@-; )/"));
935}
936
937BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
938{
939 int64_t amount = 0;
940 BOOST_CHECK(ParseFixedPoint("0", 8, &amount));
941 BOOST_CHECK_EQUAL(amount, 0LL);
942 BOOST_CHECK(ParseFixedPoint("1", 8, &amount));
943 BOOST_CHECK_EQUAL(amount, 100000000LL);
944 BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount));
945 BOOST_CHECK_EQUAL(amount, 0LL);
946 BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount));
947 BOOST_CHECK_EQUAL(amount, -10000000LL);
948 BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount));
949 BOOST_CHECK_EQUAL(amount, 110000000LL);
950 BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount));
951 BOOST_CHECK_EQUAL(amount, 110000000LL);
952 BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount));
953 BOOST_CHECK_EQUAL(amount, 1100000000LL);
954 BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount));
955 BOOST_CHECK_EQUAL(amount, 11000000LL);
956 BOOST_CHECK(ParseFixedPoint("1000", 8, &amount));
957 BOOST_CHECK_EQUAL(amount, 100000000000LL);
958 BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount));
959 BOOST_CHECK_EQUAL(amount, -100000000000LL);
960 BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount));
961 BOOST_CHECK_EQUAL(amount, 1LL);
962 BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount));
963 BOOST_CHECK_EQUAL(amount, 1LL);
964 BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount));
965 BOOST_CHECK_EQUAL(amount, -1LL);
966 BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount));
967 BOOST_CHECK_EQUAL(amount, 100000000000000001LL);
968 BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount));
969 BOOST_CHECK_EQUAL(amount, 999999999999999999LL);
970 BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount));
971 BOOST_CHECK_EQUAL(amount, -999999999999999999LL);
972
973 BOOST_CHECK(!ParseFixedPoint("", 8, &amount));
974 BOOST_CHECK(!ParseFixedPoint("-", 8, &amount));
975 BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount));
976 BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount));
977 BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount));
978 BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount));
979 BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount));
980 BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount));
981 BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount));
982 BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount));
983 BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount));
984 BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount));
985 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount));
986 BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount));
987 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount));
988 BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount));
989 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount));
990 BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount));
991 BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount));
992 BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount));
993 BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount));
994 BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount));
995 BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount));
996 BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount));
997 BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
998 BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
999 BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));
1000
1001 // Test with 3 decimal places for fee rates in sat/vB.
1002 BOOST_CHECK(ParseFixedPoint("0.001", 3, &amount));
1003 BOOST_CHECK_EQUAL(amount, CAmount{1});
1004 BOOST_CHECK(!ParseFixedPoint("0.0009", 3, &amount));
1005 BOOST_CHECK(!ParseFixedPoint("31.00100001", 3, &amount));
1006 BOOST_CHECK(!ParseFixedPoint("31.0011", 3, &amount));
1007 BOOST_CHECK(!ParseFixedPoint("31.99999999", 3, &amount));
1008 BOOST_CHECK(!ParseFixedPoint("31.999999999999999999999", 3, &amount));
1009}
1010
1011#ifndef WIN32 // Cannot do this test on WIN32 due to lack of fork()
1012static constexpr char LockCommand = 'L';
1013static constexpr char UnlockCommand = 'U';
1014static constexpr char ExitCommand = 'X';
1015enum : char {
1016 ResSuccess = 2, // Start with 2 to avoid accidental collision with common values 0 and 1
1020};
1021
1022[[noreturn]] static void TestOtherProcess(fs::path dirname, fs::path lockname, int fd)
1023{
1024 char ch;
1025 while (true) {
1026 int rv = read(fd, &ch, 1); // Wait for command
1027 assert(rv == 1);
1028 switch (ch) {
1029 case LockCommand:
1030 ch = [&] {
1031 switch (util::LockDirectory(dirname, lockname)) {
1035 } // no default case, so the compiler can warn about missing cases
1036 assert(false);
1037 }();
1038 rv = write(fd, &ch, 1);
1039 assert(rv == 1);
1040 break;
1041 case UnlockCommand:
1043 ch = ResUnlockSuccess; // Always succeeds
1044 rv = write(fd, &ch, 1);
1045 assert(rv == 1);
1046 break;
1047 case ExitCommand:
1048 close(fd);
1049 exit(0);
1050 default:
1051 assert(0);
1052 }
1053 }
1054}
1055#endif
1056
1057BOOST_AUTO_TEST_CASE(test_LockDirectory)
1058{
1059 fs::path dirname = m_args.GetDataDirBase() / "lock_dir";
1060 const fs::path lockname = ".lock";
1061#ifndef WIN32
1062 // Fork another process for testing before creating the lock, so that we
1063 // won't fork while holding the lock (which might be undefined, and is not
1064 // relevant as test case as that is avoided with -daemonize).
1065 int fd[2];
1066 BOOST_CHECK_EQUAL(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0);
1067 pid_t pid = fork();
1068 if (!pid) {
1069 BOOST_CHECK_EQUAL(close(fd[1]), 0); // Child: close parent end
1070 TestOtherProcess(dirname, lockname, fd[0]);
1071 }
1072 BOOST_CHECK_EQUAL(close(fd[0]), 0); // Parent: close child end
1073
1074 char ch;
1075 // Lock on non-existent directory should fail
1076 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
1077 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
1079#endif
1080 // Lock on non-existent directory should fail
1082
1083 fs::create_directories(dirname);
1084
1085 // Probing lock on new directory should succeed
1087
1088 // Persistent lock on new directory should succeed
1090
1091 // Another lock on the directory from the same thread should succeed
1093
1094 // Another lock on the directory from a different thread within the same process should succeed
1095 util::LockResult threadresult;
1096 std::thread thr([&] { threadresult = util::LockDirectory(dirname, lockname); });
1097 thr.join();
1099#ifndef WIN32
1100 // Try to acquire lock in child process while we're holding it, this should fail.
1101 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
1102 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
1104
1105 // Give up our lock
1107 // Probing lock from our side now should succeed, but not hold on to the lock.
1109
1110 // Try to acquire the lock in the child process, this should be successful.
1111 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
1112 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
1114
1115 // When we try to probe the lock now, it should fail.
1117
1118 // Unlock the lock in the child process
1119 BOOST_CHECK_EQUAL(write(fd[1], &UnlockCommand, 1), 1);
1120 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
1122
1123 // When we try to probe the lock now, it should succeed.
1125
1126 // Re-lock the lock in the child process, then wait for it to exit, check
1127 // successful return. After that, we check that exiting the process
1128 // has released the lock as we would expect by probing it.
1129 int processstatus;
1130 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
1131 // The following line invokes the ~CNetCleanup dtor without
1132 // a paired SetupNetworking call. This is acceptable as long as
1133 // ~CNetCleanup is a no-op for non-Windows platforms.
1134 BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1);
1135 BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid);
1136 BOOST_CHECK_EQUAL(processstatus, 0);
1138
1139 BOOST_CHECK_EQUAL(close(fd[1]), 0); // Close our side of the socketpair
1140#endif
1141 // Clean up
1143 fs::remove(dirname / lockname);
1144 fs::remove(dirname);
1145}
1146
1148{
1149 BOOST_CHECK_EQUAL(ToLower('@'), '@');
1150 BOOST_CHECK_EQUAL(ToLower('A'), 'a');
1151 BOOST_CHECK_EQUAL(ToLower('Z'), 'z');
1152 BOOST_CHECK_EQUAL(ToLower('['), '[');
1154 BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
1155
1156 BOOST_CHECK_EQUAL(ToLower(""), "");
1157 BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl");
1158 BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff");
1159}
1160
1162{
1163 BOOST_CHECK_EQUAL(ToUpper('`'), '`');
1164 BOOST_CHECK_EQUAL(ToUpper('a'), 'A');
1165 BOOST_CHECK_EQUAL(ToUpper('z'), 'Z');
1166 BOOST_CHECK_EQUAL(ToUpper('{'), '{');
1168 BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
1169
1170 BOOST_CHECK_EQUAL(ToUpper(""), "");
1171 BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL");
1172 BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff");
1173}
1174
1175BOOST_AUTO_TEST_CASE(test_Capitalize)
1176{
1178 BOOST_CHECK_EQUAL(Capitalize("bitcoin"), "Bitcoin");
1179 BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff");
1180}
1181
1182static std::string SpanToStr(const std::span<const char>& span)
1183{
1184 return std::string(span.begin(), span.end());
1185}
1186
1187BOOST_AUTO_TEST_CASE(test_script_parsing)
1188{
1189 using namespace script;
1190 std::string input;
1191 std::span<const char> sp;
1192 bool success;
1193
1194 // Const(...): parse a constant, update span to skip it if successful
1195 input = "MilkToastHoney";
1196 sp = input;
1197 success = Const("", sp); // empty
1198 BOOST_CHECK(success);
1199 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
1200
1201 success = Const("Milk", sp, /*skip=*/false);
1202 BOOST_CHECK(success);
1203 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
1204
1205 success = Const("Milk", sp);
1206 BOOST_CHECK(success);
1207 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
1208
1209 success = Const("Bread", sp, /*skip=*/false);
1210 BOOST_CHECK(!success);
1211
1212 success = Const("Bread", sp);
1213 BOOST_CHECK(!success);
1214
1215 success = Const("Toast", sp, /*skip=*/false);
1216 BOOST_CHECK(success);
1217 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
1218
1219 success = Const("Toast", sp);
1220 BOOST_CHECK(success);
1221 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
1222
1223 success = Const("Honeybadger", sp);
1224 BOOST_CHECK(!success);
1225
1226 success = Const("Honey", sp, /*skip=*/false);
1227 BOOST_CHECK(success);
1228 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
1229
1230 success = Const("Honey", sp);
1231 BOOST_CHECK(success);
1233 // Func(...): parse a function call, update span to argument if successful
1234 input = "Foo(Bar(xy,z()))";
1235 sp = input;
1236
1237 success = Func("FooBar", sp);
1238 BOOST_CHECK(!success);
1239
1240 success = Func("Foo(", sp);
1241 BOOST_CHECK(!success);
1242
1243 success = Func("Foo", sp);
1244 BOOST_CHECK(success);
1245 BOOST_CHECK_EQUAL(SpanToStr(sp), "Bar(xy,z())");
1246
1247 success = Func("Bar", sp);
1248 BOOST_CHECK(success);
1249 BOOST_CHECK_EQUAL(SpanToStr(sp), "xy,z()");
1250
1251 success = Func("xy", sp);
1252 BOOST_CHECK(!success);
1253
1254 // Expr(...): return expression that span begins with, update span to skip it
1255 std::span<const char> result;
1256
1257 input = "(n*(n-1))/2";
1258 sp = input;
1259 result = Expr(sp);
1260 BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2");
1262
1263 input = "foo,bar";
1264 sp = input;
1265 result = Expr(sp);
1266 BOOST_CHECK_EQUAL(SpanToStr(result), "foo");
1267 BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar");
1268
1269 input = "(aaaaa,bbbbb()),c";
1270 sp = input;
1271 result = Expr(sp);
1272 BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())");
1273 BOOST_CHECK_EQUAL(SpanToStr(sp), ",c");
1274
1275 input = "xyz)foo";
1276 sp = input;
1277 result = Expr(sp);
1278 BOOST_CHECK_EQUAL(SpanToStr(result), "xyz");
1279 BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo");
1280
1281 input = "((a),(b),(c)),xxx";
1282 sp = input;
1283 result = Expr(sp);
1284 BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))");
1285 BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
1286
1287 // Split(...): split a string on every instance of sep, return vector
1288 std::vector<std::span<const char>> results;
1289
1290 input = "xxx";
1291 results = Split(input, 'x');
1292 BOOST_CHECK_EQUAL(results.size(), 4U);
1293 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
1294 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "");
1295 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "");
1296 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
1297
1298 input = "one#two#three";
1299 results = Split(input, '-');
1300 BOOST_CHECK_EQUAL(results.size(), 1U);
1301 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three");
1302
1303 input = "one#two#three";
1304 results = Split(input, '#');
1305 BOOST_CHECK_EQUAL(results.size(), 3U);
1306 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one");
1307 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two");
1308 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
1309
1310 results = Split(input, '#', /*include_sep=*/true);
1311 BOOST_CHECK_EQUAL(results.size(), 3U);
1312 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#");
1313 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two#");
1314 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
1315
1316 input = "*foo*bar*";
1317 results = Split(input, '*');
1318 BOOST_CHECK_EQUAL(results.size(), 4U);
1319 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
1320 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo");
1321 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar");
1322 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
1323
1324 results = Split(input, '*', /*include_sep=*/true);
1325 BOOST_CHECK_EQUAL(results.size(), 4U);
1326 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "*");
1327 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo*");
1328 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar*");
1329 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
1330}
1331
1332BOOST_AUTO_TEST_CASE(test_SplitString)
1333{
1334 // Empty string.
1335 {
1336 std::vector<std::string> result = SplitString("", '-');
1337 BOOST_CHECK_EQUAL(result.size(), 1);
1338 BOOST_CHECK_EQUAL(result[0], "");
1339 }
1340
1341 // Empty items.
1342 {
1343 std::vector<std::string> result = SplitString("-", '-');
1344 BOOST_CHECK_EQUAL(result.size(), 2);
1345 BOOST_CHECK_EQUAL(result[0], "");
1346 BOOST_CHECK_EQUAL(result[1], "");
1347 }
1348
1349 // More empty items.
1350 {
1351 std::vector<std::string> result = SplitString("--", '-');
1352 BOOST_CHECK_EQUAL(result.size(), 3);
1353 BOOST_CHECK_EQUAL(result[0], "");
1354 BOOST_CHECK_EQUAL(result[1], "");
1355 BOOST_CHECK_EQUAL(result[2], "");
1356 }
1357
1358 // Separator is not present.
1359 {
1360 std::vector<std::string> result = SplitString("abc", '-');
1361 BOOST_CHECK_EQUAL(result.size(), 1);
1362 BOOST_CHECK_EQUAL(result[0], "abc");
1363 }
1364
1365 // Basic behavior.
1366 {
1367 std::vector<std::string> result = SplitString("a-b", '-');
1368 BOOST_CHECK_EQUAL(result.size(), 2);
1369 BOOST_CHECK_EQUAL(result[0], "a");
1370 BOOST_CHECK_EQUAL(result[1], "b");
1371 }
1372
1373 // Case-sensitivity of the separator.
1374 {
1375 std::vector<std::string> result = SplitString("AAA", 'a');
1376 BOOST_CHECK_EQUAL(result.size(), 1);
1377 BOOST_CHECK_EQUAL(result[0], "AAA");
1378 }
1379
1380 // multiple split characters
1381 {
1382 using V = std::vector<std::string>;
1383 BOOST_TEST(SplitString("a,b.c:d;e", ",;") == V({"a", "b.c:d", "e"}));
1384 BOOST_TEST(SplitString("a,b.c:d;e", ",;:.") == V({"a", "b", "c", "d", "e"}));
1385 BOOST_TEST(SplitString("a,b.c:d;e", "") == V({"a,b.c:d;e"}));
1386 BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"}));
1387 BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"}));
1388 BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"}));
1389 BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"}));
1390 BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"}));
1391 }
1392}
1393
1394BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
1395{
1396 // ASCII and UTF-8 must pass through unaltered.
1397 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
1398 // Newlines must pass through unaltered.
1399 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
1400 // Other control characters are escaped in C syntax.
1401 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
1402 // Embedded NULL characters are escaped too.
1403 const std::string NUL("O\x00O", 3);
1404 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
1405}
1406
1407namespace {
1408
1409struct Tracker
1410{
1412 const Tracker* origin;
1414 int copies{0};
1415
1416 Tracker() noexcept : origin(this) {}
1417 Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
1418 Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
1419 Tracker& operator=(const Tracker& t) noexcept
1420 {
1421 if (this != &t) {
1422 origin = t.origin;
1423 copies = t.copies + 1;
1424 }
1425 return *this;
1426 }
1427};
1428
1429}
1430
1431BOOST_AUTO_TEST_CASE(test_tracked_vector)
1432{
1433 Tracker t1;
1434 Tracker t2;
1435 Tracker t3;
1436
1437 BOOST_CHECK(t1.origin == &t1);
1438 BOOST_CHECK(t2.origin == &t2);
1439 BOOST_CHECK(t3.origin == &t3);
1440
1441 auto v1 = Vector(t1);
1442 BOOST_CHECK_EQUAL(v1.size(), 1U);
1443 BOOST_CHECK(v1[0].origin == &t1);
1444 BOOST_CHECK_EQUAL(v1[0].copies, 1);
1445
1446 auto v2 = Vector(std::move(t2));
1447 BOOST_CHECK_EQUAL(v2.size(), 1U);
1448 BOOST_CHECK(v2[0].origin == &t2); // NOLINT(*-use-after-move)
1449 BOOST_CHECK_EQUAL(v2[0].copies, 0);
1450
1451 auto v3 = Vector(t1, std::move(t2));
1452 BOOST_CHECK_EQUAL(v3.size(), 2U);
1453 BOOST_CHECK(v3[0].origin == &t1);
1454 BOOST_CHECK(v3[1].origin == &t2); // NOLINT(*-use-after-move)
1455 BOOST_CHECK_EQUAL(v3[0].copies, 1);
1456 BOOST_CHECK_EQUAL(v3[1].copies, 0);
1457
1458 auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
1459 BOOST_CHECK_EQUAL(v4.size(), 3U);
1460 BOOST_CHECK(v4[0].origin == &t1);
1461 BOOST_CHECK(v4[1].origin == &t2);
1462 BOOST_CHECK(v4[2].origin == &t3); // NOLINT(*-use-after-move)
1463 BOOST_CHECK_EQUAL(v4[0].copies, 1);
1464 BOOST_CHECK_EQUAL(v4[1].copies, 1);
1465 BOOST_CHECK_EQUAL(v4[2].copies, 0);
1466
1467 auto v5 = Cat(v1, v4);
1468 BOOST_CHECK_EQUAL(v5.size(), 4U);
1469 BOOST_CHECK(v5[0].origin == &t1);
1470 BOOST_CHECK(v5[1].origin == &t1);
1471 BOOST_CHECK(v5[2].origin == &t2);
1472 BOOST_CHECK(v5[3].origin == &t3);
1473 BOOST_CHECK_EQUAL(v5[0].copies, 2);
1474 BOOST_CHECK_EQUAL(v5[1].copies, 2);
1475 BOOST_CHECK_EQUAL(v5[2].copies, 2);
1476 BOOST_CHECK_EQUAL(v5[3].copies, 1);
1477
1478 auto v6 = Cat(std::move(v1), v3);
1479 BOOST_CHECK_EQUAL(v6.size(), 3U);
1480 BOOST_CHECK(v6[0].origin == &t1);
1481 BOOST_CHECK(v6[1].origin == &t1);
1482 BOOST_CHECK(v6[2].origin == &t2);
1483 BOOST_CHECK_EQUAL(v6[0].copies, 1);
1484 BOOST_CHECK_EQUAL(v6[1].copies, 2);
1485 BOOST_CHECK_EQUAL(v6[2].copies, 1);
1486
1487 auto v7 = Cat(v2, std::move(v4));
1488 BOOST_CHECK_EQUAL(v7.size(), 4U);
1489 BOOST_CHECK(v7[0].origin == &t2);
1490 BOOST_CHECK(v7[1].origin == &t1);
1491 BOOST_CHECK(v7[2].origin == &t2);
1492 BOOST_CHECK(v7[3].origin == &t3);
1493 BOOST_CHECK_EQUAL(v7[0].copies, 1);
1494 BOOST_CHECK_EQUAL(v7[1].copies, 1);
1495 BOOST_CHECK_EQUAL(v7[2].copies, 1);
1496 BOOST_CHECK_EQUAL(v7[3].copies, 0);
1497
1498 auto v8 = Cat(std::move(v2), std::move(v3));
1499 BOOST_CHECK_EQUAL(v8.size(), 3U);
1500 BOOST_CHECK(v8[0].origin == &t2);
1501 BOOST_CHECK(v8[1].origin == &t1);
1502 BOOST_CHECK(v8[2].origin == &t2);
1503 BOOST_CHECK_EQUAL(v8[0].copies, 0);
1504 BOOST_CHECK_EQUAL(v8[1].copies, 1);
1505 BOOST_CHECK_EQUAL(v8[2].copies, 0);
1506}
1507
1509{
1510 const std::array<unsigned char, 32> privkey_bytes = {
1511 // just some random data
1512 // derived address from this private key: 15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs
1513 0xD9, 0x7F, 0x51, 0x08, 0xF1, 0x1C, 0xDA, 0x6E,
1514 0xEE, 0xBA, 0xAA, 0x42, 0x0F, 0xEF, 0x07, 0x26,
1515 0xB1, 0xF8, 0x98, 0x06, 0x0B, 0x98, 0x48, 0x9F,
1516 0xA3, 0x09, 0x84, 0x63, 0xC0, 0x03, 0x28, 0x66
1517 };
1518
1519 const std::string message = "Trust no one";
1520
1521 const std::string expected_signature =
1522 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=";
1523
1524 CKey privkey;
1525 std::string generated_signature;
1526
1527 BOOST_REQUIRE_MESSAGE(!privkey.IsValid(),
1528 "Confirm the private key is invalid");
1529
1530 BOOST_CHECK_MESSAGE(!MessageSign(privkey, message, generated_signature),
1531 "Sign with an invalid private key");
1532
1533 privkey.Set(privkey_bytes.begin(), privkey_bytes.end(), true);
1534
1535 BOOST_REQUIRE_MESSAGE(privkey.IsValid(),
1536 "Confirm the private key is valid");
1537
1538 BOOST_CHECK_MESSAGE(MessageSign(privkey, message, generated_signature),
1539 "Sign with a valid private key");
1540
1541 BOOST_CHECK_EQUAL(expected_signature, generated_signature);
1542}
1543
1545{
1548 "invalid address",
1549 "signature should be irrelevant",
1550 "message too"),
1552
1555 "3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
1556 "signature should be irrelevant",
1557 "message too"),
1559
1562 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
1563 "invalid signature, not in base64 encoding",
1564 "message should be irrelevant"),
1566
1569 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
1570 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1571 "message should be irrelevant"),
1573
1576 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
1577 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
1578 "I never signed this"),
1580
1583 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
1584 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
1585 "Trust no one"),
1587
1590 "11canuhp9X2NocwCq7xNrQYTmUgZAnLK3",
1591 "IIcaIENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzIAaHRtbCeDZINyavx14=",
1592 "Trust me"),
1594}
1595
1597{
1598 const std::string unsigned_tx = "...";
1599 const std::string prefixed_message =
1600 std::string(1, (char)MESSAGE_MAGIC.length()) +
1602 std::string(1, (char)unsigned_tx.length()) +
1603 unsigned_tx;
1604
1605 const uint256 signature_hash = Hash(unsigned_tx);
1606 const uint256 message_hash1 = Hash(prefixed_message);
1607 const uint256 message_hash2 = MessageHash(unsigned_tx);
1608
1609 BOOST_CHECK_EQUAL(message_hash1, message_hash2);
1610 BOOST_CHECK_NE(message_hash1, signature_hash);
1611}
1612
1614{
1615 BOOST_CHECK_EQUAL(RemovePrefix("./common/system.h", "./"), "common/system.h");
1616 BOOST_CHECK_EQUAL(RemovePrefixView("foo", "foo"), "");
1617 BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o");
1618 BOOST_CHECK_EQUAL(RemovePrefixView("foo", "f"), "oo");
1619 BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo");
1620 BOOST_CHECK_EQUAL(RemovePrefixView("fo", "foo"), "fo");
1621 BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f");
1622 BOOST_CHECK_EQUAL(RemovePrefixView("", "foo"), "");
1623 BOOST_CHECK_EQUAL(RemovePrefix("", ""), "");
1624}
1625
1626BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
1627{
1628 auto noop = ByteUnit::NOOP;
1629
1630 // no multiplier
1631 BOOST_CHECK_EQUAL(ParseByteUnits("1", noop).value(), 1);
1632 BOOST_CHECK_EQUAL(ParseByteUnits("0", noop).value(), 0);
1633
1634 BOOST_CHECK_EQUAL(ParseByteUnits("1k", noop).value(), 1000ULL);
1635 BOOST_CHECK_EQUAL(ParseByteUnits("1K", noop).value(), 1ULL << 10);
1636
1637 BOOST_CHECK_EQUAL(ParseByteUnits("2m", noop).value(), 2'000'000ULL);
1638 BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2_MiB);
1639
1640 BOOST_CHECK_EQUAL(ParseByteUnits("3g", noop).value(), 3'000'000'000ULL);
1641 BOOST_CHECK_EQUAL(ParseByteUnits("3G", noop).value(), 3_GiB);
1642
1643 BOOST_CHECK_EQUAL(ParseByteUnits("4t", noop).value(), 4'000'000'000'000ULL);
1644 BOOST_CHECK_EQUAL(ParseByteUnits("4T", noop).value(), 4ULL << 40);
1645
1646 // check default multiplier
1647 BOOST_CHECK_EQUAL(ParseByteUnits("5", ByteUnit::K).value(), 5ULL << 10);
1648
1649 // NaN
1650 BOOST_CHECK(!ParseByteUnits("", noop));
1651 BOOST_CHECK(!ParseByteUnits("foo", noop));
1652
1653 // whitespace
1654 BOOST_CHECK(!ParseByteUnits("123m ", noop));
1655 BOOST_CHECK(!ParseByteUnits(" 123m", noop));
1656
1657 // no +-
1658 BOOST_CHECK(!ParseByteUnits("-123m", noop));
1659 BOOST_CHECK(!ParseByteUnits("+123m", noop));
1660
1661 // zero padding
1662 BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20_MiB);
1663
1664 // fractions not allowed
1665 BOOST_CHECK(!ParseByteUnits("0.5T", noop));
1666
1667 // overflow
1668 BOOST_CHECK(!ParseByteUnits("18446744073709551615g", noop));
1669
1670 // invalid unit
1671 BOOST_CHECK(!ParseByteUnits("1x", noop));
1672}
1673
1674BOOST_AUTO_TEST_CASE(util_ReadBinaryFile)
1675{
1676 fs::path tmpfolder = m_args.GetDataDirBase();
1677 fs::path tmpfile = tmpfolder / "read_binary.dat";
1678 std::string expected_text;
1679 for (int i = 0; i < 30; i++) {
1680 expected_text += "0123456789";
1681 }
1682 {
1683 std::ofstream file{tmpfile.std_path()};
1684 file << expected_text;
1685 }
1686 {
1687 // read all contents in file
1688 auto [valid, text] = ReadBinaryFile(tmpfile);
1689 BOOST_CHECK(valid);
1690 BOOST_CHECK_EQUAL(text, expected_text);
1691 }
1692 {
1693 // read half contents in file
1694 auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2);
1695 BOOST_CHECK(valid);
1696 BOOST_CHECK_EQUAL(text, expected_text.substr(0, expected_text.size() / 2));
1697 }
1698 {
1699 // read from non-existent file
1700 fs::path invalid_file = tmpfolder / "invalid_binary.dat";
1701 auto [valid, text] = ReadBinaryFile(invalid_file);
1702 BOOST_CHECK(!valid);
1703 BOOST_CHECK(text.empty());
1704 }
1705}
1706
1707BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
1708{
1709 fs::path tmpfolder = m_args.GetDataDirBase();
1710 fs::path tmpfile = tmpfolder / "write_binary.dat";
1711 std::string expected_text = "bitcoin";
1712 auto valid = WriteBinaryFile(tmpfile, expected_text);
1713 std::string actual_text;
1714 std::ifstream file{tmpfile.std_path()};
1715 file >> actual_text;
1716 BOOST_CHECK(valid);
1717 BOOST_CHECK_EQUAL(actual_text, expected_text);
1718}
1719
1720BOOST_AUTO_TEST_CASE(clearshrink_test)
1721{
1722 {
1723 std::vector<uint8_t> v = {1, 2, 3};
1724 ClearShrink(v);
1725 BOOST_CHECK_EQUAL(v.size(), 0);
1726 BOOST_CHECK_EQUAL(v.capacity(), 0);
1727 }
1728
1729 {
1730 std::vector<bool> v = {false, true, false, false, true, true};
1731 ClearShrink(v);
1732 BOOST_CHECK_EQUAL(v.size(), 0);
1733 BOOST_CHECK_EQUAL(v.capacity(), 0);
1734 }
1735
1736 {
1737 std::deque<int> v = {1, 3, 3, 7};
1738 ClearShrink(v);
1739 BOOST_CHECK_EQUAL(v.size(), 0);
1740 // std::deque has no capacity() we can observe.
1741 }
1742}
1743
1744template <typename T>
1746{
1747 constexpr auto MAX{std::numeric_limits<T>::max()};
1748
1749 // Basic operations
1750 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 1), 0);
1751 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 127), 0);
1752 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, 1), 2);
1753 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(2, 2), 8);
1754 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MAX >> 1, 1), MAX - 1);
1755
1756 // Max left shift
1757 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1);
1758
1759 // Overflow cases
1760 BOOST_CHECK(!CheckedLeftShift<T>((MAX >> 1) + 1, 1));
1761 BOOST_CHECK(!CheckedLeftShift<T>(MAX, 1));
1762 BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits));
1763 BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits + 1));
1764
1765 if constexpr (std::is_signed_v<T>) {
1766 constexpr auto MIN{std::numeric_limits<T>::min()};
1767 // Negative input
1768 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(-1, 1), -2);
1769 BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 2), 1), MIN / 2);
1770 BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2);
1771 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MIN >> 1, 1), MIN);
1772 // Overflow negative
1773 BOOST_CHECK(!CheckedLeftShift<T>((MIN >> 1) - 1, 1));
1774 BOOST_CHECK(!CheckedLeftShift<T>(MIN >> 1, 2));
1775 BOOST_CHECK(!CheckedLeftShift<T>(-1, 100));
1776 }
1777}
1778
1779template <typename T>
1781{
1782 constexpr auto MAX{std::numeric_limits<T>::max()};
1783
1784 // Basic operations
1785 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 1), 0);
1786 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 127), 0);
1787 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, 1), 2);
1788 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(2, 2), 8);
1789 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX >> 1, 1), MAX - 1);
1790
1791 // Max left shift
1792 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1);
1793
1794 // Saturation cases
1795 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MAX >> 1) + 1, 1), MAX);
1796 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX, 1), MAX);
1797 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits), MAX);
1798 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits + 1), MAX);
1799
1800 if constexpr (std::is_signed_v<T>) {
1801 constexpr auto MIN{std::numeric_limits<T>::min()};
1802 // Negative input
1803 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 1), -2);
1804 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 2), 1), MIN / 2);
1805 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2);
1806 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 1), MIN);
1807 // Saturation negative
1808 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) - 1, 1), MIN);
1809 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 2), MIN);
1810 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 100), MIN);
1811 }
1812}
1813
1814BOOST_AUTO_TEST_CASE(checked_left_shift_test)
1815{
1816 TestCheckedLeftShift<uint8_t>();
1817 TestCheckedLeftShift<int8_t>();
1818 TestCheckedLeftShift<size_t>();
1819 TestCheckedLeftShift<uint64_t>();
1820 TestCheckedLeftShift<int64_t>();
1821}
1822
1823BOOST_AUTO_TEST_CASE(saturating_left_shift_test)
1824{
1825 TestSaturatingLeftShift<uint8_t>();
1826 TestSaturatingLeftShift<int8_t>();
1827 TestSaturatingLeftShift<size_t>();
1828 TestSaturatingLeftShift<uint64_t>();
1829 TestSaturatingLeftShift<int64_t>();
1830}
1831
1832template <class Int, auto bytes>
1833concept BraceInitializesTo = requires { Int{bytes}; };
1834
1835BOOST_AUTO_TEST_CASE(mib_string_literal_test)
1836{
1837 // Basic equivalences and simple arithmetic operations
1838 BOOST_CHECK_EQUAL(0_MiB, 0);
1839 BOOST_CHECK_EQUAL(1_MiB, 1 << 20);
1840 BOOST_CHECK_EQUAL(1_MiB, 1024 * 1024);
1841 BOOST_CHECK_EQUAL(1_MiB, 0x100000U);
1842 BOOST_CHECK_EQUAL(1_MiB, 1048576U);
1843 BOOST_CHECK_EQUAL(2ULL * 1_MiB, 2ULL << 20);
1844 BOOST_CHECK_EQUAL((3_MiB + 123) / double(1_MiB), (3_MiB + 123) / 1024.0 / 1024.0);
1845
1846 // Specific codebase values
1847 BOOST_CHECK_EQUAL(4_MiB, 1 << 22);
1848 BOOST_CHECK_EQUAL(8_MiB, 1 << 23);
1849 BOOST_CHECK_EQUAL(16_MiB, 0x1000000U);
1850 BOOST_CHECK_EQUAL(16_MiB, 1 << 24);
1851 BOOST_CHECK_EQUAL(32_MiB, 0x2000000U);
1852 BOOST_CHECK_EQUAL(32_MiB, 32U << 20);
1853 BOOST_CHECK_EQUAL(50_MiB / 1_MiB, 50U);
1854 BOOST_CHECK_EQUAL(50_MiB, 52428800U);
1855 BOOST_CHECK_EQUAL(128_MiB, 0x8000000U);
1856 BOOST_CHECK_EQUAL(550_MiB, 550ULL * 1024 * 1024);
1857
1858 // 4095 MiB fits in uint32_t bytes. 4096 MiB requires the uint64_t return type.
1862 BOOST_CHECK_EQUAL(4095_MiB, uint32_t{4095} << 20);
1863 BOOST_CHECK_EQUAL(4096_MiB, uint64_t{4096} << 20);
1864}
1865
1867{
1868 // Type combinations used by current CeilDiv callsites.
1869 BOOST_CHECK((std::is_same_v<decltype(CeilDiv(uint32_t{0}, 8u)), uint32_t>));
1870 BOOST_CHECK((std::is_same_v<decltype(CeilDiv(size_t{0}, 8u)), size_t>));
1871 BOOST_CHECK((std::is_same_v<decltype(CeilDiv(unsigned{0}, size_t{1})), size_t>));
1872
1873 // `common/bloom.cpp` and `cuckoocache.h` patterns.
1874 BOOST_CHECK_EQUAL(CeilDiv(uint32_t{3}, 2u), uint32_t{2});
1875 BOOST_CHECK_EQUAL(CeilDiv(uint32_t{65}, 64u), uint32_t{2});
1876 BOOST_CHECK_EQUAL(CeilDiv(uint32_t{9}, 8u), uint32_t{2});
1877
1878 // `key_io.cpp`, `rest.cpp`, `merkleblock.cpp`, `strencodings.cpp` patterns.
1879 BOOST_CHECK_EQUAL(CeilDiv(size_t{9}, 8u), size_t{2});
1880 BOOST_CHECK_EQUAL(CeilDiv(size_t{10}, 3u), size_t{4});
1881 BOOST_CHECK_EQUAL(CeilDiv(size_t{11}, 5u), size_t{3});
1882 BOOST_CHECK_EQUAL(CeilDiv(size_t{41} * 8, 5u), size_t{66});
1883
1884 // `flatfile.cpp` mixed unsigned/size_t pattern.
1885 BOOST_CHECK_EQUAL(CeilDiv(unsigned{10}, size_t{4}), size_t{3});
1886
1887 // `util/feefrac.h` fast-path rounding-up pattern.
1888 constexpr int64_t fee{12345};
1889 constexpr int32_t at_size{67};
1890 constexpr int32_t size{10};
1891 BOOST_CHECK_EQUAL(CeilDiv(uint64_t(fee) * at_size, uint32_t(size)),
1892 (uint64_t(fee) * at_size + uint32_t(size) - 1) / uint32_t(size));
1893
1894 // `bitset.h` template parameter pattern.
1895 constexpr unsigned bits{129};
1896 constexpr size_t digits{std::numeric_limits<size_t>::digits};
1897 BOOST_CHECK_EQUAL(CeilDiv(bits, digits), (bits + digits - 1) / digits);
1898
1899 // `serialize.h` varint scratch-buffer pattern.
1900 BOOST_CHECK_EQUAL(CeilDiv(sizeof(uint64_t) * 8, 7u), (sizeof(uint64_t) * 8 + 6) / 7);
1901}
1902
1903BOOST_AUTO_TEST_CASE(gib_string_literal_test)
1904{
1905 // Basic equivalences and simple arithmetic operations
1906 BOOST_CHECK_EQUAL(0_GiB, 0);
1907 BOOST_CHECK_EQUAL(1_GiB, 1 << 30);
1908 BOOST_CHECK_EQUAL(1_GiB, 1024 * 1024 * 1024);
1909 BOOST_CHECK_EQUAL(1_GiB, 0x40000000U);
1910 BOOST_CHECK_EQUAL(1_GiB, 1073741824U);
1911 BOOST_CHECK_EQUAL(1_GiB, 1_MiB * 1024);
1912 BOOST_CHECK_EQUAL(1_GiB, 1024_MiB);
1913 BOOST_CHECK_EQUAL((1_GiB + 123) / double(1_GiB), (1_GiB + 123) / 1024.0 / 1024.0 / 1024.0);
1914 BOOST_CHECK_EQUAL(2ULL * 1_GiB, 2ULL << 30);
1915 BOOST_CHECK_EQUAL(4 * uint64_t{1_GiB}, uint64_t{4} << 30);
1916 BOOST_CHECK_EQUAL(2_GiB, 2048_MiB);
1917 BOOST_CHECK_EQUAL(3_GiB / 1_GiB, 3U);
1918 BOOST_CHECK_EQUAL(3_GiB, 3U << 30);
1919
1920 // 3 GiB fits in uint32_t bytes. 4 GiB requires the uint64_t return type.
1924 BOOST_CHECK_EQUAL(3_GiB, uint32_t{3} << 30);
1925 BOOST_CHECK_EQUAL(4_GiB, uint64_t{4} << 30);
1926
1927 // Specific codebase values
1928 BOOST_CHECK_EQUAL(4_GiB, 4096_MiB);
1929 BOOST_CHECK_EQUAL(8_GiB, 8192_MiB);
1930 BOOST_CHECK_EQUAL(16_GiB, 16384_MiB);
1931 BOOST_CHECK_EQUAL(32_GiB, 32768_MiB);
1932}
1933
1934BOOST_AUTO_TEST_CASE(token_bucket_initial_value)
1935{
1936 // Initial value is clamped to cap
1937 util::TokenBucket<NodeClock> b1(/*rate=*/1, /*value=*/100, /*cap=*/10);
1938 BOOST_CHECK_EQUAL(b1.value(), 10);
1939
1940 // Initial value below cap is kept as-is
1941 util::TokenBucket<NodeClock> b2(/*rate=*/1, /*value=*/5, /*cap=*/10);
1942 BOOST_CHECK_EQUAL(b2.value(), 5);
1943}
1944
1945BOOST_AUTO_TEST_CASE(token_bucket_first_increment)
1946{
1947 // First increment establishes the time baseline but does not refill
1948 util::TokenBucket<NodeClock> b(/*rate=*/100, /*value=*/0, /*cap=*/1000);
1950 BOOST_CHECK_EQUAL(b.value(), 0);
1951
1952 // Second increment refills based on elapsed time
1954 BOOST_CHECK_EQUAL(b.value(), 500); // 100/s * 5s
1955}
1956
1957BOOST_AUTO_TEST_CASE(token_bucket_refill_caps)
1958{
1959 util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/90, /*cap=*/100);
1961 b.increment(NodeClock::time_point{100s}); // would add 990, but cap is 100
1962 BOOST_CHECK_EQUAL(b.value(), 100);
1963}
1964
1965BOOST_AUTO_TEST_CASE(token_bucket_time_backwards)
1966{
1967 util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/50, /*cap=*/200);
1969 b.increment(NodeClock::time_point{5s}); // backwards, no change
1970 BOOST_CHECK_EQUAL(b.value(), 50);
1971 b.increment(NodeClock::time_point{15s}); // forwards takes backwards into account
1972 BOOST_CHECK_EQUAL(b.value(), 150);
1973}
1974
1975BOOST_AUTO_TEST_CASE(token_bucket_decrement_no_debt)
1976{
1977 // Default debt=0: returns false at exactly 0
1978 util::TokenBucket<NodeClock> b(/*rate=*/1, /*value=*/3, /*cap=*/10);
1979 BOOST_CHECK(b.decrement(1)); // 3 -> 2
1980 BOOST_CHECK(b.decrement(1)); // 2 -> 1
1981 BOOST_CHECK(!b.decrement(1)); // 1 -> 0, at floor
1982 BOOST_CHECK_EQUAL(b.value(), 0);
1983 BOOST_CHECK(!b.decrement(1)); // 0 -> -1, despite being at floor
1984 BOOST_CHECK_EQUAL(b.value(), -1);
1985}
1986
1987BOOST_AUTO_TEST_CASE(token_bucket_decrement_with_debt)
1988{
1989 util::TokenBucket<NodeClock> b(/*rate=*/1, /*value=*/2, /*cap=*/10);
1990 BOOST_CHECK(b.decrement(1, -3)); // 2 -> 1
1991 BOOST_CHECK(b.decrement(1, -3)); // 1 -> 0
1992 BOOST_CHECK(b.decrement(1, -3)); // 0 -> -1, still above -3
1993 BOOST_CHECK(b.decrement(1, -3)); // -1 -> -2, still above -3
1994 BOOST_CHECK(!b.decrement(1, -3)); // -2 -> -3, at floor
1995 BOOST_CHECK_EQUAL(b.value(), -3);
1996}
1997
1998BOOST_AUTO_TEST_CASE(token_bucket_drain_and_refill)
1999{
2000 util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/20, /*cap=*/100);
2001 b.decrement(20); // drain to 0
2002 BOOST_CHECK_EQUAL(b.value(), 0);
2003
2005 b.increment(NodeClock::time_point{4s}); // +30
2006 BOOST_CHECK_EQUAL(b.value(), 30);
2007}
2008
2009
2010BOOST_AUTO_TEST_CASE(token_bucket_first_increment_at_epoch)
2011{
2012 // The first increment establishes the baseline (no refill) even when it
2013 // lands exactly on the clock epoch; later increments then refill normally.
2014 util::TokenBucket<NodeClock> b(/*rate=*/100, /*value=*/0, /*cap=*/1000);
2016 BOOST_CHECK_EQUAL(b.value(), 0);
2018 BOOST_CHECK_EQUAL(b.value(), 500); // 100/s * 5s
2019}
2020
2021BOOST_AUTO_TEST_CASE(token_bucket_at_cap_advances_baseline)
2022{
2023 util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/100, /*cap=*/100);
2024 BOOST_CHECK_EQUAL(b.value(), 100); // already at cap
2025 b.increment(NodeClock::time_point{1s}); // baseline established at 1s
2026 b.increment(NodeClock::time_point{100s}); // 99s spent at the cap; baseline -> 100s
2027 BOOST_CHECK_EQUAL(b.value(), 100);
2028
2029 b.decrement(100); // drain to 0
2030 BOOST_CHECK_EQUAL(b.value(), 0);
2031
2032 // refill doesn't "bank" the extra 99s we were at cap
2034 BOOST_CHECK_EQUAL(b.value(), 10);
2035
2036 // And when real time genuinely elapses, a single increment refills straight
2037 // back to the cap immediately.
2038 b.increment(NodeClock::time_point{200s}); // 99s elapsed -> +990, clamped to cap
2039 BOOST_CHECK_EQUAL(b.value(), 100);
2040}
2041
2042BOOST_AUTO_TEST_CASE(token_bucket_fractional_refill)
2043{
2044 // Sub-second elapsed time accumulates fractional tokens via double math.
2045 util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/0, /*cap=*/100);
2047 b.increment(NodeClock::time_point{1250ms}); // 10/s * 0.25s = 2.5
2048 BOOST_CHECK_EQUAL(b.value(), 2.5);
2049}
2050
2051BOOST_AUTO_TEST_CASE(token_bucket_refill_from_debt)
2052{
2053 // Refilling from a negative (debt) balance accrues normally and still
2054 // clamps to the cap rather than to debt + increment.
2055 util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/0, /*cap=*/100);
2056 BOOST_CHECK(!b.decrement(50)); // -> -50, below floor 0
2057 BOOST_CHECK_EQUAL(b.value(), -50);
2058 b.increment(NodeClock::time_point{1s}); // baseline
2059 b.increment(NodeClock::time_point{4s}); // +30 -> -20
2060 BOOST_CHECK_EQUAL(b.value(), -20);
2061 b.increment(NodeClock::time_point{100s}); // +960 but clamped to cap
2062 BOOST_CHECK_EQUAL(b.value(), 100);
2063}
2064
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15
static void pool cs
#define Assert(val)
Identity function.
Definition: check.h:116
#define Assume(val)
Assume is the identity function.
Definition: check.h:128
An encapsulated private key.
Definition: key.h:40
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:128
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:108
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
Definition: time.h:54
256-bit opaque blob.
Definition: uint256.h:196
A token bucket rate limiter.
Definition: tokenbucket.h:24
bool decrement(double n=1.0, double floor=0.0)
Consume n tokens.
Definition: tokenbucket.h:52
void increment(const time_point &now)
Refill tokens based on elapsed time since last call.
Definition: tokenbucket.h:40
double value() const
Current token balance.
Definition: tokenbucket.h:59
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...
uint256 MessageHash(const std::string &message)
Hashes a message for signing and verification in a manner that prevents inadvertently signing a trans...
Definition: signmessage.cpp:76
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: signmessage.cpp:60
const std::string MESSAGE_MAGIC
Text used to signify that a signed message follows and to prevent inadvertently signing a transaction...
Definition: signmessage.cpp:27
MessageVerificationResult MessageVerify(const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: signmessage.cpp:29
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: fs_helpers.cpp:87
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:83
#define T(expected, seed, data)
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:30
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
std::thread thread
Thread variable should be after other struct members so the thread does not start until the other mem...
uint64_t fee
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:45
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:19
std::string LogEscapeMessage(std::string_view str)
Belts and suspenders: make sure outgoing log messages don't contain potentially suspicious characters...
Definition: logging.cpp:337
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
Definition: parsing.cpp:31
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
Definition: parsing.cpp:22
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
Definition: parsing.cpp:13
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
Definition: strencodings.h:386
std::vector< std::string > SplitString(std::string_view str, char sep)
Definition: string.h:152
consteval uint8_t ConstevalHexDigit(const char c)
consteval version of HexDigit() without the lookup table.
Definition: strencodings.h:331
std::string_view TrimStringView(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
Definition: string.h:162
LockResult
Definition: fs_helpers.h:69
std::string_view RemovePrefixView(std::string_view str, std::string_view prefix)
Definition: string.h:185
std::string TrimString(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
Definition: string.h:172
std::string RemovePrefix(std::string_view str, std::string_view prefix)
Definition: string.h:193
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition: string.h:208
void ReplaceAll(std::string &in_out, const std::string &search, const std::string &substitute)
Definition: string.cpp:14
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
Definition: string.h:119
LockResult LockDirectory(const fs::path &directory, const fs::path &lockfile_name, bool probe_only)
Definition: fs_helpers.cpp:53
#define BOOST_CHECK(expr)
Definition: object.cpp:16
std::optional< T > CheckedAdd(const T i, const T j) noexcept
Definition: overflow.h:27
constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
Integer ceiling division (for unsigned values).
Definition: overflow.h:70
T SaturatingAdd(const T i, const T j) noexcept
Definition: overflow.h:44
bool WriteBinaryFile(const fs::path &filename, const std::string &data)
Write contents of std::string to a file.
std::pair< bool, std::string > ReadBinaryFile(const fs::path &filename, size_t maxsize)
Read full contents of a file and return them in a std::string.
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
@ ERR_INVALID_ADDRESS
The provided address is invalid.
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
@ OK
The message verification was successful.
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
auto MakeByteSpan(const V &v) noexcept
Definition: span.h:84
constexpr auto MakeUCharSpan(const V &v) -> decltype(UCharSpanCast(std::span{v}))
Like the std::span constructor, but for (const) unsigned char member types only.
Definition: span.h:111
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:150
bool TimingResistantEqual(const T &a, const T &b)
Timing-attack-resistant comparison.
Definition: strencodings.h:203
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h:69
@ SAFE_CHARS_UA_COMMENT
BIP-0014 subset.
Definition: strencodings.h:34
Basic testing setup.
Definition: setup_common.h:58
static time_point now() noexcept
Return current system time or mocked time, if set.
Definition: time.cpp:38
std::chrono::time_point< NodeClock > time_point
Definition: time.h:28
#define LOCK(cs)
Definition: sync.h:268
#define TRY_LOCK(cs, name)
Definition: sync.h:273
@ ZEROS
Seed with a compile time constant of zeros.
static int count
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
std::string Capitalize(std::string str)
Capitalizes the first character of the given string.
std::string ToUpper(std::string_view str)
Returns the uppercase equivalent of the given string.
bool ParseFixedPoint(std::string_view val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
bool IsHex(std::string_view str)
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.
std::optional< std::vector< Byte > > TryParseHex(std::string_view str)
Parse the hex string into bytes (uint8_t or std::byte).
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::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:30
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition: time.cpp:89
std::string FormatISO8601Date(int64_t nTime)
Definition: time.cpp:100
std::optional< int64_t > ParseISO8601DateTime(std::string_view str)
Definition: time.cpp:108
std::string FormatRFC1123DateTime(int64_t time)
RFC1123 formatting https://www.rfc-editor.org/rfc/rfc1123#section-5.2.14 Used in HTTP/1....
Definition: time.cpp:132
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: time.cpp:91
constexpr int64_t TicksSeconds(Duration d)
Definition: time.h:88
int64_t atoi64_legacy(const std::string &str)
Definition: util_tests.cpp:770
#define E
Definition: util_tests.cpp:566
constexpr uint8_t HEX_PARSE_OUTPUT[]
Definition: util_tests.cpp:149
constexpr char HEX_PARSE_INPUT[]
Definition: util_tests.cpp:148
static void TestOtherProcess(fs::path dirname, fs::path lockname, int fd)
#define B
Definition: util_tests.cpp:565
static constexpr char ExitCommand
static constexpr char UnlockCommand
static std::string SpanToStr(const std::span< const char > &span)
@ ResErrorWrite
@ ResUnlockSuccess
@ ResSuccess
@ ResErrorLock
static void TestAddMatrixOverflow()
Definition: util_tests.cpp:633
static void TestAddMatrix()
Definition: util_tests.cpp:653
BOOST_AUTO_TEST_CASE(util_check)
Definition: util_tests.cpp:100
static void RunToIntegralTests()
Definition: util_tests.cpp:680
static const std::string STRING_WITH_EMBEDDED_NULL_CHAR
Definition: util_tests.cpp:66
static constexpr char LockCommand
void TestCheckedLeftShift()
void TestSaturatingLeftShift()
assert(!tx.IsCoinBase())
V Cat(V v1, V &&v2)
Concatenate two vectors, moving elements.
Definition: vector.h:34
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:23
void ClearShrink(V &v) noexcept
Clear a vector (or std::deque) and release its allocated memory.
Definition: vector.h:56