Bitcoin Core  28.1.0
P2P Digital Currency
streams_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2022 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 <streams.h>
6 #include <test/util/random.h>
8 #include <util/fs.h>
9 #include <util/strencodings.h>
10 
11 #include <boost/test/unit_test.hpp>
12 
13 using namespace std::string_literals;
14 
15 BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup)
16 
18 {
19  fs::path xor_path{m_args.GetDataDirBase() / "test_xor.bin"};
20  auto raw_file{[&](const auto& mode) { return fsbridge::fopen(xor_path, mode); }};
21  const std::vector<uint8_t> test1{1, 2, 3};
22  const std::vector<uint8_t> test2{4, 5};
23  const std::vector<std::byte> xor_pat{std::byte{0xff}, std::byte{0x00}};
24  {
25  // Check errors for missing file
26  AutoFile xor_file{raw_file("rb"), xor_pat};
27  BOOST_CHECK_EXCEPTION(xor_file << std::byte{}, std::ios_base::failure, HasReason{"AutoFile::write: file handle is nullpt"});
28  BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: file handle is nullpt"});
29  BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: file handle is nullpt"});
30  }
31  {
32 #ifdef __MINGW64__
33  // Temporary workaround for https://github.com/bitcoin/bitcoin/issues/30210
34  const char* mode = "wb";
35 #else
36  const char* mode = "wbx";
37 #endif
38  AutoFile xor_file{raw_file(mode), xor_pat};
39  xor_file << test1 << test2;
40  }
41  {
42  // Read raw from disk
43  AutoFile non_xor_file{raw_file("rb")};
44  std::vector<std::byte> raw(7);
45  non_xor_file >> Span{raw};
46  BOOST_CHECK_EQUAL(HexStr(raw), "fc01fd03fd04fa");
47  // Check that no padding exists
48  BOOST_CHECK_EXCEPTION(non_xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
49  }
50  {
51  AutoFile xor_file{raw_file("rb"), xor_pat};
52  std::vector<std::byte> read1, read2;
53  xor_file >> read1 >> read2;
55  BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
56  // Check that eof was reached
57  BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
58  }
59  {
60  AutoFile xor_file{raw_file("rb"), xor_pat};
61  std::vector<std::byte> read2;
62  // Check that ignore works
63  xor_file.ignore(4);
64  xor_file >> read2;
65  BOOST_CHECK_EQUAL(HexStr(read2), HexStr(test2));
66  // Check that ignore and read fail now
67  BOOST_CHECK_EXCEPTION(xor_file.ignore(1), std::ios_base::failure, HasReason{"AutoFile::ignore: end of file"});
68  BOOST_CHECK_EXCEPTION(xor_file >> std::byte{}, std::ios_base::failure, HasReason{"AutoFile::read: end of file"});
69  }
70 }
71 
72 BOOST_AUTO_TEST_CASE(streams_vector_writer)
73 {
74  unsigned char a(1);
75  unsigned char b(2);
76  unsigned char bytes[] = { 3, 4, 5, 6 };
77  std::vector<unsigned char> vch;
78 
79  // Each test runs twice. Serializing a second time at the same starting
80  // point should yield the same results, even if the first test grew the
81  // vector.
82 
83  VectorWriter{vch, 0, a, b};
84  BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
85  VectorWriter{vch, 0, a, b};
86  BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
87  vch.clear();
88 
89  VectorWriter{vch, 2, a, b};
90  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
91  VectorWriter{vch, 2, a, b};
92  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
93  vch.clear();
94 
95  vch.resize(5, 0);
96  VectorWriter{vch, 2, a, b};
97  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
98  VectorWriter{vch, 2, a, b};
99  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
100  vch.clear();
101 
102  vch.resize(4, 0);
103  VectorWriter{vch, 3, a, b};
104  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
105  VectorWriter{vch, 3, a, b};
106  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
107  vch.clear();
108 
109  vch.resize(4, 0);
110  VectorWriter{vch, 4, a, b};
111  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
112  VectorWriter{vch, 4, a, b};
113  BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
114  vch.clear();
115 
116  VectorWriter{vch, 0, bytes};
117  BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
118  VectorWriter{vch, 0, bytes};
119  BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
120  vch.clear();
121 
122  vch.resize(4, 8);
123  VectorWriter{vch, 2, a, bytes, b};
124  BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
125  VectorWriter{vch, 2, a, bytes, b};
126  BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
127  vch.clear();
128 }
129 
130 BOOST_AUTO_TEST_CASE(streams_vector_reader)
131 {
132  std::vector<unsigned char> vch = {1, 255, 3, 4, 5, 6};
133 
134  SpanReader reader{vch};
135  BOOST_CHECK_EQUAL(reader.size(), 6U);
136  BOOST_CHECK(!reader.empty());
137 
138  // Read a single byte as an unsigned char.
139  unsigned char a;
140  reader >> a;
141  BOOST_CHECK_EQUAL(a, 1);
142  BOOST_CHECK_EQUAL(reader.size(), 5U);
143  BOOST_CHECK(!reader.empty());
144 
145  // Read a single byte as a int8_t.
146  int8_t b;
147  reader >> b;
148  BOOST_CHECK_EQUAL(b, -1);
149  BOOST_CHECK_EQUAL(reader.size(), 4U);
150  BOOST_CHECK(!reader.empty());
151 
152  // Read a 4 bytes as an unsigned int.
153  unsigned int c;
154  reader >> c;
155  BOOST_CHECK_EQUAL(c, 100992003U); // 3,4,5,6 in little-endian base-256
156  BOOST_CHECK_EQUAL(reader.size(), 0U);
157  BOOST_CHECK(reader.empty());
158 
159  // Reading after end of byte vector throws an error.
160  signed int d;
161  BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
162 
163  // Read a 4 bytes as a signed int from the beginning of the buffer.
164  SpanReader new_reader{vch};
165  new_reader >> d;
166  BOOST_CHECK_EQUAL(d, 67370753); // 1,255,3,4 in little-endian base-256
167  BOOST_CHECK_EQUAL(new_reader.size(), 2U);
168  BOOST_CHECK(!new_reader.empty());
169 
170  // Reading after end of byte vector throws an error even if the reader is
171  // not totally empty.
172  BOOST_CHECK_THROW(new_reader >> d, std::ios_base::failure);
173 }
174 
175 BOOST_AUTO_TEST_CASE(streams_vector_reader_rvalue)
176 {
177  std::vector<uint8_t> data{0x82, 0xa7, 0x31};
178  SpanReader reader{data};
179  uint32_t varint = 0;
180  // Deserialize into r-value
181  reader >> VARINT(varint);
182  BOOST_CHECK_EQUAL(varint, 54321U);
183  BOOST_CHECK(reader.empty());
184 }
185 
186 BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
187 {
188  DataStream data{};
189 
190  BitStreamWriter bit_writer{data};
191  bit_writer.Write(0, 1);
192  bit_writer.Write(2, 2);
193  bit_writer.Write(6, 3);
194  bit_writer.Write(11, 4);
195  bit_writer.Write(1, 5);
196  bit_writer.Write(32, 6);
197  bit_writer.Write(7, 7);
198  bit_writer.Write(30497, 16);
199  bit_writer.Flush();
200 
201  DataStream data_copy{data};
202  uint32_t serialized_int1;
203  data >> serialized_int1;
204  BOOST_CHECK_EQUAL(serialized_int1, uint32_t{0x7700C35A}); // NOTE: Serialized as LE
205  uint16_t serialized_int2;
206  data >> serialized_int2;
207  BOOST_CHECK_EQUAL(serialized_int2, uint16_t{0x1072}); // NOTE: Serialized as LE
208 
209  BitStreamReader bit_reader{data_copy};
210  BOOST_CHECK_EQUAL(bit_reader.Read(1), 0U);
211  BOOST_CHECK_EQUAL(bit_reader.Read(2), 2U);
212  BOOST_CHECK_EQUAL(bit_reader.Read(3), 6U);
213  BOOST_CHECK_EQUAL(bit_reader.Read(4), 11U);
214  BOOST_CHECK_EQUAL(bit_reader.Read(5), 1U);
215  BOOST_CHECK_EQUAL(bit_reader.Read(6), 32U);
216  BOOST_CHECK_EQUAL(bit_reader.Read(7), 7U);
217  BOOST_CHECK_EQUAL(bit_reader.Read(16), 30497U);
218  BOOST_CHECK_THROW(bit_reader.Read(8), std::ios_base::failure);
219 }
220 
221 BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
222 {
223  std::vector<std::byte> in;
224 
225  // Degenerate case
226  {
227  DataStream ds{in};
228  ds.Xor({0x00, 0x00});
229  BOOST_CHECK_EQUAL(""s, ds.str());
230  }
231 
232  in.push_back(std::byte{0x0f});
233  in.push_back(std::byte{0xf0});
234 
235  // Single character key
236  {
237  DataStream ds{in};
238  ds.Xor({0xff});
239  BOOST_CHECK_EQUAL("\xf0\x0f"s, ds.str());
240  }
241 
242  // Multi character key
243 
244  in.clear();
245  in.push_back(std::byte{0xf0});
246  in.push_back(std::byte{0x0f});
247 
248  {
249  DataStream ds{in};
250  ds.Xor({0xff, 0x0f});
251  BOOST_CHECK_EQUAL("\x0f\x00"s, ds.str());
252  }
253 }
254 
255 BOOST_AUTO_TEST_CASE(streams_buffered_file)
256 {
257  fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
258  AutoFile file{fsbridge::fopen(streams_test_filename, "w+b")};
259 
260  // The value at each offset is the offset.
261  for (uint8_t j = 0; j < 40; ++j) {
262  file << j;
263  }
264  file.seek(0, SEEK_SET);
265 
266  // The buffer size (second arg) must be greater than the rewind
267  // amount (third arg).
268  try {
269  BufferedFile bfbad{file, 25, 25};
270  BOOST_CHECK(false);
271  } catch (const std::exception& e) {
272  BOOST_CHECK(strstr(e.what(),
273  "Rewind limit must be less than buffer size") != nullptr);
274  }
275 
276  // The buffer is 25 bytes, allow rewinding 10 bytes.
277  BufferedFile bf{file, 25, 10};
278  BOOST_CHECK(!bf.eof());
279 
280  uint8_t i;
281  bf >> i;
282  BOOST_CHECK_EQUAL(i, 0);
283  bf >> i;
284  BOOST_CHECK_EQUAL(i, 1);
285 
286  // After reading bytes 0 and 1, we're positioned at 2.
287  BOOST_CHECK_EQUAL(bf.GetPos(), 2U);
288 
289  // Rewind to offset 0, ok (within the 10 byte window).
290  BOOST_CHECK(bf.SetPos(0));
291  bf >> i;
292  BOOST_CHECK_EQUAL(i, 0);
293 
294  // We can go forward to where we've been, but beyond may fail.
295  BOOST_CHECK(bf.SetPos(2));
296  bf >> i;
297  BOOST_CHECK_EQUAL(i, 2);
298 
299  // If you know the maximum number of bytes that should be
300  // read to deserialize the variable, you can limit the read
301  // extent. The current file offset is 3, so the following
302  // SetLimit() allows zero bytes to be read.
303  BOOST_CHECK(bf.SetLimit(3));
304  try {
305  bf >> i;
306  BOOST_CHECK(false);
307  } catch (const std::exception& e) {
308  BOOST_CHECK(strstr(e.what(),
309  "Attempt to position past buffer limit") != nullptr);
310  }
311  // The default argument removes the limit completely.
312  BOOST_CHECK(bf.SetLimit());
313  // The read position should still be at 3 (no change).
314  BOOST_CHECK_EQUAL(bf.GetPos(), 3U);
315 
316  // Read from current offset, 3, forward until position 10.
317  for (uint8_t j = 3; j < 10; ++j) {
318  bf >> i;
319  BOOST_CHECK_EQUAL(i, j);
320  }
321  BOOST_CHECK_EQUAL(bf.GetPos(), 10U);
322 
323  // We're guaranteed (just barely) to be able to rewind to zero.
324  BOOST_CHECK(bf.SetPos(0));
325  BOOST_CHECK_EQUAL(bf.GetPos(), 0U);
326  bf >> i;
327  BOOST_CHECK_EQUAL(i, 0);
328 
329  // We can set the position forward again up to the farthest
330  // into the stream we've been, but no farther. (Attempting
331  // to go farther may succeed, but it's not guaranteed.)
332  BOOST_CHECK(bf.SetPos(10));
333  bf >> i;
334  BOOST_CHECK_EQUAL(i, 10);
335  BOOST_CHECK_EQUAL(bf.GetPos(), 11U);
336 
337  // Now it's only guaranteed that we can rewind to offset 1
338  // (current read position, 11, minus rewind amount, 10).
339  BOOST_CHECK(bf.SetPos(1));
340  BOOST_CHECK_EQUAL(bf.GetPos(), 1U);
341  bf >> i;
342  BOOST_CHECK_EQUAL(i, 1);
343 
344  // We can stream into large variables, even larger than
345  // the buffer size.
346  BOOST_CHECK(bf.SetPos(11));
347  {
348  uint8_t a[40 - 11];
349  bf >> a;
350  for (uint8_t j = 0; j < sizeof(a); ++j) {
351  BOOST_CHECK_EQUAL(a[j], 11 + j);
352  }
353  }
354  BOOST_CHECK_EQUAL(bf.GetPos(), 40U);
355 
356  // We've read the entire file, the next read should throw.
357  try {
358  bf >> i;
359  BOOST_CHECK(false);
360  } catch (const std::exception& e) {
361  BOOST_CHECK(strstr(e.what(),
362  "BufferedFile::Fill: end of file") != nullptr);
363  }
364  // Attempting to read beyond the end sets the EOF indicator.
365  BOOST_CHECK(bf.eof());
366 
367  // Still at offset 40, we can go back 10, to 30.
368  BOOST_CHECK_EQUAL(bf.GetPos(), 40U);
369  BOOST_CHECK(bf.SetPos(30));
370  bf >> i;
371  BOOST_CHECK_EQUAL(i, 30);
372  BOOST_CHECK_EQUAL(bf.GetPos(), 31U);
373 
374  // We're too far to rewind to position zero.
375  BOOST_CHECK(!bf.SetPos(0));
376  // But we should now be positioned at least as far back as allowed
377  // by the rewind window (relative to our farthest read position, 40).
378  BOOST_CHECK(bf.GetPos() <= 30U);
379 
380  // We can explicitly close the file, or the destructor will do it.
381  file.fclose();
382 
383  fs::remove(streams_test_filename);
384 }
385 
386 BOOST_AUTO_TEST_CASE(streams_buffered_file_skip)
387 {
388  fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
389  AutoFile file{fsbridge::fopen(streams_test_filename, "w+b")};
390  // The value at each offset is the byte offset (e.g. byte 1 in the file has the value 0x01).
391  for (uint8_t j = 0; j < 40; ++j) {
392  file << j;
393  }
394  file.seek(0, SEEK_SET);
395 
396  // The buffer is 25 bytes, allow rewinding 10 bytes.
397  BufferedFile bf{file, 25, 10};
398 
399  uint8_t i;
400  // This is like bf >> (7-byte-variable), in that it will cause data
401  // to be read from the file into memory, but it's not copied to us.
402  bf.SkipTo(7);
403  BOOST_CHECK_EQUAL(bf.GetPos(), 7U);
404  bf >> i;
405  BOOST_CHECK_EQUAL(i, 7);
406 
407  // The bytes in the buffer up to offset 7 are valid and can be read.
408  BOOST_CHECK(bf.SetPos(0));
409  bf >> i;
410  BOOST_CHECK_EQUAL(i, 0);
411  bf >> i;
412  BOOST_CHECK_EQUAL(i, 1);
413 
414  bf.SkipTo(11);
415  bf >> i;
416  BOOST_CHECK_EQUAL(i, 11);
417 
418  // SkipTo() honors the transfer limit; we can't position beyond the limit.
419  bf.SetLimit(13);
420  try {
421  bf.SkipTo(14);
422  BOOST_CHECK(false);
423  } catch (const std::exception& e) {
424  BOOST_CHECK(strstr(e.what(), "Attempt to position past buffer limit") != nullptr);
425  }
426 
427  // We can position exactly to the transfer limit.
428  bf.SkipTo(13);
429  BOOST_CHECK_EQUAL(bf.GetPos(), 13U);
430 
431  file.fclose();
432  fs::remove(streams_test_filename);
433 }
434 
435 BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
436 {
437  // Make this test deterministic.
439 
440  fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
441  for (int rep = 0; rep < 50; ++rep) {
442  AutoFile file{fsbridge::fopen(streams_test_filename, "w+b")};
443  size_t fileSize = InsecureRandRange(256);
444  for (uint8_t i = 0; i < fileSize; ++i) {
445  file << i;
446  }
447  file.seek(0, SEEK_SET);
448 
449  size_t bufSize = InsecureRandRange(300) + 1;
450  size_t rewindSize = InsecureRandRange(bufSize);
451  BufferedFile bf{file, bufSize, rewindSize};
452  size_t currentPos = 0;
453  size_t maxPos = 0;
454  for (int step = 0; step < 100; ++step) {
455  if (currentPos >= fileSize)
456  break;
457 
458  // We haven't read to the end of the file yet.
459  BOOST_CHECK(!bf.eof());
460  BOOST_CHECK_EQUAL(bf.GetPos(), currentPos);
461 
462  // Pretend the file consists of a series of objects of varying
463  // sizes; the boundaries of the objects can interact arbitrarily
464  // with the CBufferFile's internal buffer. These first three
465  // cases simulate objects of various sizes (1, 2, 5 bytes).
466  switch (InsecureRandRange(6)) {
467  case 0: {
468  uint8_t a[1];
469  if (currentPos + 1 > fileSize)
470  continue;
471  bf.SetLimit(currentPos + 1);
472  bf >> a;
473  for (uint8_t i = 0; i < 1; ++i) {
474  BOOST_CHECK_EQUAL(a[i], currentPos);
475  currentPos++;
476  }
477  break;
478  }
479  case 1: {
480  uint8_t a[2];
481  if (currentPos + 2 > fileSize)
482  continue;
483  bf.SetLimit(currentPos + 2);
484  bf >> a;
485  for (uint8_t i = 0; i < 2; ++i) {
486  BOOST_CHECK_EQUAL(a[i], currentPos);
487  currentPos++;
488  }
489  break;
490  }
491  case 2: {
492  uint8_t a[5];
493  if (currentPos + 5 > fileSize)
494  continue;
495  bf.SetLimit(currentPos + 5);
496  bf >> a;
497  for (uint8_t i = 0; i < 5; ++i) {
498  BOOST_CHECK_EQUAL(a[i], currentPos);
499  currentPos++;
500  }
501  break;
502  }
503  case 3: {
504  // SkipTo is similar to the "read" cases above, except
505  // we don't receive the data.
506  size_t skip_length{static_cast<size_t>(InsecureRandRange(5))};
507  if (currentPos + skip_length > fileSize) continue;
508  bf.SetLimit(currentPos + skip_length);
509  bf.SkipTo(currentPos + skip_length);
510  currentPos += skip_length;
511  break;
512  }
513  case 4: {
514  // Find a byte value (that is at or ahead of the current position).
515  size_t find = currentPos + InsecureRandRange(8);
516  if (find >= fileSize)
517  find = fileSize - 1;
518  bf.FindByte(std::byte(find));
519  // The value at each offset is the offset.
520  BOOST_CHECK_EQUAL(bf.GetPos(), find);
521  currentPos = find;
522 
523  bf.SetLimit(currentPos + 1);
524  uint8_t i;
525  bf >> i;
526  BOOST_CHECK_EQUAL(i, currentPos);
527  currentPos++;
528  break;
529  }
530  case 5: {
531  size_t requestPos = InsecureRandRange(maxPos + 4);
532  bool okay = bf.SetPos(requestPos);
533  // The new position may differ from the requested position
534  // because we may not be able to rewind beyond the rewind
535  // window, and we may not be able to move forward beyond the
536  // farthest position we've reached so far.
537  currentPos = bf.GetPos();
538  BOOST_CHECK_EQUAL(okay, currentPos == requestPos);
539  // Check that we can position within the rewind window.
540  if (requestPos <= maxPos &&
541  maxPos > rewindSize &&
542  requestPos >= maxPos - rewindSize) {
543  // We requested a position within the rewind window.
544  BOOST_CHECK(okay);
545  }
546  break;
547  }
548  }
549  if (maxPos < currentPos)
550  maxPos = currentPos;
551  }
552  }
553  fs::remove(streams_test_filename);
554 }
555 
556 BOOST_AUTO_TEST_CASE(streams_hashed)
557 {
558  DataStream stream{};
559  HashedSourceWriter hash_writer{stream};
560  const std::string data{"bitcoin"};
561  hash_writer << data;
562 
563  HashVerifier hash_verifier{stream};
564  std::string result;
565  hash_verifier >> result;
566  BOOST_CHECK_EQUAL(data, result);
567  BOOST_CHECK_EQUAL(hash_writer.GetHash(), hash_verifier.GetHash());
568 }
569 
#define VARINT(obj)
Definition: serialize.h:498
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:19
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:26
const std::string test1
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Definition: streams.h:542
Wrapper around an AutoFile& that implements a ring buffer to deserialize from.
Definition: streams.h:468
void Write(uint64_t data, int nbits)
Write the nbits least significant bits of a 64-bit int to the output stream.
Definition: streams.h:351
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:388
Basic testing setup.
Definition: setup_common.h:64
Minimal stream for reading from an existing byte array by Span.
Definition: streams.h:100
static uint64_t InsecureRandRange(uint64_t range)
Definition: random.h:45
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:146
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
Definition: setup_common.h:254
void SeedRandomForTest(SeedRand seedtype)
Seed the RNG for testing.
Definition: random.cpp:18
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
Definition: streams.h:276
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:29
Writes data to an underlying source stream, while hashing the written data.
Definition: hash.h:184
Reads data from an underlying stream, while hashing the read data.
Definition: hash.h:150
A Span is an object that can refer to a contiguous sequence of objects.
Definition: solver.h:20
BOOST_AUTO_TEST_CASE(xor_file)
Seed with a compile time constant of zeros.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:32
void ignore(size_t nSize)
Definition: streams.cpp:66
#define BOOST_CHECK(expr)
Definition: object.cpp:17