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