cryptonote_core: rm unnecessary db reads before block relay
What changed, and why it matters
This commit removes several database checks that Monero performed before forwarding a newly received block to other peers. Previously, the node verified that it had all the block's transactions and that no blockchain reorganisation had happened. Now it relays the block immediately with fewer checks. The stated goal is performance, but the change could allow invalid or stale blocks to be relayed more easily, potentially contributing to network confusion or denial-of-service. There is no direct evidence in the commit that this fixes a known security bug or that it introduces an exploitable vulnerability.
Review whether the removed checks were safety-critical. In particular, confirm that downstream validation in the P2P layer or receiving peers will reject blocks with missing transactions or on stale tips, so the removed local checks are truly redundant. Consider adding tests that exercise reorg-during-relay and missing-transaction scenarios. If this is a performance optimisation, document the assumed invariants.
Security signals we found
removal of pre-relay transaction-availability checks
removal of reorg-detection guard before block relay
reduced database reads in block propagation path
change in semantics of current_blockchain_height field (now block height + 1 instead of storage height)
Evidence from the diff
The patch deletes code in cryptonote_core.cpp’s block relay path. It no longer: (1) fetches the current blockchain height from storage, (2) checks whether each transaction referenced by the block is already present in the local blockchain/mempool, (3) detects a reorganisation by comparing block id-by-height to the block hash, or (4) aborts relaying when transactions are missing. Instead it sets current_blockchain_height to get_block_height(b)+1 and immediately serialises and relays the block. The removal of the ‘missed_txs’ check and the reorg guard reduces defensive validation before propagation. This could let a node relay blocks whose transactions it has not validated or that sit on a stale chain tip, but the commit itself does not show an attack vector or a disclosed vulnerability.
Changed components
src/cryptonote_core/cryptonote_core.cppblock relay / fluffy block propagationcryptonote_connection_context handlingInspect captured patch +1 / −19
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index b08939f..b0d4e9e 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1326,26 +1326,8 @@ namespace cryptonote
{
cryptonote_connection_context exclude_context = {};
NOTIFY_NEW_FLUFFY_BLOCK::request arg{};
- arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_height();
- std::vector<crypto::hash> missed_txs;
- for (const auto &tx_hash : b.tx_hashes)
- {
- if (m_blockchain_storage.have_tx(tx_hash))
- continue;
- missed_txs.push_back(tx_hash);
- }
- if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b))
- {
- LOG_PRINT_L1("Block found but, seems that reorganize just happened after that, do not relay this block");
- return true;
- }
- CHECK_AND_ASSERT_MES(!missed_txs.size(), false, "can't find some transactions in found block:" << get_block_hash(b)
- << " b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()" << missed_txs.size());
-
+ arg.current_blockchain_height = get_block_height(b) + 1;
block_to_blob(b, arg.b.block);
- // Relay an empty fluffy block
- arg.b.txs.clear();
-
m_pprotocol->relay_block(arg, exclude_context);
}
return true;
Why this scored 26/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.