blockchain: if block is known invalid, fail block verification
What changed, and why it matters
This change fixes a logic bug in Monero's blockchain handling. Previously, when the software saw a block it already knew about, it would simply mark it as 'already exists' and move on, even if that block had previously been flagged as invalid. After the patch, if a known-invalid block is seen again, the verification is now correctly marked as failed. This prevents an invalid block from being treated as harmless on re-submission and could stop certain denial-of-service or chain-integrity attacks.
Treat this as a security-relevant hardening fix and include it in the next release. Nodes and exchanges should upgrade promptly. Review whether any other callers of have_block() ignore invalid-block status similarly.
Security signals we found
Corrects inconsistent validation state for previously rejected blocks
Adds explicit failure flag when a known-invalid block is re-encountered
Prevents potential bypass of block rejection logic
Small, targeted change in consensus-critical code path
Evidence from the diff
In Blockchain::add_new_block(), the existing have_block(id) check is replaced with have_block(id, &where), which reports whether the block is in the main chain, on an alternate chain, or in the invalid blocks set. If where == HAVE_BLOCK_INVALID, the code now sets bvc.m_verifivation_failed = true in addition to bvc.m_already_exists = true. This closes a gap where a previously rejected invalid block could be re-presented without triggering a verification failure signal, potentially allowing it to be reprocessed or mishandled downstream.
Changed components
src/cryptonote_core/blockchain.cppBlockchain::add_new_block()block_verification_contextInspect captured patch +4 / −1
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 6a90211..218b94d 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -4520,10 +4520,13 @@ bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc,
CRITICAL_REGION_LOCAL(m_tx_pool);//to avoid deadlock lets lock tx_pool for whole add/reorganize process
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
db_rtxn_guard rtxn_guard(m_db);
- if(have_block(id))
+ int where = 0;
+ if(have_block(id, &where))
{
LOG_PRINT_L3("block with id = " << id << " already exists");
bvc.m_already_exists = true;
+ if (where == HAVE_BLOCK_INVALID)
+ bvc.m_verifivation_failed = true;
return false;
}
Why this scored 58/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.