What changed, and why it matters
This commit adds internal bookkeeping so Bitcoin Core can remember the last block whose state was safely written to disk. It does not, by itself, change any security boundary or fix a known bug; it is a small infrastructure change meant to support future work that keeps database indexes from getting ahead of the main chain state.
No immediate action required. Treat as normal infrastructure commit. Monitor follow-up commits that consume GetLastFlushedBlock() to ensure the intended synchronization invariant is correctly enforced.
Security signals we found
New internal state tracking for flush synchronization
No direct bug fix or vulnerability remediation visible in diff
Commit message frames change as preparatory infrastructure, not as a security fix
Evidence from the diff
The patch introduces a new Chainstate member m_last_flushed_block, guarded by cs_main, and a getter GetLastFlushedBlock(). It is set in two places: after a successful CoinsTip flush in FlushStateToDisk(), and when the chain tip is loaded at startup in LoadChainTip(). A unit test is updated to assert the tracked value matches the expected block index. The commit message states this will later be used to prevent indexes from flushing their state ahead of the chainstate.
Changed components
src/validation.cppsrc/validation.hsrc/test/chainstate_write_tests.cppInspect captured patch +8 / −0
diff --git a/src/test/chainstate_write_tests.cpp b/src/test/chainstate_write_tests.cpp
index 01e00011..6699846c 100644
--- a/src/test/chainstate_write_tests.cpp
+++ b/src/test/chainstate_write_tests.cpp
@@ -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()
diff --git a/src/validation.cpp b/src/validation.cpp
index bd05376b..9df377fb 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -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
diff --git a/src/validation.h b/src/validation.h
index 2aac1e90..d89ad353 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -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
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.