Cache block index entry corresponding to assumeutxo snapshot base blockhash

This is to (a) avoid repeated lookups into the block index for an entry that
should never change and (b) emphasize that the snapshot base should always
exist when set and not change during the runtime of the program.

Thanks to Russ Yanofsky for suggesting this approach.
This commit is contained in:
Suhas Daftuar committed 2023-07-24 16:23:38 -04:00
1 parent 3556b85022
commit d4a11abb19
2 files changed
+19 -4

No files matched your search

+9 -4
View File
@@ -1579,6 +1579,13 @@ Chainstate::Chainstate(
m_chainman(chainman), m_chainman(chainman),
m_from_snapshot_blockhash(from_snapshot_blockhash) {} 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( void Chainstate::InitCoinsDB(
size_t cache_size_bytes, size_t cache_size_bytes,
bool in_memory, bool in_memory,
@@ -3434,7 +3441,7 @@ void Chainstate::TryAddBlockIndexCandidate(CBlockIndex* pindex)
// For the background chainstate, we only consider connecting blocks // For the background chainstate, we only consider connecting blocks
// towards the snapshot base (which can't be nullptr or else we'll // towards the snapshot base (which can't be nullptr or else we'll
// never make progress). // 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) { if (snapshot_base->GetAncestor(pindex->nHeight) == pindex) {
setBlockIndexCandidates.insert(pindex); setBlockIndexCandidates.insert(pindex);
} }
@@ -5704,9 +5711,7 @@ util::Result<void> Chainstate::InvalidateCoinsDBOnDisk()
const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const
{ {
const auto blockhash_op = this->SnapshotBlockhash(); return m_active_chainstate ? m_active_chainstate->SnapshotBase() : nullptr;
if (!blockhash_op) return nullptr;
return Assert(m_blockman.LookupBlockIndex(*blockhash_op));
} }
std::optional<int> ChainstateManager::GetSnapshotBaseHeight() const std::optional<int> ChainstateManager::GetSnapshotBaseHeight() const
+10
View File
@@ -500,6 +500,9 @@ protected:
//! is set to true on the snapshot chainstate. //! is set to true on the snapshot chainstate.
bool m_disabled GUARDED_BY(::cs_main) {false}; 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: public:
//! Reference to a BlockManager instance which itself is shared across all //! Reference to a BlockManager instance which itself is shared across all
//! Chainstate instances. //! Chainstate instances.
@@ -551,6 +554,13 @@ public:
*/ */
const std::optional<uint256> m_from_snapshot_blockhash; const std::optional<uint256> 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 //! Return true if this chainstate relies on blocks that are assumed-valid. In
//! practice this means it was created based on a UTXO snapshot. //! practice this means it was created based on a UTXO snapshot.
bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); } bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); }