Skip to content

Commit e976bd3

Browse files
andrewtothsipal0rinc
committed
validation: add randomness to periodic write interval
Co-Authored-By: Pieter Wuille <[email protected]> Co-Authored-By: l0rinc <[email protected]>
1 parent 2e2f410 commit e976bd3

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

src/test/chainstate_write_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ BOOST_FIXTURE_TEST_CASE(chainstate_write_interval, TestingSetup)
2525
auto& chainstate{Assert(m_node.chainman)->ActiveChainstate()};
2626
BlockValidationState state_dummy{};
2727

28-
// The first periodic flush sets m_last_write and does not flush
28+
// The first periodic flush sets m_next_write and does not flush
2929
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
3030
m_node.validation_signals->SyncWithValidationInterfaceQueue();
3131
BOOST_CHECK(!sub->m_did_flush);
3232

33-
// The periodic flush interval is 1 hour
34-
SetMockTime(GetTime<std::chrono::minutes>() + 59min);
33+
// The periodic flush interval is between 50 and 70 minutes (inclusive)
34+
SetMockTime(GetTime<std::chrono::minutes>() + 49min);
3535
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
3636
m_node.validation_signals->SyncWithValidationInterfaceQueue();
3737
BOOST_CHECK(!sub->m_did_flush);
3838

39-
SetMockTime(GetTime<std::chrono::minutes>() + 1h);
39+
SetMockTime(GetTime<std::chrono::minutes>() + 70min);
4040
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
4141
m_node.validation_signals->SyncWithValidationInterfaceQueue();
4242
BOOST_CHECK(sub->m_did_flush);

src/validation.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,12 @@ using node::SnapshotMetadata;
9090

9191
/** Size threshold for warning about slow UTXO set flush to disk. */
9292
static constexpr size_t WARN_FLUSH_COINS_SIZE = 1 << 30; // 1 GiB
93-
/** Time to wait between writing blocks/block index and chainstate to disk. */
94-
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL{1};
93+
/** Time window to wait between writing blocks/block index and chainstate to disk.
94+
* Randomize writing time inside the window to prevent a situation where the
95+
* network over time settles into a few cohorts of synchronized writers.
96+
*/
97+
static constexpr auto DATABASE_WRITE_INTERVAL_MIN{50min};
98+
static constexpr auto DATABASE_WRITE_INTERVAL_MAX{70min};
9599
/** Maximum age of our tip for us to be considered current for fee estimation */
96100
static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE{3};
97101
const std::vector<std::string> CHECKLEVEL_DOC {
@@ -2945,7 +2949,8 @@ bool Chainstate::FlushStateToDisk(
29452949
}
29462950

29472951
if (should_write || m_next_write == NodeClock::time_point::max()) {
2948-
m_next_write = NodeClock::now() + DATABASE_WRITE_INTERVAL;
2952+
constexpr auto range{DATABASE_WRITE_INTERVAL_MAX - DATABASE_WRITE_INTERVAL_MIN};
2953+
m_next_write = FastRandomContext().rand_uniform_delay(NodeClock::now() + DATABASE_WRITE_INTERVAL_MIN, range);
29492954
}
29502955
}
29512956
if (full_flush_completed && m_chainman.m_options.signals) {

0 commit comments

Comments
 (0)