aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/txdb.h2
-rw-r--r--src/validation.cpp41
-rw-r--r--src/validation.h20
3 files changed, 55 insertions, 8 deletions
diff --git a/src/txdb.h b/src/txdb.h
index 05bf4e4453..f6db06b6de 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -20,8 +20,6 @@ class CBlockIndex;
class CCoinsViewDBCursor;
class uint256;
-//! No need to periodic flush if at least this much space still available.
-static constexpr int MAX_BLOCK_COINSDB_USAGE = 10;
//! -dbcache default (MiB)
static const int64_t nDefaultDbCache = 450;
//! -dbbatchsize default (bytes)
diff --git a/src/validation.cpp b/src/validation.cpp
index 8f5d333170..5db0ec5d96 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2185,13 +2185,44 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
return true;
}
+CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(const CTxMemPool& tx_pool)
+{
+ return this->GetCoinsCacheSizeState(
+ tx_pool,
+ nCoinCacheUsage,
+ gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
+}
+
+CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(
+ const CTxMemPool& tx_pool,
+ size_t max_coins_cache_size_bytes,
+ size_t max_mempool_size_bytes)
+{
+ int64_t nMempoolUsage = tx_pool.DynamicMemoryUsage();
+ int64_t cacheSize = CoinsTip().DynamicMemoryUsage();
+ int64_t nTotalSpace =
+ max_coins_cache_size_bytes + std::max<int64_t>(max_mempool_size_bytes - nMempoolUsage, 0);
+
+ //! No need to periodic flush if at least this much space still available.
+ static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024; // 10MB
+ int64_t large_threshold =
+ std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
+
+ if (cacheSize > nTotalSpace) {
+ LogPrintf("Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
+ return CoinsCacheSizeState::CRITICAL;
+ } else if (cacheSize > large_threshold) {
+ return CoinsCacheSizeState::LARGE;
+ }
+ return CoinsCacheSizeState::OK;
+}
+
bool CChainState::FlushStateToDisk(
const CChainParams& chainparams,
BlockValidationState &state,
FlushStateMode mode,
int nManualPruneHeight)
{
- int64_t nMempoolUsage = mempool.DynamicMemoryUsage();
LOCK(cs_main);
assert(this->CanFlushToDisk());
static int64_t nLastWrite = 0;
@@ -2206,6 +2237,7 @@ bool CChainState::FlushStateToDisk(
{
bool fFlushForPrune = false;
bool fDoFullFlush = false;
+ CoinsCacheSizeState cache_state = GetCoinsCacheSizeState(::mempool);
LOCK(cs_LastBlockFile);
if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) && !fReindex) {
if (nManualPruneHeight > 0) {
@@ -2234,13 +2266,10 @@ bool CChainState::FlushStateToDisk(
if (nLastFlush == 0) {
nLastFlush = nNow;
}
- int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
- int64_t cacheSize = CoinsTip().DynamicMemoryUsage();
- int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
// 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).
- bool fCacheLarge = mode == FlushStateMode::PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
+ bool fCacheLarge = mode == FlushStateMode::PERIODIC && cache_state >= CoinsCacheSizeState::LARGE;
// The cache is over the limit, we have to write now.
- bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cacheSize > nTotalSpace;
+ bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL;
// 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.
bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
// It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
diff --git a/src/validation.h b/src/validation.h
index 54f97e7213..81b2ccffc2 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -530,6 +530,15 @@ public:
void InitCache() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
};
+enum class CoinsCacheSizeState
+{
+ //! The coins cache is in immediate need of a flush.
+ CRITICAL = 2,
+ //! The cache is at >= 90% capacity.
+ LARGE = 1,
+ OK = 0
+};
+
/**
* CChainState stores and provides an API to update our local knowledge of the
* current best chain.
@@ -721,6 +730,17 @@ public:
/** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */
bool LoadChainTip(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ //! Dictates whether we need to flush the cache to disk or not.
+ //!
+ //! @return the state of the size of the coins cache.
+ CoinsCacheSizeState GetCoinsCacheSizeState(const CTxMemPool& tx_pool)
+ EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
+
+ CoinsCacheSizeState GetCoinsCacheSizeState(
+ const CTxMemPool& tx_pool,
+ size_t max_coins_cache_size_bytes,
+ size_t max_mempool_size_bytes) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
+
private:
bool ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
bool ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);