Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
#include <optional> | #include <optional> | ||||
#include <string> | #include <string> | ||||
#include <thread> | #include <thread> | ||||
#define MICRO 0.000001 | #define MICRO 0.000001 | ||||
#define MILLI 0.001 | #define MILLI 0.001 | ||||
/** Time to wait (in seconds) between writing blocks/block index to disk. */ | /** Time to wait between writing blocks/block index to disk. */ | ||||
static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; | static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL{1}; | ||||
/** Time to wait (in seconds) between flushing chainstate to disk. */ | /** Time to wait between flushing chainstate to disk. */ | ||||
static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; | static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL{24}; | ||||
ChainstateManager g_chainman; | ChainstateManager g_chainman; | ||||
CChainState &ChainstateActive() { | CChainState &ChainstateActive() { | ||||
LOCK(::cs_main); | LOCK(::cs_main); | ||||
assert(g_chainman.m_active_chainstate); | assert(g_chainman.m_active_chainstate); | ||||
return *g_chainman.m_active_chainstate; | return *g_chainman.m_active_chainstate; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,011 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool CChainState::FlushStateToDisk(const CChainParams &chainparams, | bool CChainState::FlushStateToDisk(const CChainParams &chainparams, | ||||
BlockValidationState &state, | BlockValidationState &state, | ||||
FlushStateMode mode, | FlushStateMode mode, | ||||
int nManualPruneHeight) { | int nManualPruneHeight) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
assert(this->CanFlushToDisk()); | assert(this->CanFlushToDisk()); | ||||
static int64_t nLastWrite = 0; | static std::chrono::microseconds nLastWrite{0}; | ||||
static int64_t nLastFlush = 0; | static std::chrono::microseconds nLastFlush{0}; | ||||
std::set<int> setFilesToPrune; | std::set<int> setFilesToPrune; | ||||
bool full_flush_completed = false; | bool full_flush_completed = false; | ||||
const size_t coins_count = CoinsTip().GetCacheSize(); | const size_t coins_count = CoinsTip().GetCacheSize(); | ||||
const size_t coins_mem_usage = CoinsTip().DynamicMemoryUsage(); | const size_t coins_mem_usage = CoinsTip().DynamicMemoryUsage(); | ||||
try { | try { | ||||
{ | { | ||||
Show All 19 Lines | try { | ||||
if (!setFilesToPrune.empty()) { | if (!setFilesToPrune.empty()) { | ||||
fFlushForPrune = true; | fFlushForPrune = true; | ||||
if (!fHavePruned) { | if (!fHavePruned) { | ||||
pblocktree->WriteFlag("prunedblockfiles", true); | pblocktree->WriteFlag("prunedblockfiles", true); | ||||
fHavePruned = true; | fHavePruned = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
int64_t nNow = GetTimeMicros(); | const auto nNow = GetTime<std::chrono::microseconds>(); | ||||
// Avoid writing/flushing immediately after startup. | // Avoid writing/flushing immediately after startup. | ||||
if (nLastWrite == 0) { | if (nLastWrite.count() == 0) { | ||||
nLastWrite = nNow; | nLastWrite = nNow; | ||||
} | } | ||||
if (nLastFlush == 0) { | if (nLastFlush.count() == 0) { | ||||
nLastFlush = nNow; | nLastFlush = nNow; | ||||
} | } | ||||
// The cache is large and we're within 10% and 10 MiB of the limit, | // The cache is large and we're within 10% and 10 MiB of the limit, | ||||
// but we have time now (not in the middle of a block processing). | // but we have time now (not in the middle of a block processing). | ||||
bool fCacheLarge = mode == FlushStateMode::PERIODIC && | bool fCacheLarge = mode == FlushStateMode::PERIODIC && | ||||
cache_state >= CoinsCacheSizeState::LARGE; | cache_state >= CoinsCacheSizeState::LARGE; | ||||
// The cache is over the limit, we have to write now. | // The cache is over the limit, we have to write now. | ||||
bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && | bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && | ||||
cache_state >= CoinsCacheSizeState::CRITICAL; | cache_state >= CoinsCacheSizeState::CRITICAL; | ||||
// It's been a while since we wrote the block index to disk. Do this | // It's been a while since we wrote the block index to disk. Do this | ||||
// frequently, so we don't need to redownload after a crash. | // frequently, so we don't need to redownload after a crash. | ||||
bool fPeriodicWrite = | bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && | ||||
mode == FlushStateMode::PERIODIC && | nNow > nLastWrite + DATABASE_WRITE_INTERVAL; | ||||
nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; | |||||
// It's been very long since we flushed the cache. Do this | // It's been very long since we flushed the cache. Do this | ||||
// infrequently, to optimize cache usage. | // infrequently, to optimize cache usage. | ||||
bool fPeriodicFlush = | bool fPeriodicFlush = mode == FlushStateMode::PERIODIC && | ||||
mode == FlushStateMode::PERIODIC && | nNow > nLastFlush + DATABASE_FLUSH_INTERVAL; | ||||
nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; | |||||
// Combine all conditions that result in a full cache flush. | // Combine all conditions that result in a full cache flush. | ||||
fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || | fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || | ||||
fCacheCritical || fPeriodicFlush || fFlushForPrune; | fCacheCritical || fPeriodicFlush || fFlushForPrune; | ||||
// Write blocks and block index to disk. | // Write blocks and block index to disk. | ||||
if (fDoFullFlush || fPeriodicWrite) { | if (fDoFullFlush || fPeriodicWrite) { | ||||
// Depend on nMinDiskSpace to ensure we can write block index | // Depend on nMinDiskSpace to ensure we can write block index | ||||
if (!CheckDiskSpace(GetBlocksDir())) { | if (!CheckDiskSpace(GetBlocksDir())) { | ||||
return AbortNode(state, "Disk space is too low!", | return AbortNode(state, "Disk space is too low!", | ||||
▲ Show 20 Lines • Show All 3,968 Lines • Show Last 20 Lines |