Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 926 Lines • ▼ Show 20 Lines | bool IsInitialBlockDownload() { | ||||
if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) { | if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) { | ||||
return true; | return true; | ||||
} | } | ||||
LogPrintf("Leaving InitialBlockDownload (latching to false)\n"); | LogPrintf("Leaving InitialBlockDownload (latching to false)\n"); | ||||
latchToFalse.store(true, std::memory_order_relaxed); | latchToFalse.store(true, std::memory_order_relaxed); | ||||
return false; | return false; | ||||
} | } | ||||
CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; | CBlockIndex const *pindexBestForkTip = nullptr; | ||||
CBlockIndex const *pindexBestForkBase = nullptr; | |||||
static void AlertNotify(const std::string &strMessage) { | static void AlertNotify(const std::string &strMessage) { | ||||
uiInterface.NotifyAlertChanged(); | uiInterface.NotifyAlertChanged(); | ||||
std::string strCmd = gArgs.GetArg("-alertnotify", ""); | std::string strCmd = gArgs.GetArg("-alertnotify", ""); | ||||
if (strCmd.empty()) { | if (strCmd.empty()) { | ||||
return; | return; | ||||
} | } | ||||
Show All 35 Lines | if (pindexBestForkTip || | ||||
std::string warning = | std::string warning = | ||||
std::string("'Warning: Large-work fork detected, forking after " | std::string("'Warning: Large-work fork detected, forking after " | ||||
"block ") + | "block ") + | ||||
pindexBestForkBase->phashBlock->ToString() + std::string("'"); | pindexBestForkBase->phashBlock->ToString() + std::string("'"); | ||||
AlertNotify(warning); | AlertNotify(warning); | ||||
} | } | ||||
if (pindexBestForkTip && pindexBestForkBase) { | if (pindexBestForkTip && pindexBestForkBase) { | ||||
LogPrintf("%s: Warning: Large valid fork found\n forking the " | LogPrintf("%s: Warning: Large fork found\n forking the " | ||||
"chain at height %d (%s)\n lasting to height %d " | "chain at height %d (%s)\n lasting to height %d " | ||||
"(%s).\nChain state database corruption likely.\n", | "(%s).\nChain state database corruption likely.\n", | ||||
__func__, pindexBestForkBase->nHeight, | __func__, pindexBestForkBase->nHeight, | ||||
pindexBestForkBase->phashBlock->ToString(), | pindexBestForkBase->phashBlock->ToString(), | ||||
pindexBestForkTip->nHeight, | pindexBestForkTip->nHeight, | ||||
pindexBestForkTip->phashBlock->ToString()); | pindexBestForkTip->phashBlock->ToString()); | ||||
SetfLargeWorkForkFound(true); | SetfLargeWorkForkFound(true); | ||||
} else { | } else { | ||||
LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks " | LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks " | ||||
"longer than our best chain.\nChain state database " | "longer than our best chain.\nChain state database " | ||||
"corruption likely.\n", | "corruption likely.\n", | ||||
__func__); | __func__); | ||||
SetfLargeWorkInvalidChainFound(true); | SetfLargeWorkInvalidChainFound(true); | ||||
} | } | ||||
} else { | } else { | ||||
SetfLargeWorkForkFound(false); | SetfLargeWorkForkFound(false); | ||||
SetfLargeWorkInvalidChainFound(false); | SetfLargeWorkInvalidChainFound(false); | ||||
} | } | ||||
} | } | ||||
static void CheckForkWarningConditionsOnNewFork(CBlockIndex *pindexNewForkTip) { | static void | ||||
CheckForkWarningConditionsOnNewFork(const CBlockIndex *pindexNewForkTip) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// If we are on a fork that is sufficiently large, set a warning flag | // If we are on a fork that is sufficiently large, set a warning flag. | ||||
CBlockIndex *pfork = pindexNewForkTip; | const CBlockIndex *pfork = chainActive.FindFork(pindexNewForkTip); | ||||
CBlockIndex *plonger = chainActive.Tip(); | |||||
while (pfork && pfork != plonger) { | |||||
while (plonger && plonger->nHeight > pfork->nHeight) { | |||||
plonger = plonger->pprev; | |||||
} | |||||
if (pfork == plonger) { | |||||
break; | |||||
} | |||||
pfork = pfork->pprev; | |||||
} | |||||
// We define a condition where we should warn the user about as a fork of at | // We define a condition where we should warn the user about as a fork of at | ||||
// least 7 blocks with a tip within 72 blocks (+/- 12 hours if no one mines | // least 7 blocks with a tip within 72 blocks (+/- 12 hours if no one mines | ||||
// it) of ours. We use 7 blocks rather arbitrarily as it represents just | // it) of ours. We use 7 blocks rather arbitrarily as it represents just | ||||
// under 10% of sustained network hash rate operating on the fork, or a | // under 10% of sustained network hash rate operating on the fork, or a | ||||
// chain that is entirely longer than ours and invalid (note that this | // chain that is entirely longer than ours and invalid (note that this | ||||
// should be detected by both). We define it this way because it allows us | // should be detected by both). We define it this way because it allows us | ||||
// to only store the highest fork tip (+ base) which meets the 7-block | // to only store the highest fork tip (+ base) which meets the 7-block | ||||
▲ Show 20 Lines • Show All 1,414 Lines • ▼ Show 20 Lines | do { | ||||
} | } | ||||
setBlockIndexCandidates.erase(pindexFailed); | setBlockIndexCandidates.erase(pindexFailed); | ||||
pindexFailed = pindexFailed->pprev; | pindexFailed = pindexFailed->pprev; | ||||
} | } | ||||
if (fInvalidChain || fParkedChain) { | if (fInvalidChain || fParkedChain) { | ||||
// We discovered a new chain tip that is either parked or | // We discovered a new chain tip that is either parked or | ||||
// invalid, we may want to warn. | // invalid, we may want to warn. | ||||
CheckForkWarningConditions(); | CheckForkWarningConditionsOnNewFork(pindexNew); | ||||
} | } | ||||
} | } | ||||
// We found a candidate that has valid ancestors. This is our guy. | // We found a candidate that has valid ancestors. This is our guy. | ||||
if (hasValidAncestor) { | if (hasValidAncestor) { | ||||
return pindexNew; | return pindexNew; | ||||
} | } | ||||
} while (true); | } while (true); | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | if (fBlocksDisconnected) { | ||||
// any disconnected transactions back to the mempool. | // any disconnected transactions back to the mempool. | ||||
disconnectpool.updateMempoolForReorg(config, true); | disconnectpool.updateMempoolForReorg(config, true); | ||||
} | } | ||||
mempool.check(pcoinsTip.get()); | mempool.check(pcoinsTip.get()); | ||||
// Callbacks/notifications for a new best chain. | // Callbacks/notifications for a new best chain. | ||||
if (fInvalidFound) { | if (fInvalidFound) { | ||||
CheckForkWarningConditionsOnNewFork(vpindexToConnect.back()); | CheckForkWarningConditionsOnNewFork(pindexMostWork); | ||||
} else { | } else { | ||||
CheckForkWarningConditions(); | CheckForkWarningConditions(); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static void NotifyHeaderTip() { | static void NotifyHeaderTip() { | ||||
▲ Show 20 Lines • Show All 2,611 Lines • Show Last 20 Lines |