* Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target. * The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex * (which in this case means the blockc
| 3959 | * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned |
| 3960 | */ |
| 3961 | static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight) |
| 3962 | { |
| 3963 | LOCK2(cs_main, cs_LastBlockFile); |
| 3964 | if (chainActive.Tip() == nullptr || nPruneTarget == 0) { |
| 3965 | return; |
| 3966 | } |
| 3967 | if ((uint64_t)chainActive.Tip()->nHeight <= nPruneAfterHeight) { |
| 3968 | return; |
| 3969 | } |
| 3970 | |
| 3971 | unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP; |
| 3972 | uint64_t nCurrentUsage = CalculateCurrentUsage(); |
| 3973 | // We don't check to prune until after we've allocated new space for files |
| 3974 | // So we should leave a buffer under our target to account for another allocation |
| 3975 | // before the next pruning. |
| 3976 | uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE; |
| 3977 | uint64_t nBytesToPrune; |
| 3978 | int count=0; |
| 3979 | |
| 3980 | if (nCurrentUsage + nBuffer >= nPruneTarget) { |
| 3981 | // On a prune event, the chainstate DB is flushed. |
| 3982 | // To avoid excessive prune events negating the benefit of high dbcache |
| 3983 | // values, we should not prune too rapidly. |
| 3984 | // So when pruning in IBD, increase the buffer a bit to avoid a re-prune too soon. |
| 3985 | if (IsInitialBlockDownload()) { |
| 3986 | // Since this is only relevant during IBD, we use a fixed 10% |
| 3987 | nBuffer += nPruneTarget / 10; |
| 3988 | } |
| 3989 | |
| 3990 | for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { |
| 3991 | nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize; |
| 3992 | |
| 3993 | if (vinfoBlockFile[fileNumber].nSize == 0) |
| 3994 | continue; |
| 3995 | |
| 3996 | if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target? |
| 3997 | break; |
| 3998 | |
| 3999 | // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning |
| 4000 | if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) |
| 4001 | continue; |
| 4002 | |
| 4003 | PruneOneBlockFile(fileNumber); |
| 4004 | // Queue up the files for removal |
| 4005 | setFilesToPrune.insert(fileNumber); |
| 4006 | nCurrentUsage -= nBytesToPrune; |
| 4007 | count++; |
| 4008 | } |
| 4009 | } |
| 4010 | |
| 4011 | LogPrint(BCLog::PRUNE, "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n", |
| 4012 | nPruneTarget/1024/1024, nCurrentUsage/1024/1024, |
| 4013 | ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024, |
| 4014 | nLastBlockWeCanPrune, count); |
| 4015 | } |
| 4016 | |
| 4017 | bool CheckDiskSpace(uint64_t nAdditionalBytes, bool blocks_dir) |
| 4018 | { |
no test coverage detected