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 <util/bitdeque.h>
18#include <util/byte_units.h>
19#include <util/fs.h>
20#include <util/fs_helpers.h>
21#include <util/moneystr.h>
22#include <util/overflow.h>
23#include <util/readwritefile.h>
24#include <util/strencodings.h>
25#include <util/string.h>
26#include <util/time.h>
27#include <util/vector.h>
28
29#include <array>
30#include <cmath>
31#include <cstdint>
32#include <cstring>
33#include <fstream>
34#include <limits>
35#include <map>
36#include <optional>
37#include <string>
38#include <thread>
39#include <univalue.h>
40#include <utility>
41#include <vector>
42
43#include <sys/types.h>
44
45#ifndef WIN32
46#include <sys/wait.h>
47#endif
48
49#include <boost/test/unit_test.hpp>
50
51using namespace std::literals;
52using namespace util::hex_literals;
54using util::Join;
58using util::Split;
62
63static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s};
64
65/* defined in logging.cpp */
66namespace BCLog {
67 std::string LogEscapeMessage(std::string_view str);
68}
69
71
72namespace {
73class NoCopyOrMove
74{
75public:
76 int i;
77 explicit NoCopyOrMove(int i) : i{i} { }
78
79 NoCopyOrMove() = delete;
80 NoCopyOrMove(const NoCopyOrMove&) = delete;
81 NoCopyOrMove(NoCopyOrMove&&) = delete;
82 NoCopyOrMove& operator=(const NoCopyOrMove&) = delete;
83 NoCopyOrMove& operator=(NoCopyOrMove&&) = delete;
84
85 operator bool() const { return i != 0; }
86
87 int get_ip1() { return i + 1; }
88 bool test()
89 {
90 // Check that Assume can be used within a lambda and still call methods
91 [&]() { Assume(get_ip1()); }();
92 return Assume(get_ip1() != 5);
93 }
94};
95} // namespace
96
98{
99 // Check that Assert can forward
100 const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2));
101 // Check that Assert works on lvalues and rvalues
102 const int two = *Assert(p_two);
103 Assert(two == 2);
104 Assert(true);
105 // Check that Assume can be used as unary expression
106 const bool result{Assume(two == 2)};
107 Assert(result);
108
109 // Check that Assert doesn't require copy/move
110 NoCopyOrMove x{9};
111 Assert(x).i += 3;
112 Assert(x).test();
113
114 // Check nested Asserts
115 BOOST_CHECK_EQUAL(Assert((Assert(x).test() ? 3 : 0)), 3);
116
117 // Check -Wdangling-gsl does not trigger when copying the int. (It would
118 // trigger on "const int&")
119 const int nine{*Assert(std::optional<int>{9})};
120 BOOST_CHECK_EQUAL(9, nine);
121}
122
123BOOST_AUTO_TEST_CASE(util_criticalsection)
124{
126
127 do {
128 LOCK(cs);
129 break;
130
131 BOOST_ERROR("break was swallowed!");
132 } while(0);
133
134 do {
135 TRY_LOCK(cs, lockTest);
136 if (lockTest) {
137 BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
138 break;
139 }
140
141 BOOST_ERROR("break was swallowed!");
142 } while(0);
143}
144
145constexpr char HEX_PARSE_INPUT[] = "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f";
146constexpr uint8_t HEX_PARSE_OUTPUT[] = {
147 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
148 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
149 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
150 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
151 0x5f
152};
153static_assert((sizeof(HEX_PARSE_INPUT) - 1) == 2 * sizeof(HEX_PARSE_OUTPUT));
155{
156 std::vector<unsigned char> result;
157
158 // Basic test vector
159 std::vector<unsigned char> expected(std::begin(HEX_PARSE_OUTPUT), std::end(HEX_PARSE_OUTPUT));
160 constexpr std::array<std::byte, 65> hex_literal_array{operator""_hex<util::detail::Hex(HEX_PARSE_INPUT)>()};
161 auto hex_literal_span{MakeUCharSpan(hex_literal_array)};
162 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end());
163
164 const std::vector<std::byte> hex_literal_vector{operator""_hex_v<util::detail::Hex(HEX_PARSE_INPUT)>()};
165 auto hex_literal_vec_span = MakeUCharSpan(hex_literal_vector);
166 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_vec_span.begin(), hex_literal_vec_span.end(), expected.begin(), expected.end());
167
168 constexpr std::array<uint8_t, 65> hex_literal_array_uint8{operator""_hex_u8<util::detail::Hex(HEX_PARSE_INPUT)>()};
169 BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_array_uint8.begin(), hex_literal_array_uint8.end(), expected.begin(), expected.end());
170
171 result = operator""_hex_v_u8<util::detail::Hex(HEX_PARSE_INPUT)>();
172 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
173
174 result = ParseHex(HEX_PARSE_INPUT);
175 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
176
177 result = TryParseHex<uint8_t>(HEX_PARSE_INPUT).value();
178 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
179
180 // Spaces between bytes must be supported
181 expected = {0x12, 0x34, 0x56, 0x78};
182 result = ParseHex("12 34 56 78");
183 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
184 result = TryParseHex<uint8_t>("12 34 56 78").value();
185 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
186
187 // Leading space must be supported
188 expected = {0x89, 0x34, 0x56, 0x78};
189 result = ParseHex(" 89 34 56 78");
190 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
191 result = TryParseHex<uint8_t>(" 89 34 56 78").value();
192 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
193
194 // Mixed case and spaces are supported
195 expected = {0xff, 0xaa};
196 result = ParseHex(" Ff aA ");
197 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
198 result = TryParseHex<uint8_t>(" Ff aA ").value();
199 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
200
201 // Empty string is supported
202 static_assert(""_hex.empty());
203 static_assert(""_hex_u8.empty());
204 BOOST_CHECK_EQUAL(""_hex_v.size(), 0);
205 BOOST_CHECK_EQUAL(""_hex_v_u8.size(), 0);
206 BOOST_CHECK_EQUAL(ParseHex("").size(), 0);
207 BOOST_CHECK_EQUAL(TryParseHex<uint8_t>("").value().size(), 0);
208
209 // Spaces between nibbles is treated as invalid
210 BOOST_CHECK_EQUAL(ParseHex("AAF F").size(), 0);
211 BOOST_CHECK(!TryParseHex("AAF F").has_value());
212
213 // Embedded null is treated as invalid
214 const std::string with_embedded_null{" 11 "s
215 " \0 "
216 " 22 "s};
217 BOOST_CHECK_EQUAL(with_embedded_null.size(), 11);
218 BOOST_CHECK_EQUAL(ParseHex(with_embedded_null).size(), 0);
219 BOOST_CHECK(!TryParseHex(with_embedded_null).has_value());
220
221 // Non-hex is treated as invalid
222 BOOST_CHECK_EQUAL(ParseHex("1234 invalid 1234").size(), 0);
223 BOOST_CHECK(!TryParseHex("1234 invalid 1234").has_value());
224
225 // Truncated input is treated as invalid
226 BOOST_CHECK_EQUAL(ParseHex("12 3").size(), 0);
227 BOOST_CHECK(!TryParseHex("12 3").has_value());
228}
229
230BOOST_AUTO_TEST_CASE(consteval_hex_digit)
231{
236}
237
239{
241 BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.last(0)), "");
242 BOOST_CHECK_EQUAL(HexStr(std::span{HEX_PARSE_OUTPUT}.first(0)), "");
243
244 {
245 constexpr std::string_view out_exp{"04678afdb0"};
246 constexpr std::span in_s{HEX_PARSE_OUTPUT, out_exp.size() / 2};
247 const std::span<const uint8_t> in_u{MakeUCharSpan(in_s)};
248 const std::span<const std::byte> in_b{MakeByteSpan(in_s)};
249
250 BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
251 BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
252 BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
253 }
254
255 {
256 auto input = std::string();
257 for (size_t i=0; i<256; ++i) {
258 input.push_back(static_cast<char>(i));
259 }
260
261 auto hex = HexStr(input);
262 BOOST_TEST_REQUIRE(hex.size() == 512);
263 static constexpr auto hexmap = std::string_view("0123456789abcdef");
264 for (size_t i = 0; i < 256; ++i) {
265 auto upper = hexmap.find(hex[i * 2]);
266 auto lower = hexmap.find(hex[i * 2 + 1]);
267 BOOST_TEST_REQUIRE(upper != std::string_view::npos);
268 BOOST_TEST_REQUIRE(lower != std::string_view::npos);
269 BOOST_TEST_REQUIRE(i == upper*16 + lower);
270 }
271 }
272}
273
274BOOST_AUTO_TEST_CASE(span_write_bytes)
275{
276 std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}};
277 const auto mut_bytes{MakeWritableByteSpan(mut_arr)};
278 mut_bytes[1] = std::byte{0x11};
279 BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa);
280 BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11);
281}
282
284{
285 // Normal version
286 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), "");
287 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo");
288 BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar");
289
290 // Version with unary operator
291 const auto op_upper = [](const std::string& s) { return ToUpper(s); };
292 BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), "");
293 BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO");
294 BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR");
295}
296
297BOOST_AUTO_TEST_CASE(util_ReplaceAll)
298{
299 const std::string original("A test \"%s\" string '%s'.");
300 auto test_replaceall = [&original](const std::string& search, const std::string& substitute, const std::string& expected) {
301 auto test = original;
302 ReplaceAll(test, search, substitute);
303 BOOST_CHECK_EQUAL(test, expected);
304 };
305
306 test_replaceall("", "foo", original);
307 test_replaceall(original, "foo", "foo");
308 test_replaceall("%s", "foo", "A test \"foo\" string 'foo'.");
309 test_replaceall("\"", "foo", "A test foo%sfoo string '%s'.");
310 test_replaceall("'", "foo", "A test \"%s\" string foo%sfoo.");
311}
312
313BOOST_AUTO_TEST_CASE(util_TrimString)
314{
315 BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar");
316 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");
317 BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar");
318 BOOST_CHECK_EQUAL(TrimStringView("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n ");
319 BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar");
320 BOOST_CHECK_EQUAL(TrimStringView("foo bar", "fobar"), " ");
321 BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7));
322 BOOST_CHECK_EQUAL(TrimStringView(std::string(" foo ", 5)), std::string("foo", 3));
323 BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2));
324 BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6));
325 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));
326 BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), "");
327}
328
329BOOST_AUTO_TEST_CASE(util_ParseISO8601DateTime)
330{
331 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1969-12-31T23:59:59Z").value(), -1);
332 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z").value(), 0);
333 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:01Z").value(), 1);
334 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:01Z").value(), 946684801);
335 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z").value(), 1317425777);
336 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2100-12-31T23:59:59Z").value(), 4133980799);
337 BOOST_CHECK_EQUAL(ParseISO8601DateTime("9999-12-31T23:59:59Z").value(), 253402300799);
338
339 // Accept edge-cases, where the time overflows. They are not produced by
340 // FormatISO8601DateTime, so this can be changed in the future, if needed.
341 // For now, keep compatibility with the previous implementation.
342 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:00:00Z").value(), 947041200);
343 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:99:00Z").value(), 946690740);
344 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:99Z").value(), 946684899);
345 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:99:99Z").value(), 947047239);
346
347 // Reject date overflows.
348 BOOST_CHECK(!ParseISO8601DateTime("2000-99-01T00:00:00Z"));
349 BOOST_CHECK(!ParseISO8601DateTime("2000-01-99T00:00:00Z"));
350
351 // Reject out-of-range years
352 BOOST_CHECK(!ParseISO8601DateTime("32768-12-31T23:59:59Z"));
353 BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T23:59:59Z"));
354 BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T00:00:00Z"));
355 BOOST_CHECK(!ParseISO8601DateTime("999-12-31T00:00:00Z"));
356
357 // Reject invalid format
358 const std::string valid{"2000-01-01T00:00:01Z"};
359 BOOST_CHECK(ParseISO8601DateTime(valid).has_value());
360 for (auto mut{0U}; mut < valid.size(); ++mut) {
361 std::string invalid{valid};
362 invalid[mut] = 'a';
364 }
365}
366
367BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime)
368{
369 BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z");
370 BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z");
371
372 BOOST_CHECK_EQUAL(FormatISO8601DateTime(-1), "1969-12-31T23:59:59Z");
373 BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z");
374 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1), "1970-01-01T00:00:01Z");
375 BOOST_CHECK_EQUAL(FormatISO8601DateTime(946684801), "2000-01-01T00:00:01Z");
376 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
377 BOOST_CHECK_EQUAL(FormatISO8601DateTime(4133980799), "2100-12-31T23:59:59Z");
378 BOOST_CHECK_EQUAL(FormatISO8601DateTime(253402300799), "9999-12-31T23:59:59Z");
379}
380
381BOOST_AUTO_TEST_CASE(util_FormatISO8601Date)
382{
383 BOOST_CHECK_EQUAL(FormatISO8601Date(971890963199), "32767-12-31");
384 BOOST_CHECK_EQUAL(FormatISO8601Date(971890876800), "32767-12-31");
385
386 BOOST_CHECK_EQUAL(FormatISO8601Date(0), "1970-01-01");
387 BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30");
388}
389
390
391BOOST_AUTO_TEST_CASE(util_FormatRFC1123DateTime)
392{
393 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(std::numeric_limits<int64_t>::max()), "");
394 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(253402300800), "");
395 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(253402300799), "Fri, 31 Dec 9999 23:59:59 GMT");
396 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(253402214400), "Fri, 31 Dec 9999 00:00:00 GMT");
397 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(1717429609), "Mon, 03 Jun 2024 15:46:49 GMT");
398 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(0), "Thu, 01 Jan 1970 00:00:00 GMT");
399 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-1), "Wed, 31 Dec 1969 23:59:59 GMT");
400 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-1717429609), "Sat, 31 Jul 1915 08:13:11 GMT");
401 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-62167219200), "Sat, 01 Jan 0000 00:00:00 GMT");
402 BOOST_CHECK_EQUAL(FormatRFC1123DateTime(-62167219201), "");
403}
404
405BOOST_AUTO_TEST_CASE(util_FormatMoney)
406{
407 BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
408 BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
410
411 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
412 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
413 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
414 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
415 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
416 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
417 BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
418 BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
421 BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
422 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
423 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
424 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
425 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
426 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
427 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
428
429 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807");
430 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806");
431 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805");
432 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804");
433 // ...
434 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805");
435 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806");
436 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807");
437 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808");
438}
439
440BOOST_AUTO_TEST_CASE(util_ParseMoney)
441{
442 BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
443 BOOST_CHECK_EQUAL(ParseMoney(".").value(), 0);
444 BOOST_CHECK_EQUAL(ParseMoney("0.").value(), 0);
445 BOOST_CHECK_EQUAL(ParseMoney(".0").value(), 0);
446 BOOST_CHECK_EQUAL(ParseMoney(".6789").value(), 6789'0000);
447 BOOST_CHECK_EQUAL(ParseMoney("12345.").value(), COIN * 12345);
448
449 BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
450
451 BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
452 BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
453 BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
454 BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
455 BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
456 BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
457 BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
458 BOOST_CHECK_EQUAL(ParseMoney("1.00").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(" 1 ").value(), COIN);
463 BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
464 BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
465 BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
466 BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
467 BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
468 BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
469 BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
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 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
474
475 // Parsing amount that cannot be represented should fail
476 BOOST_CHECK(!ParseMoney("100000000.00"));
477 BOOST_CHECK(!ParseMoney("0.000000001"));
478
479 // Parsing empty string should fail
481 BOOST_CHECK(!ParseMoney(" "));
482 BOOST_CHECK(!ParseMoney(" "));
483
484 // Parsing two numbers should fail
485 BOOST_CHECK(!ParseMoney(".."));
486 BOOST_CHECK(!ParseMoney("0..0"));
487 BOOST_CHECK(!ParseMoney("1 2"));
488 BOOST_CHECK(!ParseMoney(" 1 2 "));
489 BOOST_CHECK(!ParseMoney(" 1.2 3 "));
490 BOOST_CHECK(!ParseMoney(" 1 2.3 "));
491
492 // Embedded whitespace should fail
493 BOOST_CHECK(!ParseMoney(" -1 .2 "));
494 BOOST_CHECK(!ParseMoney(" 1 .2 "));
495 BOOST_CHECK(!ParseMoney(" +1 .2 "));
496
497 // Attempted 63 bit overflow should fail
498 BOOST_CHECK(!ParseMoney("92233720368.54775808"));
499
500 // Parsing negative amounts must fail
501 BOOST_CHECK(!ParseMoney("-1"));
502
503 // Parsing strings with embedded NUL characters should fail
504 BOOST_CHECK(!ParseMoney("\0-1"s));
506 BOOST_CHECK(!ParseMoney("1\0"s));
507}
508
510{
511 BOOST_CHECK(IsHex("00"));
512 BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
513 BOOST_CHECK(IsHex("ff"));
514 BOOST_CHECK(IsHex("FF"));
515
516 BOOST_CHECK(!IsHex(""));
517 BOOST_CHECK(!IsHex("0"));
518 BOOST_CHECK(!IsHex("a"));
519 BOOST_CHECK(!IsHex("eleven"));
520 BOOST_CHECK(!IsHex("00xx00"));
521 BOOST_CHECK(!IsHex("0x0000"));
522}
523
524BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
525{
526 SeedRandomForTest(SeedRand::ZEROS);
527 for (int mod=2;mod<11;mod++)
528 {
529 int mask = 1;
530 // Really rough binomial confidence approximation.
531 int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
532 //mask is 2^ceil(log2(mod))-1
533 while(mask<mod-1)mask=(mask<<1)+1;
534
535 int count = 0;
536 //How often does it get a zero from the uniform range [0,mod)?
537 for (int i = 0; i < 10000; i++) {
538 uint32_t rval;
539 do{
540 rval=m_rng.rand32()&mask;
541 }while(rval>=(uint32_t)mod);
542 count += rval==0;
543 }
544 BOOST_CHECK(count<=10000/mod+err);
545 BOOST_CHECK(count>=10000/mod-err);
546 }
547}
548
549BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
550{
551 BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
552 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
553 BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
554 BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
555 BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
556 BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
557 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
558}
559
560/* Test strprintf formatting directives.
561 * Put a string before and after to ensure sanity of element sizes on stack. */
562#define B "check_prefix"
563#define E "check_postfix"
564BOOST_AUTO_TEST_CASE(strprintf_numbers)
565{
566 int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
567 uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
568 BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
569 BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
570 BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
571
572 size_t st = 12345678; /* unsigned size_t test value */
573 ssize_t sst = -12345678; /* signed size_t test value */
574 BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
575 BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
576 BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
577
578 ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
579 ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
580 BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
581 BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
582 BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
583}
584#undef B
585#undef E
586
588{
589 NodeClockContext clock_ctx{111s};
590 // Check that mock time does not change after a sleep
591 for (const auto& num_sleep : {0ms, 1ms}) {
592 UninterruptibleSleep(num_sleep);
593 BOOST_CHECK_EQUAL(111, GetTime()); // Deprecated time getter
594 BOOST_CHECK_EQUAL(111, Now<NodeSeconds>().time_since_epoch().count());
595 BOOST_CHECK_EQUAL(111, TicksSinceEpoch<std::chrono::seconds>(NodeClock::now()));
596 BOOST_CHECK_EQUAL(111, TicksSinceEpoch<SecondsDouble>(Now<NodeSeconds>()));
597 BOOST_CHECK_EQUAL(111, GetTime<std::chrono::seconds>().count());
598 BOOST_CHECK_EQUAL(111000, GetTime<std::chrono::milliseconds>().count());
599 BOOST_CHECK_EQUAL(111000, TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()));
600 BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count());
601 }
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(dirname / lockname);
1142 fs::remove(dirname);
1143}
1144
1146{
1147 BOOST_CHECK_EQUAL(ToLower('@'), '@');
1148 BOOST_CHECK_EQUAL(ToLower('A'), 'a');
1149 BOOST_CHECK_EQUAL(ToLower('Z'), 'z');
1150 BOOST_CHECK_EQUAL(ToLower('['), '[');
1152 BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
1153
1154 BOOST_CHECK_EQUAL(ToLower(""), "");
1155 BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl");
1156 BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff");
1157}
1158
1160{
1161 BOOST_CHECK_EQUAL(ToUpper('`'), '`');
1162 BOOST_CHECK_EQUAL(ToUpper('a'), 'A');
1163 BOOST_CHECK_EQUAL(ToUpper('z'), 'Z');
1164 BOOST_CHECK_EQUAL(ToUpper('{'), '{');
1166 BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
1167
1168 BOOST_CHECK_EQUAL(ToUpper(""), "");
1169 BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL");
1170 BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff");
1171}
1172
1173BOOST_AUTO_TEST_CASE(test_Capitalize)
1174{
1176 BOOST_CHECK_EQUAL(Capitalize("bitcoin"), "Bitcoin");
1177 BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff");
1178}
1179
1180static std::string SpanToStr(const std::span<const char>& span)
1181{
1182 return std::string(span.begin(), span.end());
1183}
1184
1185BOOST_AUTO_TEST_CASE(test_script_parsing)
1186{
1187 using namespace script;
1188 std::string input;
1189 std::span<const char> sp;
1190 bool success;
1191
1192 // Const(...): parse a constant, update span to skip it if successful
1193 input = "MilkToastHoney";
1194 sp = input;
1195 success = Const("", sp); // empty
1196 BOOST_CHECK(success);
1197 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
1198
1199 success = Const("Milk", sp, /*skip=*/false);
1200 BOOST_CHECK(success);
1201 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
1202
1203 success = Const("Milk", sp);
1204 BOOST_CHECK(success);
1205 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
1206
1207 success = Const("Bread", sp, /*skip=*/false);
1208 BOOST_CHECK(!success);
1209
1210 success = Const("Bread", sp);
1211 BOOST_CHECK(!success);
1212
1213 success = Const("Toast", sp, /*skip=*/false);
1214 BOOST_CHECK(success);
1215 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
1216
1217 success = Const("Toast", sp);
1218 BOOST_CHECK(success);
1219 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
1220
1221 success = Const("Honeybadger", sp);
1222 BOOST_CHECK(!success);
1223
1224 success = Const("Honey", sp, /*skip=*/false);
1225 BOOST_CHECK(success);
1226 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
1227
1228 success = Const("Honey", sp);
1229 BOOST_CHECK(success);
1231 // Func(...): parse a function call, update span to argument if successful
1232 input = "Foo(Bar(xy,z()))";
1233 sp = input;
1234
1235 success = Func("FooBar", sp);
1236 BOOST_CHECK(!success);
1237
1238 success = Func("Foo(", sp);
1239 BOOST_CHECK(!success);
1240
1241 success = Func("Foo", sp);
1242 BOOST_CHECK(success);
1243 BOOST_CHECK_EQUAL(SpanToStr(sp), "Bar(xy,z())");
1244
1245 success = Func("Bar", sp);
1246 BOOST_CHECK(success);
1247 BOOST_CHECK_EQUAL(SpanToStr(sp), "xy,z()");
1248
1249 success = Func("xy", sp);
1250 BOOST_CHECK(!success);
1251
1252 // Expr(...): return expression that span begins with, update span to skip it
1253 std::span<const char> result;
1254
1255 input = "(n*(n-1))/2";
1256 sp = input;
1257 result = Expr(sp);
1258 BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2");
1260
1261 input = "foo,bar";
1262 sp = input;
1263 result = Expr(sp);
1264 BOOST_CHECK_EQUAL(SpanToStr(result), "foo");
1265 BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar");
1266
1267 input = "(aaaaa,bbbbb()),c";
1268 sp = input;
1269 result = Expr(sp);
1270 BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())");
1271 BOOST_CHECK_EQUAL(SpanToStr(sp), ",c");
1272
1273 input = "xyz)foo";
1274 sp = input;
1275 result = Expr(sp);
1276 BOOST_CHECK_EQUAL(SpanToStr(result), "xyz");
1277 BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo");
1278
1279 input = "((a),(b),(c)),xxx";
1280 sp = input;
1281 result = Expr(sp);
1282 BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))");
1283 BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
1284
1285 // Split(...): split a string on every instance of sep, return vector
1286 std::vector<std::span<const char>> results;
1287
1288 input = "xxx";
1289 results = Split(input, 'x');
1290 BOOST_CHECK_EQUAL(results.size(), 4U);
1291 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
1292 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "");
1293 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "");
1294 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
1295
1296 input = "one#two#three";
1297 results = Split(input, '-');
1298 BOOST_CHECK_EQUAL(results.size(), 1U);
1299 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three");
1300
1301 input = "one#two#three";
1302 results = Split(input, '#');
1303 BOOST_CHECK_EQUAL(results.size(), 3U);
1304 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one");
1305 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two");
1306 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
1307
1308 results = Split(input, '#', /*include_sep=*/true);
1309 BOOST_CHECK_EQUAL(results.size(), 3U);
1310 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#");
1311 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two#");
1312 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
1313
1314 input = "*foo*bar*";
1315 results = Split(input, '*');
1316 BOOST_CHECK_EQUAL(results.size(), 4U);
1317 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
1318 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo");
1319 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar");
1320 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
1321
1322 results = Split(input, '*', /*include_sep=*/true);
1323 BOOST_CHECK_EQUAL(results.size(), 4U);
1324 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "*");
1325 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo*");
1326 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar*");
1327 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
1328}
1329
1330BOOST_AUTO_TEST_CASE(test_SplitString)
1331{
1332 // Empty string.
1333 {
1334 std::vector<std::string> result = SplitString("", '-');
1335 BOOST_CHECK_EQUAL(result.size(), 1);
1336 BOOST_CHECK_EQUAL(result[0], "");
1337 }
1338
1339 // Empty items.
1340 {
1341 std::vector<std::string> result = SplitString("-", '-');
1342 BOOST_CHECK_EQUAL(result.size(), 2);
1343 BOOST_CHECK_EQUAL(result[0], "");
1344 BOOST_CHECK_EQUAL(result[1], "");
1345 }
1346
1347 // More empty items.
1348 {
1349 std::vector<std::string> result = SplitString("--", '-');
1350 BOOST_CHECK_EQUAL(result.size(), 3);
1351 BOOST_CHECK_EQUAL(result[0], "");
1352 BOOST_CHECK_EQUAL(result[1], "");
1353 BOOST_CHECK_EQUAL(result[2], "");
1354 }
1355
1356 // Separator is not present.
1357 {
1358 std::vector<std::string> result = SplitString("abc", '-');
1359 BOOST_CHECK_EQUAL(result.size(), 1);
1360 BOOST_CHECK_EQUAL(result[0], "abc");
1361 }
1362
1363 // Basic behavior.
1364 {
1365 std::vector<std::string> result = SplitString("a-b", '-');
1366 BOOST_CHECK_EQUAL(result.size(), 2);
1367 BOOST_CHECK_EQUAL(result[0], "a");
1368 BOOST_CHECK_EQUAL(result[1], "b");
1369 }
1370
1371 // Case-sensitivity of the separator.
1372 {
1373 std::vector<std::string> result = SplitString("AAA", 'a');
1374 BOOST_CHECK_EQUAL(result.size(), 1);
1375 BOOST_CHECK_EQUAL(result[0], "AAA");
1376 }
1377
1378 // multiple split characters
1379 {
1380 using V = std::vector<std::string>;
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("a,b.c:d;e", "") == V({"a,b.c:d;e"}));
1384 BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"}));
1385 BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"}));
1386 BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"}));
1387 BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"}));
1388 BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"}));
1389 }
1390}
1391
1392BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
1393{
1394 // ASCII and UTF-8 must pass through unaltered.
1395 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
1396 // Newlines must pass through unaltered.
1397 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
1398 // Other control characters are escaped in C syntax.
1399 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
1400 // Embedded NULL characters are escaped too.
1401 const std::string NUL("O\x00O", 3);
1402 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
1403}
1404
1405namespace {
1406
1407struct Tracker
1408{
1410 const Tracker* origin;
1412 int copies{0};
1413
1414 Tracker() noexcept : origin(this) {}
1415 Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
1416 Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
1417 Tracker& operator=(const Tracker& t) noexcept
1418 {
1419 if (this != &t) {
1420 origin = t.origin;
1421 copies = t.copies + 1;
1422 }
1423 return *this;
1424 }
1425};
1426
1427}
1428
1429BOOST_AUTO_TEST_CASE(test_tracked_vector)
1430{
1431 Tracker t1;
1432 Tracker t2;
1433 Tracker t3;
1434
1435 BOOST_CHECK(t1.origin == &t1);
1436 BOOST_CHECK(t2.origin == &t2);
1437 BOOST_CHECK(t3.origin == &t3);
1438
1439 auto v1 = Vector(t1);
1440 BOOST_CHECK_EQUAL(v1.size(), 1U);
1441 BOOST_CHECK(v1[0].origin == &t1);
1442 BOOST_CHECK_EQUAL(v1[0].copies, 1);
1443
1444 auto v2 = Vector(std::move(t2));
1445 BOOST_CHECK_EQUAL(v2.size(), 1U);
1446 BOOST_CHECK(v2[0].origin == &t2); // NOLINT(*-use-after-move)
1447 BOOST_CHECK_EQUAL(v2[0].copies, 0);
1448
1449 auto v3 = Vector(t1, std::move(t2));
1450 BOOST_CHECK_EQUAL(v3.size(), 2U);
1451 BOOST_CHECK(v3[0].origin == &t1);
1452 BOOST_CHECK(v3[1].origin == &t2); // NOLINT(*-use-after-move)
1453 BOOST_CHECK_EQUAL(v3[0].copies, 1);
1454 BOOST_CHECK_EQUAL(v3[1].copies, 0);
1455
1456 auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
1457 BOOST_CHECK_EQUAL(v4.size(), 3U);
1458 BOOST_CHECK(v4[0].origin == &t1);
1459 BOOST_CHECK(v4[1].origin == &t2);
1460 BOOST_CHECK(v4[2].origin == &t3); // NOLINT(*-use-after-move)
1461 BOOST_CHECK_EQUAL(v4[0].copies, 1);
1462 BOOST_CHECK_EQUAL(v4[1].copies, 1);
1463 BOOST_CHECK_EQUAL(v4[2].copies, 0);
1464
1465 auto v5 = Cat(v1, v4);
1466 BOOST_CHECK_EQUAL(v5.size(), 4U);
1467 BOOST_CHECK(v5[0].origin == &t1);
1468 BOOST_CHECK(v5[1].origin == &t1);
1469 BOOST_CHECK(v5[2].origin == &t2);
1470 BOOST_CHECK(v5[3].origin == &t3);
1471 BOOST_CHECK_EQUAL(v5[0].copies, 2);
1472 BOOST_CHECK_EQUAL(v5[1].copies, 2);
1473 BOOST_CHECK_EQUAL(v5[2].copies, 2);
1474 BOOST_CHECK_EQUAL(v5[3].copies, 1);
1475
1476 auto v6 = Cat(std::move(v1), v3);
1477 BOOST_CHECK_EQUAL(v6.size(), 3U);
1478 BOOST_CHECK(v6[0].origin == &t1);
1479 BOOST_CHECK(v6[1].origin == &t1);
1480 BOOST_CHECK(v6[2].origin == &t2);
1481 BOOST_CHECK_EQUAL(v6[0].copies, 1);
1482 BOOST_CHECK_EQUAL(v6[1].copies, 2);
1483 BOOST_CHECK_EQUAL(v6[2].copies, 1);
1484
1485 auto v7 = Cat(v2, std::move(v4));
1486 BOOST_CHECK_EQUAL(v7.size(), 4U);
1487 BOOST_CHECK(v7[0].origin == &t2);
1488 BOOST_CHECK(v7[1].origin == &t1);
1489 BOOST_CHECK(v7[2].origin == &t2);
1490 BOOST_CHECK(v7[3].origin == &t3);
1491 BOOST_CHECK_EQUAL(v7[0].copies, 1);
1492 BOOST_CHECK_EQUAL(v7[1].copies, 1);
1493 BOOST_CHECK_EQUAL(v7[2].copies, 1);
1494 BOOST_CHECK_EQUAL(v7[3].copies, 0);
1495
1496 auto v8 = Cat(std::move(v2), std::move(v3));
1497 BOOST_CHECK_EQUAL(v8.size(), 3U);
1498 BOOST_CHECK(v8[0].origin == &t2);
1499 BOOST_CHECK(v8[1].origin == &t1);
1500 BOOST_CHECK(v8[2].origin == &t2);
1501 BOOST_CHECK_EQUAL(v8[0].copies, 0);
1502 BOOST_CHECK_EQUAL(v8[1].copies, 1);
1503 BOOST_CHECK_EQUAL(v8[2].copies, 0);
1504}
1505
1507{
1508 const std::array<unsigned char, 32> privkey_bytes = {
1509 // just some random data
1510 // derived address from this private key: 15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs
1511 0xD9, 0x7F, 0x51, 0x08, 0xF1, 0x1C, 0xDA, 0x6E,
1512 0xEE, 0xBA, 0xAA, 0x42, 0x0F, 0xEF, 0x07, 0x26,
1513 0xB1, 0xF8, 0x98, 0x06, 0x0B, 0x98, 0x48, 0x9F,
1514 0xA3, 0x09, 0x84, 0x63, 0xC0, 0x03, 0x28, 0x66
1515 };
1516
1517 const std::string message = "Trust no one";
1518
1519 const std::string expected_signature =
1520 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=";
1521
1522 CKey privkey;
1523 std::string generated_signature;
1524
1525 BOOST_REQUIRE_MESSAGE(!privkey.IsValid(),
1526 "Confirm the private key is invalid");
1527
1528 BOOST_CHECK_MESSAGE(!MessageSign(privkey, message, generated_signature),
1529 "Sign with an invalid private key");
1530
1531 privkey.Set(privkey_bytes.begin(), privkey_bytes.end(), true);
1532
1533 BOOST_REQUIRE_MESSAGE(privkey.IsValid(),
1534 "Confirm the private key is valid");
1535
1536 BOOST_CHECK_MESSAGE(MessageSign(privkey, message, generated_signature),
1537 "Sign with a valid private key");
1538
1539 BOOST_CHECK_EQUAL(expected_signature, generated_signature);
1540}
1541
1543{
1546 "invalid address",
1547 "signature should be irrelevant",
1548 "message too"),
1550
1553 "3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
1554 "signature should be irrelevant",
1555 "message too"),
1557
1560 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
1561 "invalid signature, not in base64 encoding",
1562 "message should be irrelevant"),
1564
1567 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
1568 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1569 "message should be irrelevant"),
1571
1574 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
1575 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
1576 "I never signed this"),
1578
1581 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
1582 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
1583 "Trust no one"),
1585
1588 "11canuhp9X2NocwCq7xNrQYTmUgZAnLK3",
1589 "IIcaIENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzIAaHRtbCeDZINyavx14=",
1590 "Trust me"),
1592}
1593
1595{
1596 const std::string unsigned_tx = "...";
1597 const std::string prefixed_message =
1598 std::string(1, (char)MESSAGE_MAGIC.length()) +
1600 std::string(1, (char)unsigned_tx.length()) +
1601 unsigned_tx;
1602
1603 const uint256 signature_hash = Hash(unsigned_tx);
1604 const uint256 message_hash1 = Hash(prefixed_message);
1605 const uint256 message_hash2 = MessageHash(unsigned_tx);
1606
1607 BOOST_CHECK_EQUAL(message_hash1, message_hash2);
1608 BOOST_CHECK_NE(message_hash1, signature_hash);
1609}
1610
1612{
1613 BOOST_CHECK_EQUAL(RemovePrefix("./common/system.h", "./"), "common/system.h");
1614 BOOST_CHECK_EQUAL(RemovePrefixView("foo", "foo"), "");
1615 BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o");
1616 BOOST_CHECK_EQUAL(RemovePrefixView("foo", "f"), "oo");
1617 BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo");
1618 BOOST_CHECK_EQUAL(RemovePrefixView("fo", "foo"), "fo");
1619 BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f");
1620 BOOST_CHECK_EQUAL(RemovePrefixView("", "foo"), "");
1621 BOOST_CHECK_EQUAL(RemovePrefix("", ""), "");
1622}
1623
1624BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
1625{
1626 auto noop = ByteUnit::NOOP;
1627
1628 // no multiplier
1629 BOOST_CHECK_EQUAL(ParseByteUnits("1", noop).value(), 1);
1630 BOOST_CHECK_EQUAL(ParseByteUnits("0", noop).value(), 0);
1631
1632 BOOST_CHECK_EQUAL(ParseByteUnits("1k", noop).value(), 1000ULL);
1633 BOOST_CHECK_EQUAL(ParseByteUnits("1K", noop).value(), 1ULL << 10);
1634
1635 BOOST_CHECK_EQUAL(ParseByteUnits("2m", noop).value(), 2'000'000ULL);
1636 BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2ULL << 20);
1637
1638 BOOST_CHECK_EQUAL(ParseByteUnits("3g", noop).value(), 3'000'000'000ULL);
1639 BOOST_CHECK_EQUAL(ParseByteUnits("3G", noop).value(), 3ULL << 30);
1640
1641 BOOST_CHECK_EQUAL(ParseByteUnits("4t", noop).value(), 4'000'000'000'000ULL);
1642 BOOST_CHECK_EQUAL(ParseByteUnits("4T", noop).value(), 4ULL << 40);
1643
1644 // check default multiplier
1645 BOOST_CHECK_EQUAL(ParseByteUnits("5", ByteUnit::K).value(), 5ULL << 10);
1646
1647 // NaN
1648 BOOST_CHECK(!ParseByteUnits("", noop));
1649 BOOST_CHECK(!ParseByteUnits("foo", noop));
1650
1651 // whitespace
1652 BOOST_CHECK(!ParseByteUnits("123m ", noop));
1653 BOOST_CHECK(!ParseByteUnits(" 123m", noop));
1654
1655 // no +-
1656 BOOST_CHECK(!ParseByteUnits("-123m", noop));
1657 BOOST_CHECK(!ParseByteUnits("+123m", noop));
1658
1659 // zero padding
1660 BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20ULL << 20);
1661
1662 // fractions not allowed
1663 BOOST_CHECK(!ParseByteUnits("0.5T", noop));
1664
1665 // overflow
1666 BOOST_CHECK(!ParseByteUnits("18446744073709551615g", noop));
1667
1668 // invalid unit
1669 BOOST_CHECK(!ParseByteUnits("1x", noop));
1670}
1671
1672BOOST_AUTO_TEST_CASE(util_ReadBinaryFile)
1673{
1674 fs::path tmpfolder = m_args.GetDataDirBase();
1675 fs::path tmpfile = tmpfolder / "read_binary.dat";
1676 std::string expected_text;
1677 for (int i = 0; i < 30; i++) {
1678 expected_text += "0123456789";
1679 }
1680 {
1681 std::ofstream file{tmpfile.std_path()};
1682 file << expected_text;
1683 }
1684 {
1685 // read all contents in file
1686 auto [valid, text] = ReadBinaryFile(tmpfile);
1687 BOOST_CHECK(valid);
1688 BOOST_CHECK_EQUAL(text, expected_text);
1689 }
1690 {
1691 // read half contents in file
1692 auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2);
1693 BOOST_CHECK(valid);
1694 BOOST_CHECK_EQUAL(text, expected_text.substr(0, expected_text.size() / 2));
1695 }
1696 {
1697 // read from non-existent file
1698 fs::path invalid_file = tmpfolder / "invalid_binary.dat";
1699 auto [valid, text] = ReadBinaryFile(invalid_file);
1700 BOOST_CHECK(!valid);
1701 BOOST_CHECK(text.empty());
1702 }
1703}
1704
1705BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
1706{
1707 fs::path tmpfolder = m_args.GetDataDirBase();
1708 fs::path tmpfile = tmpfolder / "write_binary.dat";
1709 std::string expected_text = "bitcoin";
1710 auto valid = WriteBinaryFile(tmpfile, expected_text);
1711 std::string actual_text;
1712 std::ifstream file{tmpfile.std_path()};
1713 file >> actual_text;
1714 BOOST_CHECK(valid);
1715 BOOST_CHECK_EQUAL(actual_text, expected_text);
1716}
1717
1718BOOST_AUTO_TEST_CASE(clearshrink_test)
1719{
1720 {
1721 std::vector<uint8_t> v = {1, 2, 3};
1722 ClearShrink(v);
1723 BOOST_CHECK_EQUAL(v.size(), 0);
1724 BOOST_CHECK_EQUAL(v.capacity(), 0);
1725 }
1726
1727 {
1728 std::vector<bool> v = {false, true, false, false, true, true};
1729 ClearShrink(v);
1730 BOOST_CHECK_EQUAL(v.size(), 0);
1731 BOOST_CHECK_EQUAL(v.capacity(), 0);
1732 }
1733
1734 {
1735 std::deque<int> v = {1, 3, 3, 7};
1736 ClearShrink(v);
1737 BOOST_CHECK_EQUAL(v.size(), 0);
1738 // std::deque has no capacity() we can observe.
1739 }
1740}
1741
1742template <typename T>
1744{
1745 constexpr auto MAX{std::numeric_limits<T>::max()};
1746
1747 // Basic operations
1748 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 1), 0);
1749 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 127), 0);
1750 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, 1), 2);
1751 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(2, 2), 8);
1752 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MAX >> 1, 1), MAX - 1);
1753
1754 // Max left shift
1755 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1);
1756
1757 // Overflow cases
1758 BOOST_CHECK(!CheckedLeftShift<T>((MAX >> 1) + 1, 1));
1759 BOOST_CHECK(!CheckedLeftShift<T>(MAX, 1));
1760 BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits));
1761 BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits + 1));
1762
1763 if constexpr (std::is_signed_v<T>) {
1764 constexpr auto MIN{std::numeric_limits<T>::min()};
1765 // Negative input
1766 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(-1, 1), -2);
1767 BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 2), 1), MIN / 2);
1768 BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2);
1769 BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MIN >> 1, 1), MIN);
1770 // Overflow negative
1771 BOOST_CHECK(!CheckedLeftShift<T>((MIN >> 1) - 1, 1));
1772 BOOST_CHECK(!CheckedLeftShift<T>(MIN >> 1, 2));
1773 BOOST_CHECK(!CheckedLeftShift<T>(-1, 100));
1774 }
1775}
1776
1777template <typename T>
1779{
1780 constexpr auto MAX{std::numeric_limits<T>::max()};
1781
1782 // Basic operations
1783 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 1), 0);
1784 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 127), 0);
1785 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, 1), 2);
1786 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(2, 2), 8);
1787 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX >> 1, 1), MAX - 1);
1788
1789 // Max left shift
1790 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1);
1791
1792 // Saturation cases
1793 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MAX >> 1) + 1, 1), MAX);
1794 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX, 1), MAX);
1795 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits), MAX);
1796 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits + 1), MAX);
1797
1798 if constexpr (std::is_signed_v<T>) {
1799 constexpr auto MIN{std::numeric_limits<T>::min()};
1800 // Negative input
1801 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 1), -2);
1802 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 2), 1), MIN / 2);
1803 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2);
1804 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 1), MIN);
1805 // Saturation negative
1806 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) - 1, 1), MIN);
1807 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 2), MIN);
1808 BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 100), MIN);
1809 }
1810}
1811
1812BOOST_AUTO_TEST_CASE(checked_left_shift_test)
1813{
1814 TestCheckedLeftShift<uint8_t>();
1815 TestCheckedLeftShift<int8_t>();
1816 TestCheckedLeftShift<size_t>();
1817 TestCheckedLeftShift<uint64_t>();
1818 TestCheckedLeftShift<int64_t>();
1819}
1820
1821BOOST_AUTO_TEST_CASE(saturating_left_shift_test)
1822{
1823 TestSaturatingLeftShift<uint8_t>();
1824 TestSaturatingLeftShift<int8_t>();
1825 TestSaturatingLeftShift<size_t>();
1826 TestSaturatingLeftShift<uint64_t>();
1827 TestSaturatingLeftShift<int64_t>();
1828}
1829
1830BOOST_AUTO_TEST_CASE(mib_string_literal_test)
1831{
1832 BOOST_CHECK_EQUAL(0_MiB, 0);
1833 BOOST_CHECK_EQUAL(1_MiB, 1024 * 1024);
1834 const auto max_mib{std::numeric_limits<size_t>::max() >> 20};
1835 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"));
1836}
1837
1839{
1840 // Type combinations used by current CeilDiv callsites.
1841 BOOST_CHECK((std::is_same_v<decltype(CeilDiv(uint32_t{0}, 8u)), uint32_t>));
1842 BOOST_CHECK((std::is_same_v<decltype(CeilDiv(size_t{0}, 8u)), size_t>));
1843 BOOST_CHECK((std::is_same_v<decltype(CeilDiv(unsigned{0}, size_t{1})), size_t>));
1844
1845 // `common/bloom.cpp` and `cuckoocache.h` patterns.
1846 BOOST_CHECK_EQUAL(CeilDiv(uint32_t{3}, 2u), uint32_t{2});
1847 BOOST_CHECK_EQUAL(CeilDiv(uint32_t{65}, 64u), uint32_t{2});
1848 BOOST_CHECK_EQUAL(CeilDiv(uint32_t{9}, 8u), uint32_t{2});
1849
1850 // `key_io.cpp`, `rest.cpp`, `merkleblock.cpp`, `strencodings.cpp` patterns.
1851 BOOST_CHECK_EQUAL(CeilDiv(size_t{9}, 8u), size_t{2});
1852 BOOST_CHECK_EQUAL(CeilDiv(size_t{10}, 3u), size_t{4});
1853 BOOST_CHECK_EQUAL(CeilDiv(size_t{11}, 5u), size_t{3});
1854 BOOST_CHECK_EQUAL(CeilDiv(size_t{41} * 8, 5u), size_t{66});
1855
1856 // `flatfile.cpp` mixed unsigned/size_t pattern.
1857 BOOST_CHECK_EQUAL(CeilDiv(unsigned{10}, size_t{4}), size_t{3});
1858
1859 // `util/feefrac.h` fast-path rounding-up pattern.
1860 constexpr int64_t fee{12345};
1861 constexpr int32_t at_size{67};
1862 constexpr int32_t size{10};
1863 BOOST_CHECK_EQUAL(CeilDiv(uint64_t(fee) * at_size, uint32_t(size)),
1864 (uint64_t(fee) * at_size + uint32_t(size) - 1) / uint32_t(size));
1865
1866 // `bitset.h` template parameter pattern.
1867 constexpr unsigned bits{129};
1868 constexpr size_t digits{std::numeric_limits<size_t>::digits};
1869 BOOST_CHECK_EQUAL(CeilDiv(bits, digits), (bits + digits - 1) / digits);
1870
1871 // `serialize.h` varint scratch-buffer pattern.
1872 BOOST_CHECK_EQUAL(CeilDiv(sizeof(uint64_t) * 8, 7u), (sizeof(uint64_t) * 8 + 6) / 7);
1873}
1874
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: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:19
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
Definition: time.h:40
256-bit opaque blob.
Definition: uint256.h:196
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:82
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:393
std::vector< std::string > SplitString(std::string_view str, char sep)
Definition: string.h:150
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:160
LockResult
Definition: fs_helpers.h:58
std::string_view RemovePrefixView(std::string_view str, std::string_view prefix)
Definition: string.h:183
std::string TrimString(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
Definition: string.h:170
std::string RemovePrefix(std::string_view str, std::string_view prefix)
Definition: string.h:191
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition: string.h:206
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:117
LockResult LockDirectory(const fs::path &directory, const fs::path &lockfile_name, bool probe_only)
Definition: fs_helpers.cpp:48
#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:28
constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
Integer ceiling division (for unsigned values).
Definition: overflow.h:71
T SaturatingAdd(const T i, const T j) noexcept
Definition: overflow.h:45
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:61
static time_point now() noexcept
Return current system time or mocked time, if set.
Definition: time.cpp:36
#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:87
std::string FormatISO8601Date(int64_t nTime)
Definition: time.cpp:98
std::optional< int64_t > ParseISO8601DateTime(std::string_view str)
Definition: time.cpp:106
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:130
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: time.cpp:89
constexpr int64_t TicksSeconds(Duration d)
Definition: time.h:87
int64_t atoi64_legacy(const std::string &str)
Definition: util_tests.cpp:767
#define E
Definition: util_tests.cpp:563
constexpr uint8_t HEX_PARSE_OUTPUT[]
Definition: util_tests.cpp:146
constexpr char HEX_PARSE_INPUT[]
Definition: util_tests.cpp:145
static void TestOtherProcess(fs::path dirname, fs::path lockname, int fd)
#define B
Definition: util_tests.cpp:562
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:97
static void RunToIntegralTests()
Definition: util_tests.cpp:677
static const std::string STRING_WITH_EMBEDDED_NULL_CHAR
Definition: util_tests.cpp:63
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