Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | bool AcceptBlock(const Config &config, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
CValidationState &state, bool fRequested, | CValidationState &state, bool fRequested, | ||||
const FlatFilePos *dbp, bool *fNewBlock); | const FlatFilePos *dbp, bool *fNewBlock); | ||||
// Block (dis)connection on a given view: | // Block (dis)connection on a given view: | ||||
DisconnectResult DisconnectBlock(const CBlock &block, | DisconnectResult DisconnectBlock(const CBlock &block, | ||||
const CBlockIndex *pindex, | const CBlockIndex *pindex, | ||||
CCoinsViewCache &view); | CCoinsViewCache &view); | ||||
bool ConnectBlock(const Config &config, const CBlock &block, | bool ConnectBlock(const CBlock &block, CValidationState &state, | ||||
CValidationState &state, CBlockIndex *pindex, | CBlockIndex *pindex, CCoinsViewCache &view, | ||||
CCoinsViewCache &view, bool fJustCheck = false); | const CChainParams ¶ms, | ||||
BlockValidationOptions options, bool fJustCheck = false); | |||||
// Block disconnection on our pcoinsTip: | // Block disconnection on our pcoinsTip: | ||||
bool DisconnectTip(const Config &config, CValidationState &state, | bool DisconnectTip(const Config &config, CValidationState &state, | ||||
DisconnectedBlockTransactions *disconnectpool); | DisconnectedBlockTransactions *disconnectpool); | ||||
// Manual block validity manipulation: | // Manual block validity manipulation: | ||||
bool PreciousBlock(const Config &config, CValidationState &state, | bool PreciousBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex); | CBlockIndex *pindex); | ||||
▲ Show 20 Lines • Show All 1,490 Lines • ▼ Show 20 Lines | |||||
static int64_t nBlocksTotal = 0; | static int64_t nBlocksTotal = 0; | ||||
/** | /** | ||||
* Apply the effects of this block (with given index) on the UTXO set | * Apply the effects of this block (with given index) on the UTXO set | ||||
* represented by coins. Validity checks that depend on the UTXO set are also | * represented by coins. Validity checks that depend on the UTXO set are also | ||||
* done; ConnectBlock() can fail if those validity checks fail (among other | * done; ConnectBlock() can fail if those validity checks fail (among other | ||||
* reasons). | * reasons). | ||||
*/ | */ | ||||
bool CChainState::ConnectBlock(const Config &config, const CBlock &block, | bool CChainState::ConnectBlock(const CBlock &block, CValidationState &state, | ||||
CValidationState &state, CBlockIndex *pindex, | CBlockIndex *pindex, CCoinsViewCache &view, | ||||
CCoinsViewCache &view, bool fJustCheck) { | const CChainParams ¶ms, | ||||
BlockValidationOptions options, | |||||
bool fJustCheck) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
assert(pindex); | assert(pindex); | ||||
assert(*pindex->phashBlock == block.GetHash()); | assert(*pindex->phashBlock == block.GetHash()); | ||||
int64_t nTimeStart = GetTimeMicros(); | int64_t nTimeStart = GetTimeMicros(); | ||||
const Consensus::Params &consensusParams = | const Consensus::Params &consensusParams = params.GetConsensus(); | ||||
config.GetChainParams().GetConsensus(); | |||||
// Check it again in case a previous version let a bad block in | // Check it again in case a previous version let a bad block in | ||||
// NOTE: We don't currently (re-)invoke ContextualCheckBlock() or | // NOTE: We don't currently (re-)invoke ContextualCheckBlock() or | ||||
// ContextualCheckBlockHeader() here. This means that if we add a new | // ContextualCheckBlockHeader() here. This means that if we add a new | ||||
// consensus rule that is enforced in one of those two functions, then we | // consensus rule that is enforced in one of those two functions, then we | ||||
// may have let in a block that violates the rule prior to updating the | // may have let in a block that violates the rule prior to updating the | ||||
// software, and we would NOT be enforcing the rule here. Fully solving | // software, and we would NOT be enforcing the rule here. Fully solving | ||||
// upgrade from one software version to the next after a consensus rule | // upgrade from one software version to the next after a consensus rule | ||||
// change is potentially tricky and issue-specific (see RewindBlockIndex() | // change is potentially tricky and issue-specific (see RewindBlockIndex() | ||||
// for one general approach that was used for BIP 141 deployment). | // for one general approach that was used for BIP 141 deployment). | ||||
// Also, currently the rule against blocks more than 2 hours in the future | // Also, currently the rule against blocks more than 2 hours in the future | ||||
// is enforced in ContextualCheckBlockHeader(); we wouldn't want to | // is enforced in ContextualCheckBlockHeader(); we wouldn't want to | ||||
// re-enforce that rule here (at least until we make it impossible for | // re-enforce that rule here (at least until we make it impossible for | ||||
// GetAdjustedTime() to go backward). | // GetAdjustedTime() to go backward). | ||||
if (!CheckBlock(block, state, consensusParams, | if (!CheckBlock(block, state, consensusParams, | ||||
BlockValidationOptions(config) | options.withCheckPoW(!fJustCheck) | ||||
.withCheckPoW(!fJustCheck) | |||||
.withCheckMerkleRoot(!fJustCheck))) { | .withCheckMerkleRoot(!fJustCheck))) { | ||||
if (state.CorruptionPossible()) { | if (state.CorruptionPossible()) { | ||||
// We don't write down blocks to disk if they may have been | // We don't write down blocks to disk if they may have been | ||||
// corrupted, so this should be impossible unless we're having | // corrupted, so this should be impossible unless we're having | ||||
// hardware problems. | // hardware problems. | ||||
return AbortNode(state, "Corrupt block found indicating potential " | return AbortNode(state, "Corrupt block found indicating potential " | ||||
"hardware failure; shutting down"); | "hardware failure; shutting down"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 263 Lines • ▼ Show 20 Lines | LogPrint( | ||||
nInputs - 1, MILLI * (nTime4 - nTime2), | nInputs - 1, MILLI * (nTime4 - nTime2), | ||||
nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs - 1), | nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs - 1), | ||||
nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal); | nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal); | ||||
if (fJustCheck) { | if (fJustCheck) { | ||||
return true; | return true; | ||||
} | } | ||||
if (!WriteUndoDataForBlock(blockundo, state, pindex, | if (!WriteUndoDataForBlock(blockundo, state, pindex, params)) { | ||||
config.GetChainParams())) { | |||||
return false; | return false; | ||||
} | } | ||||
if (!pindex->IsValid(BlockValidity::SCRIPTS)) { | if (!pindex->IsValid(BlockValidity::SCRIPTS)) { | ||||
pindex->RaiseValidity(BlockValidity::SCRIPTS); | pindex->RaiseValidity(BlockValidity::SCRIPTS); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 461 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
bool CChainState::ConnectTip(const Config &config, CValidationState &state, | bool CChainState::ConnectTip(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
ConnectTrace &connectTrace, | ConnectTrace &connectTrace, | ||||
DisconnectedBlockTransactions &disconnectpool) { | DisconnectedBlockTransactions &disconnectpool) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const Consensus::Params &consensusParams = | const CChainParams ¶ms = config.GetChainParams(); | ||||
config.GetChainParams().GetConsensus(); | const Consensus::Params &consensusParams = params.GetConsensus(); | ||||
assert(pindexNew->pprev == chainActive.Tip()); | assert(pindexNew->pprev == chainActive.Tip()); | ||||
// Read block from disk. | // Read block from disk. | ||||
int64_t nTime1 = GetTimeMicros(); | int64_t nTime1 = GetTimeMicros(); | ||||
std::shared_ptr<const CBlock> pthisBlock; | std::shared_ptr<const CBlock> pthisBlock; | ||||
if (!pblock) { | if (!pblock) { | ||||
std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); | std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); | ||||
if (!ReadBlockFromDisk(*pblockNew, pindexNew, consensusParams)) { | if (!ReadBlockFromDisk(*pblockNew, pindexNew, consensusParams)) { | ||||
Show All 9 Lines | bool CChainState::ConnectTip(const Config &config, CValidationState &state, | ||||
// Apply the block atomically to the chain state. | // Apply the block atomically to the chain state. | ||||
int64_t nTime2 = GetTimeMicros(); | int64_t nTime2 = GetTimeMicros(); | ||||
nTimeReadFromDisk += nTime2 - nTime1; | nTimeReadFromDisk += nTime2 - nTime1; | ||||
int64_t nTime3; | int64_t nTime3; | ||||
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", | LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", | ||||
(nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO); | (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO); | ||||
{ | { | ||||
CCoinsViewCache view(pcoinsTip.get()); | CCoinsViewCache view(pcoinsTip.get()); | ||||
bool rv = ConnectBlock(config, blockConnecting, state, pindexNew, view); | bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, params, | ||||
BlockValidationOptions(config)); | |||||
GetMainSignals().BlockChecked(blockConnecting, state); | GetMainSignals().BlockChecked(blockConnecting, state); | ||||
if (!rv) { | if (!rv) { | ||||
if (state.IsInvalid()) { | if (state.IsInvalid()) { | ||||
InvalidBlockFound(pindexNew, state); | InvalidBlockFound(pindexNew, state); | ||||
} | } | ||||
return error("ConnectTip(): ConnectBlock %s failed (%s)", | return error("ConnectTip(): ConnectBlock %s failed (%s)", | ||||
pindexNew->GetBlockHash().ToString(), | pindexNew->GetBlockHash().ToString(), | ||||
▲ Show 20 Lines • Show All 1,668 Lines • ▼ Show 20 Lines | bool TestBlockValidity(const Config &config, CValidationState &state, | ||||
} | } | ||||
if (!ContextualCheckBlock( | if (!ContextualCheckBlock( | ||||
block, state, config.GetChainParams().GetConsensus(), pindexPrev)) { | block, state, config.GetChainParams().GetConsensus(), pindexPrev)) { | ||||
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, | return error("%s: Consensus::ContextualCheckBlock: %s", __func__, | ||||
FormatStateMessage(state)); | FormatStateMessage(state)); | ||||
} | } | ||||
if (!g_chainstate.ConnectBlock(config, block, state, &indexDummy, viewNew, | if (!g_chainstate.ConnectBlock(block, state, &indexDummy, viewNew, | ||||
config.GetChainParams(), validationOptions, | |||||
true)) { | true)) { | ||||
return false; | return false; | ||||
} | } | ||||
assert(state.IsValid()); | assert(state.IsValid()); | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 417 Lines • ▼ Show 20 Lines | |||||
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) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const Consensus::Params &consensusParams = | const CChainParams ¶ms = config.GetChainParams(); | ||||
config.GetChainParams().GetConsensus(); | const Consensus::Params &consensusParams = params.GetConsensus(); | ||||
if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr) { | if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr) { | ||||
return true; | return true; | ||||
} | } | ||||
// Verify blocks in the best chain | // Verify blocks in the best chain | ||||
if (nCheckDepth <= 0 || nCheckDepth > chainActive.Height()) { | if (nCheckDepth <= 0 || nCheckDepth > chainActive.Height()) { | ||||
nCheckDepth = chainActive.Height(); | nCheckDepth = chainActive.Height(); | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | if (nCheckLevel >= 4) { | ||||
false); | false); | ||||
pindex = chainActive.Next(pindex); | pindex = chainActive.Next(pindex); | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pindex, consensusParams)) { | if (!ReadBlockFromDisk(block, pindex, consensusParams)) { | ||||
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 (!g_chainstate.ConnectBlock(config, block, state, pindex, | if (!g_chainstate.ConnectBlock(block, state, pindex, coins, params, | ||||
coins)) { | BlockValidationOptions(config))) { | ||||
return error("VerifyDB(): *** found unconnectable block at %d, " | return error("VerifyDB(): *** found unconnectable block at %d, " | ||||
"hash=%s (%s)", | "hash=%s (%s)", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString(), | pindex->nHeight, pindex->GetBlockHash().ToString(), | ||||
FormatStateMessage(state)); | FormatStateMessage(state)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 981 Lines • Show Last 20 Lines |