Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,260 Lines • ▼ Show 20 Lines | |||||
/** Abort with a message */ | /** Abort with a message */ | ||||
static bool AbortNode(const std::string &strMessage, | static bool AbortNode(const std::string &strMessage, | ||||
const std::string &userMessage = "") { | const std::string &userMessage = "") { | ||||
SetMiscWarning(strMessage); | SetMiscWarning(strMessage); | ||||
LogPrintf("*** %s\n", strMessage); | LogPrintf("*** %s\n", strMessage); | ||||
uiInterface.ThreadSafeMessageBox( | uiInterface.ThreadSafeMessageBox( | ||||
userMessage.empty() ? _("Error: A fatal internal error occurred, see " | userMessage.empty() ? _("Error: A fatal internal error occurred, see " | ||||
"debug.log for details") | "debug.log for details") | ||||
.translated | |||||
: userMessage, | : userMessage, | ||||
"", CClientUIInterface::MSG_ERROR); | "", CClientUIInterface::MSG_ERROR); | ||||
StartShutdown(); | StartShutdown(); | ||||
return false; | return false; | ||||
} | } | ||||
static bool AbortNode(CValidationState &state, const std::string &strMessage, | static bool AbortNode(CValidationState &state, const std::string &strMessage, | ||||
const std::string &userMessage = "") { | const std::string &userMessage = "") { | ||||
▲ Show 20 Lines • Show All 739 Lines • ▼ Show 20 Lines | try { | ||||
// 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(GetBlocksDir())) { | if (!CheckDiskSpace(GetBlocksDir())) { | ||||
return AbortNode(state, "Disk space is low!", | return AbortNode(state, "Disk space is low!", | ||||
_("Error: Disk space is low!")); | _("Error: Disk space is low!").translated); | ||||
} | } | ||||
// 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 32 Lines | try { | ||||
// 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(GetDataDir(), | if (!CheckDiskSpace(GetDataDir(), | ||||
48 * 2 * 2 * pcoinsTip->GetCacheSize())) { | 48 * 2 * 2 * pcoinsTip->GetCacheSize())) { | ||||
return AbortNode(state, "Disk space is low!", | return AbortNode(state, "Disk space is low!", | ||||
_("Error: Disk space is low!")); | _("Error: Disk space is low!").translated); | ||||
} | } | ||||
// 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,340 Lines • ▼ Show 20 Lines | static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, | ||||
} | } | ||||
if (!fKnown) { | if (!fKnown) { | ||||
bool out_of_space; | bool out_of_space; | ||||
size_t bytes_allocated = | size_t bytes_allocated = | ||||
BlockFileSeq().Allocate(pos, nAddSize, out_of_space); | BlockFileSeq().Allocate(pos, nAddSize, out_of_space); | ||||
if (out_of_space) { | if (out_of_space) { | ||||
return AbortNode("Disk space is low!", | return AbortNode("Disk space is low!", | ||||
_("Error: Disk space is low!")); | _("Error: Disk space is low!").translated); | ||||
} | } | ||||
if (bytes_allocated != 0 && fPruneMode) { | if (bytes_allocated != 0 && fPruneMode) { | ||||
fCheckForPruning = true; | fCheckForPruning = true; | ||||
} | } | ||||
} | } | ||||
setDirtyFileInfo.insert(nFile); | setDirtyFileInfo.insert(nFile); | ||||
return true; | return true; | ||||
Show All 9 Lines | static bool FindUndoPos(CValidationState &state, int nFile, FlatFilePos &pos, | ||||
vinfoBlockFile[nFile].nUndoSize += nAddSize; | vinfoBlockFile[nFile].nUndoSize += nAddSize; | ||||
setDirtyFileInfo.insert(nFile); | setDirtyFileInfo.insert(nFile); | ||||
bool out_of_space; | bool out_of_space; | ||||
size_t bytes_allocated = | size_t bytes_allocated = | ||||
UndoFileSeq().Allocate(pos, nAddSize, out_of_space); | UndoFileSeq().Allocate(pos, nAddSize, out_of_space); | ||||
if (out_of_space) { | if (out_of_space) { | ||||
return AbortNode(state, "Disk space is low!", | return AbortNode(state, "Disk space is low!", | ||||
_("Error: Disk space is low!")); | _("Error: Disk space is low!").translated); | ||||
} | } | ||||
if (bytes_allocated != 0 && fPruneMode) { | if (bytes_allocated != 0 && fPruneMode) { | ||||
fCheckForPruning = true; | fCheckForPruning = true; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,161 Lines • ▼ Show 20 Lines | LogPrintf( | ||||
::ChainActive().Height(), | ::ChainActive().Height(), | ||||
FormatISO8601DateTime(::ChainActive().Tip()->GetBlockTime()), | FormatISO8601DateTime(::ChainActive().Tip()->GetBlockTime()), | ||||
GuessVerificationProgress(config.GetChainParams().TxData(), | GuessVerificationProgress(config.GetChainParams().TxData(), | ||||
::ChainActive().Tip())); | ::ChainActive().Tip())); | ||||
return true; | return true; | ||||
} | } | ||||
CVerifyDB::CVerifyDB() { | CVerifyDB::CVerifyDB() { | ||||
uiInterface.ShowProgress(_("Verifying blocks..."), 0, false); | uiInterface.ShowProgress(_("Verifying blocks...").translated, 0, false); | ||||
} | } | ||||
CVerifyDB::~CVerifyDB() { | CVerifyDB::~CVerifyDB() { | ||||
uiInterface.ShowProgress("", 100, false); | uiInterface.ShowProgress("", 100, false); | ||||
} | } | ||||
bool CVerifyDB::VerifyDB(const Config &config, CCoinsView *coinsview, | bool CVerifyDB::VerifyDB(const Config &config, CCoinsView *coinsview, | ||||
int nCheckLevel, int nCheckDepth) { | int nCheckLevel, int nCheckDepth) { | ||||
Show All 33 Lines | for (pindex = ::ChainActive().Tip(); pindex && pindex->pprev; | ||||
(nCheckLevel >= 4 ? 50 : 100)))); | (nCheckLevel >= 4 ? 50 : 100)))); | ||||
if (reportDone < percentageDone / 10) { | if (reportDone < percentageDone / 10) { | ||||
// report every 10% step | // report every 10% step | ||||
LogPrintfToBeContinued("[%d%%]...", percentageDone); | LogPrintfToBeContinued("[%d%%]...", percentageDone); | ||||
reportDone = percentageDone / 10; | reportDone = percentageDone / 10; | ||||
} | } | ||||
uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone, | uiInterface.ShowProgress(_("Verifying blocks...").translated, | ||||
false); | percentageDone, false); | ||||
if (pindex->nHeight <= ::ChainActive().Height() - nCheckDepth) { | if (pindex->nHeight <= ::ChainActive().Height() - nCheckDepth) { | ||||
break; | break; | ||||
} | } | ||||
if (fPruneMode && !pindex->nStatus.hasData()) { | if (fPruneMode && !pindex->nStatus.hasData()) { | ||||
// If pruning, only go back as far as we have data. | // If pruning, only go back as far as we have data. | ||||
LogPrintf("VerifyDB(): block verification stopping at height %d " | LogPrintf("VerifyDB(): block verification stopping at height %d " | ||||
"(pruning, no data)\n", | "(pruning, no data)\n", | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | bool CVerifyDB::VerifyDB(const Config &config, CCoinsView *coinsview, | ||||
// store block count as we move pindex at check level >= 4 | // store block count as we move pindex at check level >= 4 | ||||
int block_count = ::ChainActive().Height() - pindex->nHeight; | int block_count = ::ChainActive().Height() - pindex->nHeight; | ||||
// check level 4: try reconnecting blocks | // check level 4: try reconnecting blocks | ||||
if (nCheckLevel >= 4) { | if (nCheckLevel >= 4) { | ||||
while (pindex != ::ChainActive().Tip()) { | while (pindex != ::ChainActive().Tip()) { | ||||
boost::this_thread::interruption_point(); | boost::this_thread::interruption_point(); | ||||
uiInterface.ShowProgress( | uiInterface.ShowProgress( | ||||
_("Verifying blocks..."), | _("Verifying blocks...").translated, | ||||
std::max( | std::max( | ||||
1, std::min(99, | 1, std::min(99, | ||||
100 - (int)(((double)(::ChainActive().Height() - | 100 - (int)(((double)(::ChainActive().Height() - | ||||
pindex->nHeight)) / | pindex->nHeight)) / | ||||
(double)nCheckDepth * 50))), | (double)nCheckDepth * 50))), | ||||
false); | false); | ||||
pindex = ::ChainActive().Next(pindex); | pindex = ::ChainActive().Next(pindex); | ||||
CBlock block; | CBlock block; | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | if (hashHeads.empty()) { | ||||
// We're already in a consistent state. | // We're already in a consistent state. | ||||
return true; | return true; | ||||
} | } | ||||
if (hashHeads.size() != 2) { | if (hashHeads.size() != 2) { | ||||
return error("ReplayBlocks(): unknown inconsistent state"); | return error("ReplayBlocks(): unknown inconsistent state"); | ||||
} | } | ||||
uiInterface.ShowProgress(_("Replaying blocks..."), 0, false); | uiInterface.ShowProgress(_("Replaying blocks...").translated, 0, false); | ||||
LogPrintf("Replaying blocks\n"); | LogPrintf("Replaying blocks\n"); | ||||
// Old tip during the interrupted flush. | // Old tip during the interrupted flush. | ||||
const CBlockIndex *pindexOld = nullptr; | const CBlockIndex *pindexOld = nullptr; | ||||
// New tip during the interrupted flush. | // New tip during the interrupted flush. | ||||
const CBlockIndex *pindexNew; | const CBlockIndex *pindexNew; | ||||
// Latest block common to both the old and the new tip. | // Latest block common to both the old and the new tip. | ||||
const CBlockIndex *pindexFork = nullptr; | const CBlockIndex *pindexFork = nullptr; | ||||
▲ Show 20 Lines • Show All 877 Lines • Show Last 20 Lines |