| 2489 | } |
| 2490 | |
| 2491 | bool CChainState::FlushStateToDisk( |
| 2492 | BlockValidationState &state, |
| 2493 | FlushStateMode mode, |
| 2494 | int nManualPruneHeight) |
| 2495 | { |
| 2496 | LOCK(cs_main); |
| 2497 | assert(this->CanFlushToDisk()); |
| 2498 | static std::chrono::microseconds nLastWrite{0}; |
| 2499 | static std::chrono::microseconds nLastFlush{0}; |
| 2500 | std::set<int> setFilesToPrune; |
| 2501 | bool full_flush_completed = false; |
| 2502 | |
| 2503 | const size_t coins_count = CoinsTip().GetCacheSize(); |
| 2504 | const size_t coins_mem_usage = CoinsTip().DynamicMemoryUsage(); |
| 2505 | |
| 2506 | try { |
| 2507 | { |
| 2508 | bool fFlushForPrune = false; |
| 2509 | bool fDoFullFlush = false; |
| 2510 | |
| 2511 | CoinsCacheSizeState cache_state = GetCoinsCacheSizeState(); |
| 2512 | LOCK(m_blockman.cs_LastBlockFile); |
| 2513 | if (fPruneMode && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !fReindex) { |
| 2514 | // make sure we don't prune above the blockfilterindexes bestblocks |
| 2515 | // pruning is height-based |
| 2516 | int last_prune = m_chain.Height(); // last height we can prune |
| 2517 | ForEachBlockFilterIndex([&](BlockFilterIndex& index) { |
| 2518 | last_prune = std::max(1, std::min(last_prune, index.GetSummary().best_block_height)); |
| 2519 | }); |
| 2520 | |
| 2521 | if (nManualPruneHeight > 0) { |
| 2522 | LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune (manual)", BCLog::BENCH); |
| 2523 | |
| 2524 | m_blockman.FindFilesToPruneManual(setFilesToPrune, std::min(last_prune, nManualPruneHeight), m_chain.Height()); |
| 2525 | } else { |
| 2526 | LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH); |
| 2527 | |
| 2528 | m_blockman.FindFilesToPrune(setFilesToPrune, m_params.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload()); |
| 2529 | m_blockman.m_check_for_pruning = false; |
| 2530 | } |
| 2531 | if (!setFilesToPrune.empty()) { |
| 2532 | fFlushForPrune = true; |
| 2533 | if (!fHavePruned) { |
| 2534 | m_blockman.m_block_tree_db->WriteFlag("prunedblockfiles", true); |
| 2535 | fHavePruned = true; |
| 2536 | } |
| 2537 | } |
| 2538 | } |
| 2539 | const auto nNow = GetTime<std::chrono::microseconds>(); |
| 2540 | // Avoid writing/flushing immediately after startup. |
| 2541 | if (nLastWrite.count() == 0) { |
| 2542 | nLastWrite = nNow; |
| 2543 | } |
| 2544 | if (nLastFlush.count() == 0) { |
| 2545 | nLastFlush = nNow; |
| 2546 | } |
| 2547 | // 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). |
| 2548 | bool fCacheLarge = mode == FlushStateMode::PERIODIC && cache_state >= CoinsCacheSizeState::LARGE; |
no test coverage detected