Skip to content

Commit 48a6890

Browse files
committed
Add LoadExternalBlockFile() benchmark
1 parent fabc031 commit 48a6890

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ bench_bench_bitcoin_SOURCES = \
3232
bench/examples.cpp \
3333
bench/gcs_filter.cpp \
3434
bench/hashpadding.cpp \
35+
bench/load_external.cpp \
3536
bench/lockedpool.cpp \
3637
bench/logging.cpp \
3738
bench/mempool_eviction.cpp \

src/bench/load_external.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or https://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <bench/bench.h>
6+
#include <bench/data.h>
7+
#include <chainparams.h>
8+
#include <test/util/setup_common.h>
9+
#include <validation.h>
10+
11+
/**
12+
* The LoadExternalBlockFile() function is used during -reindex and -loadblock.
13+
*
14+
* Create a test file that's similar to a datadir/blocks/blk?????.dat file,
15+
* It contains around 134 copies of the same block (typical size of real block files).
16+
* For each block in the file, LoadExternalBlockFile() won't find its parent,
17+
* and so will skip the block. (In the real system, it will re-read the block
18+
* from disk later when it encounters its parent.)
19+
*
20+
* This benchmark measures the performance of deserializing the block (or just
21+
* its header, beginning with PR 16981).
22+
*/
23+
static void LoadExternalBlockFile(benchmark::Bench& bench)
24+
{
25+
const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN)};
26+
27+
// Create a single block as in the blocks files (magic bytes, block size,
28+
// block data) as a stream object.
29+
const fs::path blkfile{testing_setup.get()->m_path_root / "blk.dat"};
30+
CDataStream ss(SER_DISK, 0);
31+
auto params{testing_setup->m_node.chainman->GetParams()};
32+
ss << params.MessageStart();
33+
ss << static_cast<uint32_t>(benchmark::data::block413567.size());
34+
// We can't use the streaming serialization (ss << benchmark::data::block413567)
35+
// because that first writes a compact size.
36+
ss.write(MakeByteSpan(benchmark::data::block413567));
37+
38+
// Create the test file.
39+
{
40+
// "wb+" is "binary, O_RDWR | O_CREAT | O_TRUNC".
41+
FILE* file{fsbridge::fopen(blkfile, "wb+")};
42+
// Make the test block file about 128 MB in length.
43+
for (size_t i = 0; i < node::MAX_BLOCKFILE_SIZE / ss.size(); ++i) {
44+
if (fwrite(ss.data(), 1, ss.size(), file) != ss.size()) {
45+
throw std::runtime_error("write to test file failed\n");
46+
}
47+
}
48+
fclose(file);
49+
}
50+
51+
Chainstate& chainstate{testing_setup->m_node.chainman->ActiveChainstate()};
52+
std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
53+
FlatFilePos pos;
54+
bench.run([&] {
55+
// "rb" is "binary, O_RDONLY", positioned to the start of the file.
56+
// The file will be closed by LoadExternalBlockFile().
57+
FILE* file{fsbridge::fopen(blkfile, "rb")};
58+
chainstate.LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent);
59+
});
60+
fs::remove(blkfile);
61+
}
62+
63+
BENCHMARK(LoadExternalBlockFile, benchmark::PriorityLevel::HIGH);

0 commit comments

Comments
 (0)