Skip to content

Commit d4a11ab

Browse files
committed
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.
1 parent 3556b85 commit d4a11ab

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

src/validation.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,13 @@ Chainstate::Chainstate(
15791579
m_chainman(chainman),
15801580
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
15811581

1582+
const CBlockIndex* Chainstate::SnapshotBase()
1583+
{
1584+
if (!m_from_snapshot_blockhash) return nullptr;
1585+
if (!m_cached_snapshot_base) m_cached_snapshot_base = Assert(m_chainman.m_blockman.LookupBlockIndex(*m_from_snapshot_blockhash));
1586+
return m_cached_snapshot_base;
1587+
}
1588+
15821589
void Chainstate::InitCoinsDB(
15831590
size_t cache_size_bytes,
15841591
bool in_memory,
@@ -3434,7 +3441,7 @@ void Chainstate::TryAddBlockIndexCandidate(CBlockIndex* pindex)
34343441
// For the background chainstate, we only consider connecting blocks
34353442
// towards the snapshot base (which can't be nullptr or else we'll
34363443
// never make progress).
3437-
const CBlockIndex* snapshot_base = Assert(m_chainman.GetSnapshotBaseBlock());
3444+
const CBlockIndex* snapshot_base{Assert(m_chainman.GetSnapshotBaseBlock())};
34383445
if (snapshot_base->GetAncestor(pindex->nHeight) == pindex) {
34393446
setBlockIndexCandidates.insert(pindex);
34403447
}
@@ -5704,9 +5711,7 @@ util::Result<void> Chainstate::InvalidateCoinsDBOnDisk()
57045711

57055712
const CBlockIndex* ChainstateManager::GetSnapshotBaseBlock() const
57065713
{
5707-
const auto blockhash_op = this->SnapshotBlockhash();
5708-
if (!blockhash_op) return nullptr;
5709-
return Assert(m_blockman.LookupBlockIndex(*blockhash_op));
5714+
return m_active_chainstate ? m_active_chainstate->SnapshotBase() : nullptr;
57105715
}
57115716

57125717
std::optional<int> ChainstateManager::GetSnapshotBaseHeight() const

src/validation.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ class Chainstate
500500
//! is set to true on the snapshot chainstate.
501501
bool m_disabled GUARDED_BY(::cs_main) {false};
502502

503+
//! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash)
504+
const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main) {nullptr};
505+
503506
public:
504507
//! Reference to a BlockManager instance which itself is shared across all
505508
//! Chainstate instances.
@@ -551,6 +554,13 @@ class Chainstate
551554
*/
552555
const std::optional<uint256> m_from_snapshot_blockhash;
553556

557+
/**
558+
* The base of the snapshot this chainstate was created from.
559+
*
560+
* nullptr if this chainstate was not created from a snapshot.
561+
*/
562+
const CBlockIndex* SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
563+
554564
//! Return true if this chainstate relies on blocks that are assumed-valid. In
555565
//! practice this means it was created based on a UTXO snapshot.
556566
bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); }

0 commit comments

Comments
 (0)