Blockchain: fix wrong block_weight in handle_get_objects
What changed, and why it matters
This commit fixes a bug in Monero's blockchain code where a node could accidentally report the wrong block size (weight) to a peer. The bug happened because the code used a mismatched index when some requested blocks were missing. A peer receiving the wrong weight might ban the node, hurting network connectivity. The fix also removes an unnecessary database lookup.
Apply the patch. Nodes should upgrade to avoid being incorrectly banned by peers due to stale or mismatched block weight data. No immediate incident response beyond normal patching is indicated.
Security signals we found
Incorrect index mapping between request and response arrays
Wrong block metadata returned to peer
Potential peer-triggered node ban (denial of service / isolation)
Fix saves a database query per returned block
Evidence from the diff
In Blockchain::handle_get_objects(), the loop iterated over local blocks but indexed into arg.blocks using counter i. When some requested IDs are missing, blocks.size() differs from arg.blocks.size(), so arg.blocks[i] does not correspond to the current block. The patch uses bl.second (the block hash paired with the returned block) to look up the correct block height and weight, and removes a redundant block_exists() check. This prevents returning an incorrect block_weight to peers during pruned block responses.
Changed components
src/cryptonote_core/blockchain.cppBlockchain::handle_get_objectsP2P block/transaction object response handlingInspect captured patch +1 / −3
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 09e6a3f..b1945f6 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -2270,9 +2270,7 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
//pack block
e.block = std::move(bl.first);
- e.block_weight = 0;
- if (arg.prune && m_db->block_exists(arg.blocks[i]))
- e.block_weight = m_db->get_block_weight(m_db->get_block_height(arg.blocks[i]));
+ e.block_weight = arg.prune ? m_db->get_block_weight(get_block_height(bl.second)) : 0;
}
return true;
Why this scored 60/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.