|
|
@ -3840,12 +3840,14 @@ bool CVerifyDB::VerifyDB(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
|
|
|
|
|
|
|
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr)
|
|
|
|
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr) {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Verify blocks in the best chain
|
|
|
|
// Verify blocks in the best chain
|
|
|
|
if (nCheckDepth <= 0 || nCheckDepth > chainstate.m_chain.Height())
|
|
|
|
if (nCheckDepth <= 0 || nCheckDepth > chainstate.m_chain.Height()) {
|
|
|
|
nCheckDepth = chainstate.m_chain.Height();
|
|
|
|
nCheckDepth = chainstate.m_chain.Height();
|
|
|
|
|
|
|
|
}
|
|
|
|
nCheckLevel = std::max(0, std::min(4, nCheckLevel));
|
|
|
|
nCheckLevel = std::max(0, std::min(4, nCheckLevel));
|
|
|
|
LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
|
|
|
|
LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
|
|
|
|
CCoinsViewCache coins(&coinsview);
|
|
|
|
CCoinsViewCache coins(&coinsview);
|
|
|
@ -3860,14 +3862,15 @@ bool CVerifyDB::VerifyDB(
|
|
|
|
|
|
|
|
|
|
|
|
for (pindex = chainstate.m_chain.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
|
|
|
|
for (pindex = chainstate.m_chain.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
|
|
|
|
const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
|
|
|
|
const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
|
|
|
|
if (reportDone < percentageDone/10) {
|
|
|
|
if (reportDone < percentageDone / 10) {
|
|
|
|
// report every 10% step
|
|
|
|
// report every 10% step
|
|
|
|
LogPrintf("[%d%%]...", percentageDone); /* Continued */
|
|
|
|
LogPrintf("[%d%%]...", percentageDone); /* Continued */
|
|
|
|
reportDone = percentageDone/10;
|
|
|
|
reportDone = percentageDone / 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
|
|
|
|
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
|
|
|
|
if (pindex->nHeight <= chainstate.m_chain.Height()-nCheckDepth)
|
|
|
|
if (pindex->nHeight <= chainstate.m_chain.Height() - nCheckDepth) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
if ((fPruneMode || is_snapshot_cs) && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
|
|
|
|
if ((fPruneMode || is_snapshot_cs) && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
|
|
|
|
// If pruning or running under an assumeutxo snapshot, only go
|
|
|
|
// If pruning or running under an assumeutxo snapshot, only go
|
|
|
|
// back as far as we have data.
|
|
|
|
// back as far as we have data.
|
|
|
@ -3876,12 +3879,14 @@ bool CVerifyDB::VerifyDB(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CBlock block;
|
|
|
|
CBlock block;
|
|
|
|
// check level 0: read from disk
|
|
|
|
// check level 0: read from disk
|
|
|
|
if (!ReadBlockFromDisk(block, pindex, consensus_params))
|
|
|
|
if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
|
|
|
|
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
|
|
|
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
|
|
|
|
|
|
|
}
|
|
|
|
// check level 1: verify block validity
|
|
|
|
// check level 1: verify block validity
|
|
|
|
if (nCheckLevel >= 1 && !CheckBlock(block, state, consensus_params))
|
|
|
|
if (nCheckLevel >= 1 && !CheckBlock(block, state, consensus_params)) {
|
|
|
|
return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
|
|
|
|
return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
|
|
|
|
pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
|
|
|
|
pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
|
|
|
|
|
|
|
|
}
|
|
|
|
// check level 2: verify undo validity
|
|
|
|
// check level 2: verify undo validity
|
|
|
|
if (nCheckLevel >= 2 && pindex) {
|
|
|
|
if (nCheckLevel >= 2 && pindex) {
|
|
|
|
CBlockUndo undo;
|
|
|
|
CBlockUndo undo;
|
|
|
@ -3909,8 +3914,9 @@ bool CVerifyDB::VerifyDB(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ShutdownRequested()) return true;
|
|
|
|
if (ShutdownRequested()) return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pindexFailure)
|
|
|
|
if (pindexFailure) {
|
|
|
|
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
|
|
|
|
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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 = chainstate.m_chain.Height() - pindex->nHeight;
|
|
|
|
int block_count = chainstate.m_chain.Height() - pindex->nHeight;
|
|
|
@ -3919,10 +3925,10 @@ bool CVerifyDB::VerifyDB(
|
|
|
|
if (nCheckLevel >= 4) {
|
|
|
|
if (nCheckLevel >= 4) {
|
|
|
|
while (pindex != chainstate.m_chain.Tip()) {
|
|
|
|
while (pindex != chainstate.m_chain.Tip()) {
|
|
|
|
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
|
|
|
|
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
|
|
|
|
if (reportDone < percentageDone/10) {
|
|
|
|
if (reportDone < percentageDone / 10) {
|
|
|
|
// report every 10% step
|
|
|
|
// report every 10% step
|
|
|
|
LogPrintf("[%d%%]...", percentageDone); /* Continued */
|
|
|
|
LogPrintf("[%d%%]...", percentageDone); /* Continued */
|
|
|
|
reportDone = percentageDone/10;
|
|
|
|
reportDone = percentageDone / 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
|
|
|
|
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
|
|
|
|
pindex = chainstate.m_chain.Next(pindex);
|
|
|
|
pindex = chainstate.m_chain.Next(pindex);
|
|
|
|