aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSuhas Daftuar <sdaftuar@chaincode.com>2023-06-27 12:11:34 -0400
committerSuhas Daftuar <sdaftuar@chaincode.com>2023-07-24 16:23:38 -0400
commitd4a11abb1972b54f0babdccfbb2fde97ab885933 (patch)
treeae48398820384ca2a159c80887e378c11884f82c /src
parent3556b850221bc0e597d7dd749d4d47ab58dc8083 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/validation.cpp13
-rw-r--r--src/validation.h10
2 files changed, 19 insertions, 4 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index 93c32006c6..4321108bf8 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<void> 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<int> ChainstateManager::GetSnapshotBaseHeight() const
diff --git a/src/validation.h b/src/validation.h
index 4fecc13071..b983876c66 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<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
//! practice this means it was created based on a UTXO snapshot.
bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); }