validation: track last flushed block

This will be used to prevent the indexes from flushing their state ahead of
the chainstate.

Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
This commit is contained in:
Martin Zumsande
2025-09-10 15:03:35 -04:00
parent 13c02b5466
commit 09c06960c6
3 changed files with 8 additions and 0 deletions

View File

@@ -85,6 +85,7 @@ BOOST_FIXTURE_TEST_CASE(write_during_multiblock_activation, TestChain100Setup)
// Set m_next_write to current time
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::FORCE_FLUSH);
BOOST_CHECK_EQUAL(WITH_LOCK(::cs_main, return chainstate.GetLastFlushedBlock()), second_from_tip->pprev);
m_node.validation_signals->SyncWithValidationInterfaceQueue();
// The periodic flush interval is between 50 and 70 minutes (inclusive)
// The next call to a PERIODIC write will flush
@@ -101,6 +102,7 @@ BOOST_FIXTURE_TEST_CASE(write_during_multiblock_activation, TestChain100Setup)
// inside the outer loop.
m_node.validation_signals->SyncWithValidationInterfaceQueue();
BOOST_CHECK_EQUAL(sub->m_flushed_at_block, second_from_tip);
BOOST_CHECK_EQUAL(WITH_LOCK(::cs_main, return chainstate.GetLastFlushedBlock()), second_from_tip);
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -2823,6 +2823,7 @@ bool Chainstate::FlushStateToDisk(
}
// Flush the chainstate (which may refer to block index entries).
empty_cache ? CoinsTip().Flush() : CoinsTip().Sync();
m_last_flushed_block = m_blockman.LookupBlockIndex(CoinsTip().GetBestBlock());
full_flush_completed = true;
TRACEPOINT(utxocache, flush,
int64_t{Ticks<std::chrono::microseconds>(NodeClock::now() - nNow)},
@@ -4584,6 +4585,7 @@ bool Chainstate::LoadChainTip()
}
m_chain.SetTip(*pindex);
m_chainman.UpdateIBDStatus();
m_last_flushed_block = pindex;
tip = m_chain.Tip();
// nSequenceId is one of the keys used to sort setBlockIndexCandidates. Ensure all

View File

@@ -840,6 +840,9 @@ public:
std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
//! Get the last block that was flushed to disk.
const CBlockIndex* GetLastFlushedBlock() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { return m_last_flushed_block; }
//! Indirection necessary to make lock annotations work with an optional mempool.
RecursiveMutex* MempoolMutex() const LOCK_RETURNED(m_mempool->cs)
{
@@ -890,6 +893,7 @@ protected:
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
NodeClock::time_point m_next_write{NodeClock::time_point::max()};
const CBlockIndex* m_last_flushed_block GUARDED_BY(::cs_main){nullptr};
/**
* In case of an invalid snapshot, rename the coins leveldb directory so