Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <test/util/setup_common.h>6#include <test/util/time.h>7#include <validation.h>8#include <validationinterface.h>10#include <boost/test/unit_test.hpp>12using kernel::ChainstateRole;14// Taken from validation.cpp15static constexpr auto DATABASE_WRITE_INTERVAL_MIN{50min};16static constexpr auto DATABASE_WRITE_INTERVAL_MAX{70min};18BOOST_AUTO_TEST_SUITE(chainstate_write_tests)20BOOST_FIXTURE_TEST_CASE(chainstate_write_interval, TestingSetup)21{22struct TestSubscriber final : CValidationInterface {23bool m_did_flush{false};24void ChainStateFlushed(const ChainstateRole&, const CBlockLocator&) override25{26m_did_flush = true;27}28};30const auto sub{std::make_shared<TestSubscriber>()};31m_node.validation_signals->RegisterSharedValidationInterface(sub);32auto& chainstate{Assert(m_node.chainman)->ActiveChainstate()};33BlockValidationState state_dummy{};34FakeNodeClock clock{};36// The first periodic flush sets m_next_write and does not flush37chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);38m_node.validation_signals->SyncWithValidationInterfaceQueue();39BOOST_CHECK(!sub->m_did_flush);41// The periodic flush interval is between 50 and 70 minutes (inclusive)42clock += DATABASE_WRITE_INTERVAL_MIN - 1min;43chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);44m_node.validation_signals->SyncWithValidationInterfaceQueue();45BOOST_CHECK(!sub->m_did_flush);47clock += DATABASE_WRITE_INTERVAL_MAX;48chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);49m_node.validation_signals->SyncWithValidationInterfaceQueue();50BOOST_CHECK(sub->m_did_flush);51}53// Test that we do PERIODIC flushes inside ActivateBestChain.54// This is necessary for reindex-chainstate to be able to periodically flush55// before reaching chain tip.56BOOST_FIXTURE_TEST_CASE(write_during_multiblock_activation, TestChain100Setup)57{58struct TestSubscriber final : CValidationInterface59{60const CBlockIndex* m_tip{nullptr};61const CBlockIndex* m_flushed_at_block{nullptr};62void ChainStateFlushed(const ChainstateRole&, const CBlockLocator&) override63{64m_flushed_at_block = m_tip;65}66void UpdatedBlockTip(const CBlockIndex* block_index, const CBlockIndex*, bool) override {67m_tip = block_index;68}69};71auto& chainstate{Assert(m_node.chainman)->ActiveChainstate()};72BlockValidationState state_dummy{};74// Pop two blocks from the tip75const CBlockIndex* tip{chainstate.m_chain.Tip()};76CBlockIndex* second_from_tip{tip->pprev};78{79LOCK2(m_node.chainman->GetMutex(), chainstate.MempoolMutex());80chainstate.DisconnectTip(state_dummy, nullptr);81chainstate.DisconnectTip(state_dummy, nullptr);82}84BOOST_CHECK_EQUAL(second_from_tip->pprev, chainstate.m_chain.Tip());86// Set m_next_write to current time87chainstate.FlushStateToDisk(state_dummy, FlushStateMode::FORCE_FLUSH);88BOOST_CHECK_EQUAL(WITH_LOCK(::cs_main, return chainstate.GetLastFlushedBlock()), second_from_tip->pprev);89m_node.validation_signals->SyncWithValidationInterfaceQueue();90// The periodic flush interval is between 50 and 70 minutes (inclusive)91// The next call to a PERIODIC write will flush92m_clock += DATABASE_WRITE_INTERVAL_MAX;94const auto sub{std::make_shared<TestSubscriber>()};95m_node.validation_signals->RegisterSharedValidationInterface(sub);97// ActivateBestChain back to tip98chainstate.ActivateBestChain(state_dummy, nullptr);99BOOST_CHECK_EQUAL(tip, chainstate.m_chain.Tip());100// Check that we flushed inside ActivateBestChain while we were at the101// second block from tip, since FlushStateToDisk is called with PERIODIC102// inside the outer loop.103m_node.validation_signals->SyncWithValidationInterfaceQueue();104BOOST_CHECK_EQUAL(sub->m_flushed_at_block, second_from_tip);105BOOST_CHECK_EQUAL(WITH_LOCK(::cs_main, return chainstate.GetLastFlushedBlock()), second_from_tip);106}108BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.