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