@@ -2185,13 +2185,44 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
2185
2185
return true ;
2186
2186
}
2187
2187
2188
+ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState (const CTxMemPool& tx_pool)
2189
+ {
2190
+ return this ->GetCoinsCacheSizeState (
2191
+ tx_pool,
2192
+ nCoinCacheUsage,
2193
+ gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 );
2194
+ }
2195
+
2196
+ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState (
2197
+ const CTxMemPool& tx_pool,
2198
+ size_t max_coins_cache_size_bytes,
2199
+ size_t max_mempool_size_bytes)
2200
+ {
2201
+ int64_t nMempoolUsage = tx_pool.DynamicMemoryUsage ();
2202
+ int64_t cacheSize = CoinsTip ().DynamicMemoryUsage ();
2203
+ int64_t nTotalSpace =
2204
+ max_coins_cache_size_bytes + std::max<int64_t >(max_mempool_size_bytes - nMempoolUsage, 0 );
2205
+
2206
+ // ! No need to periodic flush if at least this much space still available.
2207
+ static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024 ; // 10MB
2208
+ int64_t large_threshold =
2209
+ std::max ((9 * nTotalSpace) / 10 , nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2210
+
2211
+ if (cacheSize > nTotalSpace) {
2212
+ LogPrintf (" Cache size (%s) exceeds total space (%s)\n " , cacheSize, nTotalSpace);
2213
+ return CoinsCacheSizeState::CRITICAL;
2214
+ } else if (cacheSize > large_threshold) {
2215
+ return CoinsCacheSizeState::LARGE;
2216
+ }
2217
+ return CoinsCacheSizeState::OK;
2218
+ }
2219
+
2188
2220
bool CChainState::FlushStateToDisk (
2189
2221
const CChainParams& chainparams,
2190
2222
BlockValidationState &state,
2191
2223
FlushStateMode mode,
2192
2224
int nManualPruneHeight)
2193
2225
{
2194
- int64_t nMempoolUsage = mempool.DynamicMemoryUsage ();
2195
2226
LOCK (cs_main);
2196
2227
assert (this ->CanFlushToDisk ());
2197
2228
static int64_t nLastWrite = 0 ;
@@ -2206,6 +2237,7 @@ bool CChainState::FlushStateToDisk(
2206
2237
{
2207
2238
bool fFlushForPrune = false ;
2208
2239
bool fDoFullFlush = false ;
2240
+ CoinsCacheSizeState cache_state = GetCoinsCacheSizeState (::mempool);
2209
2241
LOCK (cs_LastBlockFile);
2210
2242
if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0 ) && !fReindex ) {
2211
2243
if (nManualPruneHeight > 0 ) {
@@ -2234,13 +2266,10 @@ bool CChainState::FlushStateToDisk(
2234
2266
if (nLastFlush == 0 ) {
2235
2267
nLastFlush = nNow;
2236
2268
}
2237
- int64_t nMempoolSizeMax = gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ;
2238
- int64_t cacheSize = CoinsTip ().DynamicMemoryUsage ();
2239
- int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t >(nMempoolSizeMax - nMempoolUsage, 0 );
2240
2269
// 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).
2241
- bool fCacheLarge = mode == FlushStateMode::PERIODIC && cacheSize > std::max (( 9 * nTotalSpace) / 10 , nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024 ) ;
2270
+ bool fCacheLarge = mode == FlushStateMode::PERIODIC && cache_state >= CoinsCacheSizeState::LARGE ;
2242
2271
// The cache is over the limit, we have to write now.
2243
- bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cacheSize > nTotalSpace ;
2272
+ bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL ;
2244
2273
// 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.
2245
2274
bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow > nLastWrite + (int64_t )DATABASE_WRITE_INTERVAL * 1000000 ;
2246
2275
// It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
0 commit comments