Skip to content

Commit 5d6f6fd

Browse files
committed
Merge bitcoin/bitcoin#31490: refactor: inline UndoWriteToDisk and WriteBlockToDisk to reduce serialization calls
223081e scripted-diff: rename block and undo functions for consistency (Lőrinc) baaa3b2 refactor,blocks: remove costly asserts and modernize affected logs (Lőrinc) fa39f27 refactor,blocks: deduplicate block's serialized size calculations (Lőrinc) dfb2f9d refactor,blocks: inline `WriteBlockToDisk` (Lőrinc) 42bc491 refactor,blocks: inline `UndoWriteToDisk` (Lőrinc) 86b85bb bench: add SaveBlockBench (Lőrinc) 34f9a01 refactor,bench: rename bench/readblock.cpp to bench/readwriteblock.cpp (Lőrinc) Pull request description: `UndoWriteToDisk` and `WriteBlockToDisk` were delegating a subset of their functionality to single-use methods that didn't optimally capture a meaningful chunk of the algorithm, resulting in calculating things twice (serialized size, header size). This change inlines the awkward methods (asserting that all previous behavior was retained), and in separate commits makes the usages less confusing. Besides making the methods slightly more intuitive, the refactorings reduce duplicate calculations as well. The speed difference is insignificant for now (~0.5% for the new `SaveBlockToDiskBench`), but are a cleanup for follow-ups such as bitcoin/bitcoin#31539 ACKs for top commit: ryanofsky: Code review ACK 223081e. Since last review, "Save" was renamed to "Write", uint32_t references were dropped, some log statements and comments were improved as suggested, and a lot of tweaks made to commits and commit messages which should make this easier to review. hodlinator: ACK 223081e TheCharlatan: ACK 223081e andrewtoth: ACK 223081e Tree-SHA512: 951bc8ad3504c510988afd95c561e3e259c6212bd14f6536fe56e8eb5bf5c35c32a368bbdb1d5aea1acc473d7e5bd9cdcde02008a148b05af1f955e413062d5c
2 parents 7b4d072 + 223081e commit 5d6f6fd

20 files changed

+179
-204
lines changed

src/bench/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ add_executable(bench_bitcoin
4444
pool.cpp
4545
prevector.cpp
4646
random.cpp
47-
readblock.cpp
47+
readwriteblock.cpp
4848
rollingbloom.cpp
4949
rpc_blockchain.cpp
5050
rpc_mempool.cpp

src/bench/readblock.cpp

Lines changed: 0 additions & 60 deletions
This file was deleted.

src/bench/readwriteblock.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2023 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 <bench/bench.h>
6+
#include <bench/data/block413567.raw.h>
7+
#include <flatfile.h>
8+
#include <node/blockstorage.h>
9+
#include <primitives/block.h>
10+
#include <primitives/transaction.h>
11+
#include <serialize.h>
12+
#include <span.h>
13+
#include <streams.h>
14+
#include <test/util/setup_common.h>
15+
#include <validation.h>
16+
17+
#include <cassert>
18+
#include <cstdint>
19+
#include <memory>
20+
#include <vector>
21+
22+
static CBlock CreateTestBlock()
23+
{
24+
DataStream stream{benchmark::data::block413567};
25+
CBlock block;
26+
stream >> TX_WITH_WITNESS(block);
27+
return block;
28+
}
29+
30+
static void SaveBlockBench(benchmark::Bench& bench)
31+
{
32+
const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN)};
33+
auto& blockman{testing_setup->m_node.chainman->m_blockman};
34+
const CBlock block{CreateTestBlock()};
35+
bench.run([&] {
36+
const auto pos{blockman.WriteBlock(block, 413'567)};
37+
assert(!pos.IsNull());
38+
});
39+
}
40+
41+
static void ReadBlockBench(benchmark::Bench& bench)
42+
{
43+
const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN)};
44+
auto& blockman{testing_setup->m_node.chainman->m_blockman};
45+
const auto pos{blockman.WriteBlock(CreateTestBlock(), 413'567)};
46+
CBlock block;
47+
bench.run([&] {
48+
const auto success{blockman.ReadBlock(block, pos)};
49+
assert(success);
50+
});
51+
}
52+
53+
static void ReadRawBlockBench(benchmark::Bench& bench)
54+
{
55+
const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN)};
56+
auto& blockman{testing_setup->m_node.chainman->m_blockman};
57+
const auto pos{blockman.WriteBlock(CreateTestBlock(), 413'567)};
58+
std::vector<uint8_t> block_data;
59+
blockman.ReadRawBlock(block_data, pos); // warmup
60+
bench.run([&] {
61+
const auto success{blockman.ReadRawBlock(block_data, pos)};
62+
assert(success);
63+
});
64+
}
65+
66+
BENCHMARK(SaveBlockBench, benchmark::PriorityLevel::HIGH);
67+
BENCHMARK(ReadBlockBench, benchmark::PriorityLevel::HIGH);
68+
BENCHMARK(ReadRawBlockBench, benchmark::PriorityLevel::HIGH);

src/index/base.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void BaseIndex::Sync()
188188

189189
CBlock block;
190190
interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex);
191-
if (!m_chainstate->m_blockman.ReadBlockFromDisk(block, *pindex)) {
191+
if (!m_chainstate->m_blockman.ReadBlock(block, *pindex)) {
192192
FatalErrorf("%s: Failed to read block %s from disk",
193193
__func__, pindex->GetBlockHash().ToString());
194194
return;
@@ -256,7 +256,7 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
256256
// In the case of a reorg, ensure persisted block locator is not stale.
257257
// Pruning has a minimum of 288 blocks-to-keep and getting the index
258258
// out of sync may be possible but a users fault.
259-
// In case we reorg beyond the pruned depth, ReadBlockFromDisk would
259+
// In case we reorg beyond the pruned depth, ReadBlock would
260260
// throw and lead to a graceful shutdown
261261
SetBestBlockIndex(new_tip);
262262
if (!Commit()) {

src/index/blockfilterindex.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ bool BlockFilterIndex::CustomAppend(const interfaces::BlockInfo& block)
256256
// pindex variable gives indexing code access to node internals. It
257257
// will be removed in upcoming commit
258258
const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash));
259-
if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
259+
if (!m_chainstate->m_blockman.ReadBlockUndo(block_undo, *pindex)) {
260260
return false;
261261
}
262262
}

src/index/coinstatsindex.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ bool CoinStatsIndex::CustomAppend(const interfaces::BlockInfo& block)
123123
// pindex variable gives indexing code access to node internals. It
124124
// will be removed in upcoming commit
125125
const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash));
126-
if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
126+
if (!m_chainstate->m_blockman.ReadBlockUndo(block_undo, *pindex)) {
127127
return false;
128128
}
129129

@@ -287,7 +287,7 @@ bool CoinStatsIndex::CustomRewind(const interfaces::BlockRef& current_tip, const
287287
do {
288288
CBlock block;
289289

290-
if (!m_chainstate->m_blockman.ReadBlockFromDisk(block, *iter_tip)) {
290+
if (!m_chainstate->m_blockman.ReadBlock(block, *iter_tip)) {
291291
LogError("%s: Failed to read block %s from disk\n",
292292
__func__, iter_tip->GetBlockHash().ToString());
293293
return false;
@@ -415,7 +415,7 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
415415

416416
// Ignore genesis block
417417
if (pindex->nHeight > 0) {
418-
if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
418+
if (!m_chainstate->m_blockman.ReadBlockUndo(block_undo, *pindex)) {
419419
return false;
420420
}
421421

src/init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1587,7 +1587,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15871587
g_zmq_notification_interface = CZMQNotificationInterface::Create(
15881588
[&chainman = node.chainman](std::vector<uint8_t>& block, const CBlockIndex& index) {
15891589
assert(chainman);
1590-
return chainman->m_blockman.ReadRawBlockFromDisk(block, WITH_LOCK(cs_main, return index.GetBlockPos()));
1590+
return chainman->m_blockman.ReadRawBlock(block, WITH_LOCK(cs_main, return index.GetBlockPos()));
15911591
});
15921592

15931593
if (g_zmq_notification_interface) {

src/net_processing.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
22682268
// Fast-path: in this case it is possible to serve the block directly from disk,
22692269
// as the network format matches the format on disk
22702270
std::vector<uint8_t> block_data;
2271-
if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, block_pos)) {
2271+
if (!m_chainman.m_blockman.ReadRawBlock(block_data, block_pos)) {
22722272
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
22732273
LogDebug(BCLog::NET, "Block was pruned before it could be read, %s\n", pfrom.DisconnectMsg(fLogIPs));
22742274
} else {
@@ -2282,7 +2282,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
22822282
} else {
22832283
// Send block from disk
22842284
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
2285-
if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos)) {
2285+
if (!m_chainman.m_blockman.ReadBlock(*pblockRead, block_pos)) {
22862286
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
22872287
LogDebug(BCLog::NET, "Block was pruned before it could be read, %s\n", pfrom.DisconnectMsg(fLogIPs));
22882288
} else {
@@ -4096,7 +4096,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
40964096

40974097
if (!block_pos.IsNull()) {
40984098
CBlock block;
4099-
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, block_pos)};
4099+
const bool ret{m_chainman.m_blockman.ReadBlock(block, block_pos)};
41004100
// If height is above MAX_BLOCKTXN_DEPTH then this block cannot get
41014101
// pruned after we release cs_main above, so this read should never fail.
41024102
assert(ret);
@@ -5599,7 +5599,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
55995599
PushMessage(*pto, std::move(cached_cmpctblock_msg.value()));
56005600
} else {
56015601
CBlock block;
5602-
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pBestIndex)};
5602+
const bool ret{m_chainman.m_blockman.ReadBlock(block, *pBestIndex)};
56035603
assert(ret);
56045604
CBlockHeaderAndShortTxIDs cmpctblock{block, m_rng.rand64()};
56055605
MakeAndPushMessage(*pto, NetMsgType::CMPCTBLOCK, cmpctblock);

0 commit comments

Comments
 (0)