diff options
author | Larry Ruane <larryruane@gmail.com> | 2022-10-24 12:10:45 -0600 |
---|---|---|
committer | Larry Ruane <larryruane@gmail.com> | 2022-10-24 13:02:35 -0600 |
commit | 48a68908ba3d5e077cda7bd1e908b923fbead824 (patch) | |
tree | 708577a9f3cf3a1567318ade7f58ef48f33b36ef /src/bench | |
parent | fabc0310480b49e159a15d494525c5aa15072cba (diff) |
Add LoadExternalBlockFile() benchmark
Diffstat (limited to 'src/bench')
-rw-r--r-- | src/bench/load_external.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/bench/load_external.cpp b/src/bench/load_external.cpp new file mode 100644 index 0000000000..be01b2a483 --- /dev/null +++ b/src/bench/load_external.cpp @@ -0,0 +1,63 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php. + +#include <bench/bench.h> +#include <bench/data.h> +#include <chainparams.h> +#include <test/util/setup_common.h> +#include <validation.h> + +/** + * The LoadExternalBlockFile() function is used during -reindex and -loadblock. + * + * Create a test file that's similar to a datadir/blocks/blk?????.dat file, + * It contains around 134 copies of the same block (typical size of real block files). + * For each block in the file, LoadExternalBlockFile() won't find its parent, + * and so will skip the block. (In the real system, it will re-read the block + * from disk later when it encounters its parent.) + * + * This benchmark measures the performance of deserializing the block (or just + * its header, beginning with PR 16981). + */ +static void LoadExternalBlockFile(benchmark::Bench& bench) +{ + const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN)}; + + // Create a single block as in the blocks files (magic bytes, block size, + // block data) as a stream object. + const fs::path blkfile{testing_setup.get()->m_path_root / "blk.dat"}; + CDataStream ss(SER_DISK, 0); + auto params{testing_setup->m_node.chainman->GetParams()}; + ss << params.MessageStart(); + ss << static_cast<uint32_t>(benchmark::data::block413567.size()); + // We can't use the streaming serialization (ss << benchmark::data::block413567) + // because that first writes a compact size. + ss.write(MakeByteSpan(benchmark::data::block413567)); + + // Create the test file. + { + // "wb+" is "binary, O_RDWR | O_CREAT | O_TRUNC". + FILE* file{fsbridge::fopen(blkfile, "wb+")}; + // Make the test block file about 128 MB in length. + for (size_t i = 0; i < node::MAX_BLOCKFILE_SIZE / ss.size(); ++i) { + if (fwrite(ss.data(), 1, ss.size(), file) != ss.size()) { + throw std::runtime_error("write to test file failed\n"); + } + } + fclose(file); + } + + Chainstate& chainstate{testing_setup->m_node.chainman->ActiveChainstate()}; + std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent; + FlatFilePos pos; + bench.run([&] { + // "rb" is "binary, O_RDONLY", positioned to the start of the file. + // The file will be closed by LoadExternalBlockFile(). + FILE* file{fsbridge::fopen(blkfile, "rb")}; + chainstate.LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent); + }); + fs::remove(blkfile); +} + +BENCHMARK(LoadExternalBlockFile, benchmark::PriorityLevel::HIGH); |