log,net: avoid ComputeTotalSize when logging is disabled
`PeerManagerImpl::SendBlockTransactions()` computed the total byte size of requested transactions for a debug log line by calling `ComputeTotalSize()` in a tight loop, triggering serialization even when debug logging is off. Guard the size accumulation with `LogAcceptCategory` so the serialization work only happens when the log line can be emitted. No behavior change when debug logging is enabled: the reported block hash, transaction count, and byte totals are the same. The bounds checks still run unconditionally; the debug-only loop iterates the already-validated response contents. Separating debug-only work from the critical path reduces risk and favors the performance-critical non-debug case. This also narrows the racy scope of when logging is toggled from another thread.
This commit is contained in:
1 file changed
+5
-3
@@ -2570,17 +2570,19 @@ uint32_t PeerManagerImpl::GetFetchFlags(const Peer& peer) const
|
|||||||
void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req)
|
void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req)
|
||||||
{
|
{
|
||||||
BlockTransactions resp(req);
|
BlockTransactions resp(req);
|
||||||
unsigned int tx_requested_size = 0;
|
|
||||||
for (size_t i = 0; i < req.indexes.size(); i++) {
|
for (size_t i = 0; i < req.indexes.size(); i++) {
|
||||||
if (req.indexes[i] >= block.vtx.size()) {
|
if (req.indexes[i] >= block.vtx.size()) {
|
||||||
Misbehaving(peer, "getblocktxn with out-of-bounds tx indices");
|
Misbehaving(peer, "getblocktxn with out-of-bounds tx indices");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resp.txn[i] = block.vtx[req.indexes[i]];
|
resp.txn[i] = block.vtx[req.indexes[i]];
|
||||||
tx_requested_size += resp.txn[i]->ComputeTotalSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
if (LogAcceptCategory(BCLog::CMPCTBLOCK, BCLog::Level::Debug)) {
|
||||||
|
uint32_t tx_requested_size{0};
|
||||||
|
for (const auto& tx : resp.txn) tx_requested_size += tx->ComputeTotalSize();
|
||||||
|
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);
|
||||||
|
}
|
||||||
MakeAndPushMessage(pfrom, NetMsgType::BLOCKTXN, resp);
|
MakeAndPushMessage(pfrom, NetMsgType::BLOCKTXN, resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user