diff --git a/src/validation.cpp b/src/validation.cpp index 93c32006c68..4321108bf8b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1579,6 +1579,13 @@ Chainstate::Chainstate( m_chainman(chainman), m_from_snapshot_blockhash(from_snapshot_blockhash) {} +const CBlockIndex* Chainstate::SnapshotBase() +{ + if (!m_from_snapshot_blockhash) return nullptr; + if (!m_cached_snapshot_base) m_cached_snapshot_base = Assert(m_chainman.m_blockman.LookupBlockIndex(*m_from_snapshot_blockhash)); + return m_cached_snapshot_base; +} + void Chainstate::InitCoinsDB( size_t cache_size_bytes, bool in_memory, @@ -3434,7 +3441,7 @@ void Chainstate::TryAddBlockIndexCandidate(CBlockIndex* pindex) // For the background chainstate, we only consider connecting blocks // towards the snapshot base (which can't be nullptr or else we'll // never make progress). - const CBlockIndex* snapshot_base = Assert(m_chainman.GetSnapshotBaseBlock()); + const CBlockIndex* snapshot_base{Assert(m_chainman.GetSnapshotBaseBlock())}; if (snapshot_base->GetAncestor(pindex->nHeight) == pindex) { setBlockIndexCandidates.insert(pindex); } @@ -5704,9 +5711,7 @@ util::Result Chainstate::InvalidateCoinsDBOnDisk() const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const { - const auto blockhash_op = this->SnapshotBlockhash(); - if (!blockhash_op) return nullptr; - return Assert(m_blockman.LookupBlockIndex(*blockhash_op)); + return m_active_chainstate ? m_active_chainstate->SnapshotBase() : nullptr; } std::optional ChainstateManager::GetSnapshotBaseHeight() const diff --git a/src/validation.h b/src/validation.h index 4fecc130710..b983876c663 100644 --- a/src/validation.h +++ b/src/validation.h @@ -500,6 +500,9 @@ protected: //! is set to true on the snapshot chainstate. bool m_disabled GUARDED_BY(::cs_main) {false}; + //! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash) + const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main) {nullptr}; + public: //! Reference to a BlockManager instance which itself is shared across all //! Chainstate instances. @@ -551,6 +554,13 @@ public: */ const std::optional m_from_snapshot_blockhash; + /** + * The base of the snapshot this chainstate was created from. + * + * nullptr if this chainstate was not created from a snapshot. + */ + const CBlockIndex* SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + //! Return true if this chainstate relies on blocks that are assumed-valid. In //! practice this means it was created based on a UTXO snapshot. bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); }