From a51e91783aac0beefcb604be159eb1cb96a39051 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 23 Apr 2024 18:08:35 -0400 Subject: [PATCH] validation: add RecalculateBestHeader() function It recalculates m_best_header by looping over the entire block index. Even though this is not very performant, it will only be used in rare situations that cannot be triggered by others without a cost: As part of to invalidateblock / reconsiderblock rpcs, or when a block with an accepted header with valid PoW turns out to be invalid later during full validation. --- src/validation.cpp | 11 +++++++++++ src/validation.h | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/src/validation.cpp b/src/validation.cpp index 8e4ea8eda2f..7430ec60d11 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -6396,6 +6396,17 @@ std::optional ChainstateManager::GetSnapshotBaseHeight() const return base ? std::make_optional(base->nHeight) : std::nullopt; } +void ChainstateManager::RecalculateBestHeader() +{ + AssertLockHeld(cs_main); + m_best_header = ActiveChain().Tip(); + for (auto& entry : m_blockman.m_block_index) { + if (!(entry.second.nStatus & BLOCK_FAILED_MASK) && m_best_header->nChainWork < entry.second.nChainWork) { + m_best_header = &entry.second; + } + } +} + bool ChainstateManager::ValidatedSnapshotCleanup() { AssertLockHeld(::cs_main); diff --git a/src/validation.h b/src/validation.h index 059ae52bdf4..61a9586d744 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1321,6 +1321,11 @@ public: //! nullopt. std::optional GetSnapshotBaseHeight() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + //! If, due to invalidation / reconsideration of blocks, the previous + //! best header is no longer valid / guaranteed to be the most-work + //! header in our block-index not known to be invalid, recalculate it. + void RecalculateBestHeader() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + CCheckQueue& GetCheckQueue() { return m_script_check_queue; } ~ChainstateManager();