* Update the on-disk chain state. * The caches and indexes are flushed depending on the mode we're called with * if they're too large, if it's been a while since the last write, * or always and in all cases if we're in prune mode and are deleting files. * * If FlushStateMode::NONE is used, then FlushStateToDisk(...) won't do anything * besides checking if we need to prune. */
| 2143 | * besides checking if we need to prune. |
| 2144 | */ |
| 2145 | bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight) { |
| 2146 | int64_t nMempoolUsage = mempool.DynamicMemoryUsage(); |
| 2147 | LOCK(cs_main); |
| 2148 | static int64_t nLastWrite = 0; |
| 2149 | static int64_t nLastFlush = 0; |
| 2150 | std::set<int> setFilesToPrune; |
| 2151 | bool full_flush_completed = false; |
| 2152 | try { |
| 2153 | { |
| 2154 | bool fFlushForPrune = false; |
| 2155 | bool fDoFullFlush = false; |
| 2156 | LOCK(cs_LastBlockFile); |
| 2157 | if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) && !fReindex) { |
| 2158 | if (nManualPruneHeight > 0) { |
| 2159 | FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight); |
| 2160 | } else { |
| 2161 | FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); |
| 2162 | fCheckForPruning = false; |
| 2163 | } |
| 2164 | if (!setFilesToPrune.empty()) { |
| 2165 | fFlushForPrune = true; |
| 2166 | if (!fHavePruned) { |
| 2167 | pblocktree->WriteFlag("prunedblockfiles", true); |
| 2168 | fHavePruned = true; |
| 2169 | } |
| 2170 | } |
| 2171 | } |
| 2172 | int64_t nNow = GetTimeMicros(); |
| 2173 | // Avoid writing/flushing immediately after startup. |
| 2174 | if (nLastWrite == 0) { |
| 2175 | nLastWrite = nNow; |
| 2176 | } |
| 2177 | if (nLastFlush == 0) { |
| 2178 | nLastFlush = nNow; |
| 2179 | } |
| 2180 | int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; |
| 2181 | int64_t cacheSize = pcoinsTip->DynamicMemoryUsage(); |
| 2182 | int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0); |
| 2183 | // 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). |
| 2184 | bool fCacheLarge = mode == FlushStateMode::PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024); |
| 2185 | // The cache is over the limit, we have to write now. |
| 2186 | bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cacheSize > nTotalSpace; |
| 2187 | // 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. |
| 2188 | bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; |
| 2189 | // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage. |
| 2190 | bool fPeriodicFlush = mode == FlushStateMode::PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; |
| 2191 | // Combine all conditions that result in a full cache flush. |
| 2192 | fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune; |
| 2193 | // Write blocks and block index to disk. |
| 2194 | if (fDoFullFlush || fPeriodicWrite) { |
| 2195 | // Depend on nMinDiskSpace to ensure we can write block index |
| 2196 | if (!CheckDiskSpace(0, true)) |
| 2197 | return state.Error("out of disk space"); |
| 2198 | // First make sure all block and undo data is flushed to disk. |
| 2199 | FlushBlockFile(); |
| 2200 | // Then update all block file information (which may refer to block and undo files). |
| 2201 | { |
| 2202 | std::vector<std::pair<int, const CBlockFileInfo*> > vFiles; |
no test coverage detected