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