Context
The new accounting options introduced in #32582 can be quite heavy, and not needed when debug logging is disabled.
Problem
PartiallyDownloadedBlock::FillBlock() and PeerManagerImpl::SendBlockTransactions() accumulate transaction sizes for debug logging by calling GetTotalSize() in loops, which invokes expensive GetSerializeSize() serializations.
The header hash is also only calculated for the debug log.
Fixes
Guard the size calculations with LogAcceptCategory() checks so serialization only occurs when compact block debug logging is enabled.
Also modernized the surrounding code a bit since the change is quite trivial.
Reproducer
You can test the change by starting your up-to-date bitcoind node with -debug=cmpctblock and observing the compact block lines such as:
[cmpctblock] Successfully reconstructed block 00000000000000000001061eaa6c0fe79258e7f79606e67ac495765cb121a520 with 1 txn prefilled, 3122 txn from mempool (incl at least 3 from extra pool) and 641 txn (352126 bytes) requested
0diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp
1index 58620c93cc..f16eb38fa5 100644
2--- a/src/blockencodings.cpp
3+++ b/src/blockencodings.cpp
4@@ -186,6 +186,7 @@ bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const
5
6 ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing, bool segwit_active)
7 {
8+ LogInfo("PartiallyDownloadedBlock::FillBlock called");
9 if (header.IsNull()) return READ_STATUS_INVALID;
10
11 block = header;
12@@ -218,6 +219,7 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<
13 }
14
15 if (LogAcceptCategory(BCLog::CMPCTBLOCK, BCLog::Level::Debug)) {
16+ LogInfo("debug log enabled");
17 const uint256 hash{block.GetHash()}; // avoid cleared header
18 uint32_t tx_missing_size{0};
19 for (const auto& tx : vtx_missing) tx_missing_size += tx->ComputeTotalSize(); // avoid cleared txn_available
20diff --git a/src/net_processing.cpp b/src/net_processing.cpp
21index 5600c8d389..c081825f77 100644
22--- a/src/net_processing.cpp
23+++ b/src/net_processing.cpp
24@@ -2470,6 +2470,7 @@ uint32_t PeerManagerImpl::GetFetchFlags(const Peer& peer) const
25
26 void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req)
27 {
28+ LogInfo("PeerManagerImpl::SendBlockTransactions called");
29 BlockTransactions resp(req);
30 for (size_t i = 0; i < req.indexes.size(); i++) {
31 if (req.indexes[i] >= block.vtx.size()) {
32@@ -2480,6 +2481,7 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlo
33 }
34
35 if (LogAcceptCategory(BCLog::CMPCTBLOCK, BCLog::Level::Debug)) {
36+ LogInfo("debug log enabled");
37 uint32_t tx_requested_size{0};
38 for (const auto i : req.indexes) tx_requested_size += block.vtx[i]->ComputeTotalSize();
39 LogDebug(BCLog::CMPCTBLOCK, "Peer %d sent us a GETBLOCKTXN for block %s, sending a BLOCKTXN with %u txns. (%u bytes)\n", pfrom.GetId(), block.GetHash().ToString(), resp.txn.size(), tx_requested_size);