aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
authorJames O'Beirne <james.obeirne@gmail.com>2019-09-16 15:01:12 -0400
committerJames O'Beirne <james.obeirne@pm.me>2020-07-01 14:44:28 -0400
commitf36aaa6392fdbdac6891d92202d3efeff98754f4 (patch)
tree4cebab3fa566f6f9dc53228b92264f1cda6095b1 /src/validation.cpp
parentb223111da2e0e9ceccef75df8a20252b0094b7bc (diff)
downloadbitcoin-f36aaa6392fdbdac6891d92202d3efeff98754f4.tar.xz
Add CChainState::ResizeCoinsCaches
Also adds CCoinsViewCache::ReallocateCache() to attempt to free memory that the cacheCoins's allocator may be hanging onto when downsizing the cache. Adds `CChainState::m_coins{tip,db}_cache_size_bytes` data members so that we can reference cache size on a per-chainstate basis for flushing.
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index dbdf5028fd..1d7d85b751 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -135,7 +135,6 @@ bool fPruneMode = false;
bool fRequireStandard = true;
bool fCheckBlockIndex = false;
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
-size_t nCoinCacheUsage = 5000 * 300;
uint64_t nPruneTarget = 0;
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
@@ -1279,9 +1278,10 @@ void CChainState::InitCoinsDB(
leveldb_name, cache_size_bytes, in_memory, should_wipe);
}
-void CChainState::InitCoinsCache()
+void CChainState::InitCoinsCache(size_t cache_size_bytes)
{
assert(m_coins_views != nullptr);
+ m_coinstip_cache_size_bytes = cache_size_bytes;
m_coins_views->InitCache();
}
@@ -2228,7 +2228,7 @@ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(const CTxMemPool& tx_poo
{
return this->GetCoinsCacheSizeState(
tx_pool,
- nCoinCacheUsage,
+ m_coinstip_cache_size_bytes,
gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
}
@@ -4300,7 +4300,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
}
}
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
- if (nCheckLevel >= 3 && (coins.DynamicMemoryUsage() + ::ChainstateActive().CoinsTip().DynamicMemoryUsage()) <= nCoinCacheUsage) {
+ if (nCheckLevel >= 3 && (coins.DynamicMemoryUsage() + ::ChainstateActive().CoinsTip().DynamicMemoryUsage()) <= ::ChainstateActive().m_coinstip_cache_size_bytes) {
assert(coins.GetBestBlock() == pindex->GetBlockHash());
DisconnectResult res = ::ChainstateActive().DisconnectBlock(block, pindex, coins);
if (res == DISCONNECT_FAILED) {
@@ -4965,6 +4965,39 @@ std::string CChainState::ToString()
tip ? tip->nHeight : -1, tip ? tip->GetBlockHash().ToString() : "null");
}
+bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
+{
+ if (coinstip_size == m_coinstip_cache_size_bytes &&
+ coinsdb_size == m_coinsdb_cache_size_bytes) {
+ // Cache sizes are unchanged, no need to continue.
+ return true;
+ }
+ size_t old_coinstip_size = m_coinstip_cache_size_bytes;
+ m_coinstip_cache_size_bytes = coinstip_size;
+ m_coinsdb_cache_size_bytes = coinsdb_size;
+ CoinsDB().ResizeCache(coinsdb_size);
+
+ LogPrintf("[%s] resized coinsdb cache to %.1f MiB\n",
+ this->ToString(), coinsdb_size * (1.0 / 1024 / 1024));
+ LogPrintf("[%s] resized coinstip cache to %.1f MiB\n",
+ this->ToString(), coinstip_size * (1.0 / 1024 / 1024));
+
+ BlockValidationState state;
+ const CChainParams& chainparams = Params();
+
+ bool ret;
+
+ if (coinstip_size > old_coinstip_size) {
+ // Likely no need to flush if cache sizes have grown.
+ ret = FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED);
+ } else {
+ // Otherwise, flush state to disk and deallocate the in-memory coins map.
+ ret = FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS);
+ CoinsTip().ReallocateCache();
+ }
+ return ret;
+}
+
std::string CBlockFileInfo::ToString() const
{
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));