diff --git a/src/test/chainstate_write_tests.cpp b/src/test/chainstate_write_tests.cpp index c76164099c2..ccca2f9be10 100644 --- a/src/test/chainstate_write_tests.cpp +++ b/src/test/chainstate_write_tests.cpp @@ -25,18 +25,18 @@ BOOST_FIXTURE_TEST_CASE(chainstate_write_interval, TestingSetup) auto& chainstate{Assert(m_node.chainman)->ActiveChainstate()}; BlockValidationState state_dummy{}; - // The first periodic flush sets m_last_write and does not flush + // The first periodic flush sets m_next_write and does not flush chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC); m_node.validation_signals->SyncWithValidationInterfaceQueue(); BOOST_CHECK(!sub->m_did_flush); - // The periodic flush interval is 1 hour - SetMockTime(GetTime() + 59min); + // The periodic flush interval is between 50 and 70 minutes (inclusive) + SetMockTime(GetTime() + 49min); chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC); m_node.validation_signals->SyncWithValidationInterfaceQueue(); BOOST_CHECK(!sub->m_did_flush); - SetMockTime(GetTime() + 1h); + SetMockTime(GetTime() + 70min); chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC); m_node.validation_signals->SyncWithValidationInterfaceQueue(); BOOST_CHECK(sub->m_did_flush); diff --git a/src/validation.cpp b/src/validation.cpp index 379e8604131..c7b82678f16 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -90,8 +90,12 @@ using node::SnapshotMetadata; /** Size threshold for warning about slow UTXO set flush to disk. */ static constexpr size_t WARN_FLUSH_COINS_SIZE = 1 << 30; // 1 GiB -/** Time to wait between writing blocks/block index and chainstate to disk. */ -static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL{1}; +/** Time window to wait between writing blocks/block index and chainstate to disk. + * Randomize writing time inside the window to prevent a situation where the + * network over time settles into a few cohorts of synchronized writers. +*/ +static constexpr auto DATABASE_WRITE_INTERVAL_MIN{50min}; +static constexpr auto DATABASE_WRITE_INTERVAL_MAX{70min}; /** Maximum age of our tip for us to be considered current for fee estimation */ static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE{3}; const std::vector CHECKLEVEL_DOC { @@ -2886,7 +2890,8 @@ bool Chainstate::FlushStateToDisk( bool should_write = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicWrite || fFlushForPrune; if (should_write || m_next_write == NodeClock::time_point::max()) { - m_next_write = nNow + DATABASE_WRITE_INTERVAL; + constexpr auto range{DATABASE_WRITE_INTERVAL_MAX - DATABASE_WRITE_INTERVAL_MIN}; + m_next_write = FastRandomContext().rand_uniform_delay(nNow + DATABASE_WRITE_INTERVAL_MIN, range); } // Write blocks, block index and best chain related state to disk.