Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,023 Lines • ▼ Show 20 Lines | try { | ||||
mode == FlushStateMode::PERIODIC && | mode == FlushStateMode::PERIODIC && | ||||
nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; | nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; | ||||
// Combine all conditions that result in a full cache flush. | // Combine all conditions that result in a full cache flush. | ||||
fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || | fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || | ||||
fCacheCritical || fPeriodicFlush || fFlushForPrune; | fCacheCritical || fPeriodicFlush || fFlushForPrune; | ||||
// Write blocks and block index to disk. | // Write blocks and block index to disk. | ||||
if (fDoFullFlush || fPeriodicWrite) { | if (fDoFullFlush || fPeriodicWrite) { | ||||
// Depend on nMinDiskSpace to ensure we can write block index | // Depend on nMinDiskSpace to ensure we can write block index | ||||
if (!CheckDiskSpace(0, true)) { | if (!CheckDiskSpace(GetBlocksDir())) { | ||||
return state.Error("out of disk space"); | return AbortNode(state, "Disk space is low!", | ||||
_("Error: Disk space is low!")); | |||||
} | } | ||||
// First make sure all block and undo data is flushed to disk. | // First make sure all block and undo data is flushed to disk. | ||||
FlushBlockFile(); | FlushBlockFile(); | ||||
// Then update all block file information (which may refer to | // Then update all block file information (which may refer to | ||||
// block and undo files). | // block and undo files). | ||||
{ | { | ||||
std::vector<std::pair<int, const CBlockFileInfo *>> vFiles; | std::vector<std::pair<int, const CBlockFileInfo *>> vFiles; | ||||
Show All 29 Lines | try { | ||||
// blocks / block index write was also done. | // blocks / block index write was also done. | ||||
if (fDoFullFlush && !pcoinsTip->GetBestBlock().IsNull()) { | if (fDoFullFlush && !pcoinsTip->GetBestBlock().IsNull()) { | ||||
// Typical Coin structures on disk are around 48 bytes in size. | // Typical Coin structures on disk are around 48 bytes in size. | ||||
// Pushing a new one to the database can cause it to be written | // Pushing a new one to the database can cause it to be written | ||||
// twice (once in the log, and once in the tables). This is | // twice (once in the log, and once in the tables). This is | ||||
// already an overestimation, as most will delete an existing | // already an overestimation, as most will delete an existing | ||||
// entry or overwrite one. Still, use a conservative safety | // entry or overwrite one. Still, use a conservative safety | ||||
// factor of 2. | // factor of 2. | ||||
if (!CheckDiskSpace(48 * 2 * 2 * pcoinsTip->GetCacheSize())) { | if (!CheckDiskSpace(GetDataDir(), | ||||
return state.Error("out of disk space"); | 48 * 2 * 2 * pcoinsTip->GetCacheSize())) { | ||||
return AbortNode(state, "Disk space is low!", | |||||
_("Error: Disk space is low!")); | |||||
} | } | ||||
// Flush the chainstate (which may refer to block index | // Flush the chainstate (which may refer to block index | ||||
// entries). | // entries). | ||||
if (!pcoinsTip->Flush()) { | if (!pcoinsTip->Flush()) { | ||||
return AbortNode(state, "Failed to write to coin database"); | return AbortNode(state, "Failed to write to coin database"); | ||||
} | } | ||||
nLastFlush = nNow; | nLastFlush = nNow; | ||||
▲ Show 20 Lines • Show All 1,250 Lines • ▼ Show 20 Lines | if (!fKnown) { | ||||
unsigned int nNewChunks = | unsigned int nNewChunks = | ||||
(vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / | (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / | ||||
BLOCKFILE_CHUNK_SIZE; | BLOCKFILE_CHUNK_SIZE; | ||||
if (nNewChunks > nOldChunks) { | if (nNewChunks > nOldChunks) { | ||||
if (fPruneMode) { | if (fPruneMode) { | ||||
fCheckForPruning = true; | fCheckForPruning = true; | ||||
} | } | ||||
if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos, | if (CheckDiskSpace(GetBlocksDir(), | ||||
true)) { | nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { | ||||
FILE *file = OpenBlockFile(pos); | FILE *file = OpenBlockFile(pos); | ||||
if (file) { | if (file) { | ||||
LogPrintf( | LogPrintf( | ||||
"Pre-allocating up to position 0x%x in blk%05u.dat\n", | "Pre-allocating up to position 0x%x in blk%05u.dat\n", | ||||
nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); | nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); | ||||
AllocateFileRange(file, pos.nPos, | AllocateFileRange(file, pos.nPos, | ||||
nNewChunks * BLOCKFILE_CHUNK_SIZE - | nNewChunks * BLOCKFILE_CHUNK_SIZE - | ||||
pos.nPos); | pos.nPos); | ||||
fclose(file); | fclose(file); | ||||
} | } | ||||
} else { | } else { | ||||
return error("out of disk space"); | return AbortNode("Disk space is low!", | ||||
_("Error: Disk space is low!")); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
setDirtyFileInfo.insert(nFile); | setDirtyFileInfo.insert(nFile); | ||||
return true; | return true; | ||||
} | } | ||||
Show All 12 Lines | unsigned int nOldChunks = | ||||
(pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; | (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; | ||||
unsigned int nNewChunks = | unsigned int nNewChunks = | ||||
(nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; | (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; | ||||
if (nNewChunks > nOldChunks) { | if (nNewChunks > nOldChunks) { | ||||
if (fPruneMode) { | if (fPruneMode) { | ||||
fCheckForPruning = true; | fCheckForPruning = true; | ||||
} | } | ||||
if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos, true)) { | if (CheckDiskSpace(GetBlocksDir(), | ||||
nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) { | |||||
FILE *file = OpenUndoFile(pos); | FILE *file = OpenUndoFile(pos); | ||||
if (file) { | if (file) { | ||||
LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", | LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", | ||||
nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile); | nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile); | ||||
AllocateFileRange(file, pos.nPos, | AllocateFileRange(file, pos.nPos, | ||||
nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos); | nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos); | ||||
fclose(file); | fclose(file); | ||||
} | } | ||||
} else { | } else { | ||||
return state.Error("out of disk space"); | return AbortNode(state, "Disk space is low!", | ||||
_("Error: Disk space is low!")); | |||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Return true if the provided block header is valid. | * Return true if the provided block header is valid. | ||||
▲ Show 20 Lines • Show All 894 Lines • ▼ Show 20 Lines | static void FindFilesToPrune(std::set<int> &setFilesToPrune, | ||||
LogPrint(BCLog::PRUNE, | LogPrint(BCLog::PRUNE, | ||||
"Prune: target=%dMiB actual=%dMiB diff=%dMiB " | "Prune: target=%dMiB actual=%dMiB diff=%dMiB " | ||||
"max_prune_height=%d removed %d blk/rev pairs\n", | "max_prune_height=%d removed %d blk/rev pairs\n", | ||||
nPruneTarget / 1024 / 1024, nCurrentUsage / 1024 / 1024, | nPruneTarget / 1024 / 1024, nCurrentUsage / 1024 / 1024, | ||||
((int64_t)nPruneTarget - (int64_t)nCurrentUsage) / 1024 / 1024, | ((int64_t)nPruneTarget - (int64_t)nCurrentUsage) / 1024 / 1024, | ||||
nLastBlockWeCanPrune, count); | nLastBlockWeCanPrune, count); | ||||
} | } | ||||
bool CheckDiskSpace(uint64_t nAdditionalBytes, bool blocks_dir) { | |||||
uint64_t nFreeBytesAvailable = | |||||
fs::space(blocks_dir ? GetBlocksDir() : GetDataDir()).available; | |||||
// Check for nMinDiskSpace bytes (currently 50MB) | |||||
if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) { | |||||
return AbortNode("Disk space is low!", _("Error: Disk space is low!")); | |||||
} | |||||
return true; | |||||
} | |||||
static FILE *OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, | static FILE *OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, | ||||
bool fReadOnly) { | bool fReadOnly) { | ||||
if (pos.IsNull()) { | if (pos.IsNull()) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
fs::path path = GetBlockPosFilename(pos, prefix); | fs::path path = GetBlockPosFilename(pos, prefix); | ||||
fs::create_directories(path.parent_path()); | fs::create_directories(path.parent_path()); | ||||
▲ Show 20 Lines • Show All 1,357 Lines • Show Last 20 Lines |