Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,022 Lines • ▼ Show 20 Lines | CheckForkWarningConditionsOnNewFork(const CBlockIndex *pindexNewForkTip) { | ||||
// 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 | ||||
// condition and from this always have the most-likely-to-cause-warning fork | // condition and from this always have the most-likely-to-cause-warning fork | ||||
if (pfork && (!pindexBestForkTip || | if (pfork && | ||||
(!pindexBestForkTip || | |||||
pindexNewForkTip->nHeight > pindexBestForkTip->nHeight) && | pindexNewForkTip->nHeight > pindexBestForkTip->nHeight) && | ||||
pindexNewForkTip->nChainWork - pfork->nChainWork > | pindexNewForkTip->nChainWork - pfork->nChainWork > | ||||
(GetBlockProof(*pfork) * 7) && | (GetBlockProof(*pfork) * 7) && | ||||
chainActive.Height() - pindexNewForkTip->nHeight < 72) { | chainActive.Height() - pindexNewForkTip->nHeight < 72) { | ||||
pindexBestForkTip = pindexNewForkTip; | pindexBestForkTip = pindexNewForkTip; | ||||
pindexBestForkBase = pfork; | pindexBestForkBase = pfork; | ||||
} | } | ||||
CheckForkWarningConditions(); | CheckForkWarningConditions(); | ||||
▲ Show 20 Lines • Show All 797 Lines • ▼ Show 20 Lines | LogPrint(BCLog::BENCH, | ||||
(unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), | (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), | ||||
0.001 * (nTime3 - nTime2) / block.vtx.size(), | 0.001 * (nTime3 - nTime2) / block.vtx.size(), | ||||
nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs - 1), | nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs - 1), | ||||
nTimeConnect * 0.000001); | nTimeConnect * 0.000001); | ||||
Amount blockReward = | Amount blockReward = | ||||
nFees + GetBlockSubsidy(pindex->nHeight, consensusParams); | nFees + GetBlockSubsidy(pindex->nHeight, consensusParams); | ||||
if (block.vtx[0]->GetValueOut() > blockReward) { | if (block.vtx[0]->GetValueOut() > blockReward) { | ||||
return state.DoS(100, error("ConnectBlock(): coinbase pays too much " | return state.DoS(100, | ||||
error("ConnectBlock(): coinbase pays too much " | |||||
"(actual=%d vs limit=%d)", | "(actual=%d vs limit=%d)", | ||||
block.vtx[0]->GetValueOut(), blockReward), | block.vtx[0]->GetValueOut(), blockReward), | ||||
REJECT_INVALID, "bad-cb-amount"); | REJECT_INVALID, "bad-cb-amount"); | ||||
} | } | ||||
if (!control.Wait()) { | if (!control.Wait()) { | ||||
return state.DoS(100, false, REJECT_INVALID, "blk-bad-inputs", false, | return state.DoS(100, false, REJECT_INVALID, "blk-bad-inputs", false, | ||||
"parallel script check failed"); | "parallel script check failed"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 192 Lines • ▼ Show 20 Lines | try { | ||||
((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && | ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && | ||||
nNow > | nNow > | ||||
nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { | nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { | ||||
// Update best block in wallet (so we can detect restored wallets). | // Update best block in wallet (so we can detect restored wallets). | ||||
GetMainSignals().SetBestChain(chainActive.GetLocator()); | GetMainSignals().SetBestChain(chainActive.GetLocator()); | ||||
nLastSetChain = nNow; | nLastSetChain = nNow; | ||||
} | } | ||||
} catch (const std::runtime_error &e) { | } catch (const std::runtime_error &e) { | ||||
return AbortNode( | return AbortNode(state, std::string("System error while flushing: ") + | ||||
state, std::string("System error while flushing: ") + e.what()); | e.what()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
void FlushStateToDisk() { | void FlushStateToDisk() { | ||||
CValidationState state; | CValidationState state; | ||||
const CChainParams &chainparams = Params(); | const CChainParams &chainparams = Params(); | ||||
FlushStateToDisk(chainparams, state, FLUSH_STATE_ALWAYS); | FlushStateToDisk(chainparams, state, FLUSH_STATE_ALWAYS); | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | if (pindex->nStatus.isInvalid()) { | ||||
error("%s: Trying to finalize invalid block %s", | error("%s: Trying to finalize invalid block %s", | ||||
__func__, pindex->GetBlockHash().ToString()), | __func__, pindex->GetBlockHash().ToString()), | ||||
REJECT_INVALID, "finalize-invalid-block"); | REJECT_INVALID, "finalize-invalid-block"); | ||||
} | } | ||||
// Check that the request is consistent with current finalization. | // Check that the request is consistent with current finalization. | ||||
if (pindexFinalized && !AreOnTheSameFork(pindex, pindexFinalized)) { | if (pindexFinalized && !AreOnTheSameFork(pindex, pindexFinalized)) { | ||||
return state.DoS( | return state.DoS( | ||||
20, error("%s: Trying to finalize block %s which conflicts " | 20, | ||||
error("%s: Trying to finalize block %s which conflicts " | |||||
"with already finalized block", | "with already finalized block", | ||||
__func__, pindex->GetBlockHash().ToString()), | __func__, pindex->GetBlockHash().ToString()), | ||||
REJECT_AGAINST_FINALIZED, "bad-fork-prior-finalized"); | REJECT_AGAINST_FINALIZED, "bad-fork-prior-finalized"); | ||||
} | } | ||||
if (IsBlockFinalized(pindex)) { | if (IsBlockFinalized(pindex)) { | ||||
// The block is already finalized. | // The block is already finalized. | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,123 Lines • ▼ Show 20 Lines | static bool CheckIndexAgainstCheckpoint(const CBlockIndex *pindexPrev, | ||||
} | } | ||||
int nHeight = pindexPrev->nHeight + 1; | int nHeight = pindexPrev->nHeight + 1; | ||||
const CCheckpointData &checkpoints = chainparams.Checkpoints(); | const CCheckpointData &checkpoints = chainparams.Checkpoints(); | ||||
// Check that the block chain matches the known block chain up to a | // Check that the block chain matches the known block chain up to a | ||||
// checkpoint. | // checkpoint. | ||||
if (!Checkpoints::CheckBlock(checkpoints, nHeight, hash)) { | if (!Checkpoints::CheckBlock(checkpoints, nHeight, hash)) { | ||||
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", | return state.DoS(100, | ||||
error("%s: rejected by checkpoint lock-in at %d", | |||||
__func__, nHeight), | __func__, nHeight), | ||||
REJECT_CHECKPOINT, "checkpoint mismatch"); | REJECT_CHECKPOINT, "checkpoint mismatch"); | ||||
} | } | ||||
// Don't accept any forks from the main chain prior to last checkpoint. | // Don't accept any forks from the main chain prior to last checkpoint. | ||||
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in | // GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in | ||||
// our MapBlockIndex. | // our MapBlockIndex. | ||||
CBlockIndex *pcheckpoint = Checkpoints::GetLastCheckpoint(checkpoints); | CBlockIndex *pcheckpoint = Checkpoints::GetLastCheckpoint(checkpoints); | ||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight) { | if (pcheckpoint && nHeight < pcheckpoint->nHeight) { | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | if (hash != chainparams.GetConsensus().hashGenesisBlock) { | ||||
CBlockIndex *pindexPrev = (*mi).second; | CBlockIndex *pindexPrev = (*mi).second; | ||||
assert(pindexPrev); | assert(pindexPrev); | ||||
if (pindexPrev->nStatus.isInvalid()) { | if (pindexPrev->nStatus.isInvalid()) { | ||||
return state.DoS(100, error("%s: prev block invalid", __func__), | return state.DoS(100, error("%s: prev block invalid", __func__), | ||||
REJECT_INVALID, "bad-prevblk"); | REJECT_INVALID, "bad-prevblk"); | ||||
} | } | ||||
if (fCheckpointsEnabled && | if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint( | ||||
!CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, | pindexPrev, state, chainparams, hash)) { | ||||
hash)) { | |||||
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, | return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, | ||||
state.GetRejectReason().c_str()); | state.GetRejectReason().c_str()); | ||||
} | } | ||||
if (!ContextualCheckBlockHeader(config, block, state, pindexPrev, | if (!ContextualCheckBlockHeader(config, block, state, pindexPrev, | ||||
GetAdjustedTime())) { | GetAdjustedTime())) { | ||||
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", | return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", | ||||
__func__, hash.ToString(), FormatStateMessage(state)); | __func__, hash.ToString(), FormatStateMessage(state)); | ||||
▲ Show 20 Lines • Show All 468 Lines • ▼ Show 20 Lines | if (nCurrentUsage + nBuffer >= nPruneTarget) { | ||||
PruneOneBlockFile(fileNumber); | PruneOneBlockFile(fileNumber); | ||||
// Queue up the files for removal | // Queue up the files for removal | ||||
setFilesToPrune.insert(fileNumber); | setFilesToPrune.insert(fileNumber); | ||||
nCurrentUsage -= nBytesToPrune; | nCurrentUsage -= nBytesToPrune; | ||||
count++; | count++; | ||||
} | } | ||||
} | } | ||||
LogPrint(BCLog::PRUNE, "Prune: target=%dMiB actual=%dMiB diff=%dMiB " | LogPrint(BCLog::PRUNE, | ||||
"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 CheckDiskSpace(uint64_t nAdditionalBytes) { | ||||
uint64_t nFreeBytesAvailable = fs::space(GetDataDir()).available; | uint64_t nFreeBytesAvailable = fs::space(GetDataDir()).available; | ||||
▲ Show 20 Lines • Show All 367 Lines • ▼ Show 20 Lines | bool CVerifyDB::VerifyDB(const Config &config, CCoinsView *coinsview, | ||||
// check level 4: try reconnecting blocks | // check level 4: try reconnecting blocks | ||||
if (nCheckLevel >= 4) { | if (nCheckLevel >= 4) { | ||||
CBlockIndex *pindex = pindexState; | CBlockIndex *pindex = pindexState; | ||||
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..."), | ||||
std::max(1, | std::max( | ||||
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)))); | ||||
pindex = chainActive.Next(pindex); | pindex = chainActive.Next(pindex); | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pindex, config)) { | if (!ReadBlockFromDisk(block, pindex, config)) { | ||||
return error( | return error( | ||||
"VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", | "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
} | } | ||||
if (!ConnectBlock(config, block, state, pindex, coins)) { | if (!ConnectBlock(config, block, state, pindex, coins)) { | ||||
▲ Show 20 Lines • Show All 944 Lines • Show Last 20 Lines |