From 15fa5b5a908d1019fc1b3042901b42bee0a1bd95 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Sat, 30 Nov 2024 23:46:10 -0500 Subject: [PATCH] validation: call InvalidBlockFound also from AcceptBlock When a block it found invalid during acceptance (but before connection) we now mark its descendants with BLOCK_FAILED_CHILD and update m_best_header when these things weren't done reliably before. This does not fix a serious bug because the flags and m_best_header were being set on a best-effort basis before and not used for anything critical. Setting these reliably has a slight performance cost (iterating over the entire block index) but leads to more consistency in validation and allows removing m_failed_blocks in a later commit. This can only be triggered by providing a block with sufficient PoW that is otherwise invalid, so it is not a DoS vector. --- src/validation.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 1213d8be9f9..df690f2548b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4537,9 +4537,8 @@ bool ChainstateManager::AcceptBlock(const std::shared_ptr& pblock, if (!CheckBlock(block, state, params.GetConsensus()) || !ContextualCheckBlock(block, state, *this, pindex->pprev)) { - if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { - pindex->nStatus |= BLOCK_FAILED_VALID; - m_blockman.m_dirty_blockindex.insert(pindex); + if (Assume(state.IsInvalid())) { + ActiveChainstate().InvalidBlockFound(pindex, state); } LogError("%s: %s\n", __func__, state.ToString()); return false;