Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 4,282 Lines • ▼ Show 20 Lines | if (initial_download) { | ||||
LogPrintf("Pre-synchronizing blockheaders, height: %d (~%.2f%%)\n", | LogPrintf("Pre-synchronizing blockheaders, height: %d (~%.2f%%)\n", | ||||
height, progress); | height, progress); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Store a block on disk. | * Store a block on disk. | ||||
* | * | ||||
* @param[in] config The global config. | |||||
* @param[in,out] pblock The block we want to accept. | * @param[in,out] pblock The block we want to accept. | ||||
* @param[in] fRequested A boolean to indicate if this block was requested | * @param[in] fRequested A boolean to indicate if this block was requested | ||||
* from our peers. | * from our peers. | ||||
* @param[in] dbp If non-null, the disk position of the block. | * @param[in] dbp If non-null, the disk position of the block. | ||||
* @param[in,out] fNewBlock True if block was first received via this call. | * @param[in,out] fNewBlock True if block was first received via this call. | ||||
* @param[in] min_pow_checked True if proof-of-work anti-DoS checks have | * @param[in] min_pow_checked True if proof-of-work anti-DoS checks have | ||||
* been done by caller for headers chain | * been done by caller for headers chain | ||||
* @return True if the block is accepted as a valid block and written to disk. | * @return True if the block is accepted as a valid block and written to disk. | ||||
*/ | */ | ||||
bool Chainstate::AcceptBlock(const Config &config, | bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock> &pblock, | ||||
const std::shared_ptr<const CBlock> &pblock, | |||||
BlockValidationState &state, bool fRequested, | BlockValidationState &state, bool fRequested, | ||||
const FlatFilePos *dbp, bool *fNewBlock, | const FlatFilePos *dbp, bool *fNewBlock, | ||||
bool min_pow_checked) { | bool min_pow_checked) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const CBlock &block = *pblock; | const CBlock &block = *pblock; | ||||
if (fNewBlock) { | if (fNewBlock) { | ||||
*fNewBlock = false; | *fNewBlock = false; | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | if (!fRequested) { | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
const CChainParams ¶ms{m_chainman.GetParams()}; | const CChainParams ¶ms{m_chainman.GetParams()}; | ||||
const Consensus::Params &consensusParams = params.GetConsensus(); | const Consensus::Params &consensusParams = params.GetConsensus(); | ||||
if (!CheckBlock(block, state, consensusParams, | if (!CheckBlock(block, state, consensusParams, | ||||
BlockValidationOptions(config)) || | BlockValidationOptions(m_chainman.GetConfig())) || | ||||
!ContextualCheckBlock(block, state, consensusParams, pindex->pprev)) { | !ContextualCheckBlock(block, state, consensusParams, pindex->pprev)) { | ||||
if (state.IsInvalid() && | if (state.IsInvalid() && | ||||
state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { | state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { | ||||
pindex->nStatus = pindex->nStatus.withFailed(); | pindex->nStatus = pindex->nStatus.withFailed(); | ||||
m_blockman.m_dirty_blockindex.insert(pindex); | m_blockman.m_dirty_blockindex.insert(pindex); | ||||
} | } | ||||
return error("%s: %s (block %s)", __func__, state.ToString(), | return error("%s: %s (block %s)", __func__, state.ToString(), | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | AssertLockNotHeld(cs_main); | ||||
// CVE-2012-2459 and | // CVE-2012-2459 and | ||||
// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html. | // https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html. | ||||
// Because CheckBlock() is not very expensive, the anti-DoS benefits of | // Because CheckBlock() is not very expensive, the anti-DoS benefits of | ||||
// caching failure (of a definitely-invalid block) are not substantial. | // caching failure (of a definitely-invalid block) are not substantial. | ||||
bool ret = CheckBlock(*block, state, this->GetConsensus(), | bool ret = CheckBlock(*block, state, this->GetConsensus(), | ||||
BlockValidationOptions(this->GetConfig())); | BlockValidationOptions(this->GetConfig())); | ||||
if (ret) { | if (ret) { | ||||
// Store to disk | // Store to disk | ||||
ret = ActiveChainstate().AcceptBlock( | ret = ActiveChainstate().AcceptBlock(block, state, force_processing, | ||||
this->GetConfig(), block, state, force_processing, nullptr, | nullptr, new_block, | ||||
new_block, min_pow_checked); | min_pow_checked); | ||||
} | } | ||||
if (!ret) { | if (!ret) { | ||||
GetMainSignals().BlockChecked(*block, state); | GetMainSignals().BlockChecked(*block, state); | ||||
return error("%s: AcceptBlock FAILED (%s)", __func__, | return error("%s: AcceptBlock FAILED (%s)", __func__, | ||||
state.ToString()); | state.ToString()); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | |||||
CVerifyDB::CVerifyDB() { | CVerifyDB::CVerifyDB() { | ||||
uiInterface.ShowProgress(_("Verifying blocks...").translated, 0, false); | uiInterface.ShowProgress(_("Verifying blocks...").translated, 0, false); | ||||
} | } | ||||
CVerifyDB::~CVerifyDB() { | CVerifyDB::~CVerifyDB() { | ||||
uiInterface.ShowProgress("", 100, false); | uiInterface.ShowProgress("", 100, false); | ||||
} | } | ||||
VerifyDBResult CVerifyDB::VerifyDB(Chainstate &chainstate, const Config &config, | VerifyDBResult CVerifyDB::VerifyDB(Chainstate &chainstate, | ||||
CCoinsView &coinsview, int nCheckLevel, | CCoinsView &coinsview, int nCheckLevel, | ||||
int nCheckDepth) { | int nCheckDepth) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const Config &config = chainstate.m_chainman.GetConfig(); | |||||
const CChainParams ¶ms = config.GetChainParams(); | const CChainParams ¶ms = config.GetChainParams(); | ||||
const Consensus::Params &consensusParams = params.GetConsensus(); | const Consensus::Params &consensusParams = params.GetConsensus(); | ||||
if (chainstate.m_chain.Tip() == nullptr || | if (chainstate.m_chain.Tip() == nullptr || | ||||
chainstate.m_chain.Tip()->pprev == nullptr) { | chainstate.m_chain.Tip()->pprev == nullptr) { | ||||
return VerifyDBResult::SUCCESS; | return VerifyDBResult::SUCCESS; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 466 Lines • ▼ Show 20 Lines | try { | ||||
return error("%s: failed to write genesis block: %s", __func__, | return error("%s: failed to write genesis block: %s", __func__, | ||||
e.what()); | e.what()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
void Chainstate::LoadExternalBlockFile( | void Chainstate::LoadExternalBlockFile( | ||||
const Config &config, FILE *fileIn, FlatFilePos *dbp, | FILE *fileIn, FlatFilePos *dbp, | ||||
std::multimap<BlockHash, FlatFilePos> *blocks_with_unknown_parent) { | std::multimap<BlockHash, FlatFilePos> *blocks_with_unknown_parent) { | ||||
AssertLockNotHeld(m_chainstate_mutex); | AssertLockNotHeld(m_chainstate_mutex); | ||||
// Either both should be specified (-reindex), or neither (-loadblock). | // Either both should be specified (-reindex), or neither (-loadblock). | ||||
assert(!dbp == !blocks_with_unknown_parent); | assert(!dbp == !blocks_with_unknown_parent); | ||||
int64_t nStart = GetTimeMillis(); | int64_t nStart = GetTimeMillis(); | ||||
const CChainParams ¶ms{m_chainman.GetParams()}; | const CChainParams ¶ms{m_chainman.GetParams()}; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | try { | ||||
continue; | continue; | ||||
} | } | ||||
// process in case the block isn't known yet | // process in case the block isn't known yet | ||||
const CBlockIndex *pindex = | const CBlockIndex *pindex = | ||||
m_blockman.LookupBlockIndex(hash); | m_blockman.LookupBlockIndex(hash); | ||||
if (!pindex || !pindex->nStatus.hasData()) { | if (!pindex || !pindex->nStatus.hasData()) { | ||||
BlockValidationState state; | BlockValidationState state; | ||||
if (AcceptBlock(config, pblock, state, true, dbp, | if (AcceptBlock(pblock, state, true, dbp, nullptr, | ||||
nullptr, true)) { | true)) { | ||||
nLoaded++; | nLoaded++; | ||||
} | } | ||||
if (state.IsError()) { | if (state.IsError()) { | ||||
break; | break; | ||||
} | } | ||||
} else if (hash != params.GetConsensus().hashGenesisBlock && | } else if (hash != params.GetConsensus().hashGenesisBlock && | ||||
pindex->nHeight % 1000 == 0) { | pindex->nHeight % 1000 == 0) { | ||||
LogPrint( | LogPrint( | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | try { | ||||
params.GetConsensus())) { | params.GetConsensus())) { | ||||
LogPrint( | LogPrint( | ||||
BCLog::REINDEX, | BCLog::REINDEX, | ||||
"%s: Processing out of order child %s of %s\n", | "%s: Processing out of order child %s of %s\n", | ||||
__func__, pblockrecursive->GetHash().ToString(), | __func__, pblockrecursive->GetHash().ToString(), | ||||
head.ToString()); | head.ToString()); | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
BlockValidationState dummy; | BlockValidationState dummy; | ||||
if (AcceptBlock(config, pblockrecursive, dummy, | if (AcceptBlock(pblockrecursive, dummy, true, | ||||
true, &it->second, nullptr, true)) { | &it->second, nullptr, true)) { | ||||
nLoaded++; | nLoaded++; | ||||
queue.push_back(pblockrecursive->GetHash()); | queue.push_back(pblockrecursive->GetHash()); | ||||
} | } | ||||
} | } | ||||
range.first++; | range.first++; | ||||
blocks_with_unknown_parent->erase(it); | blocks_with_unknown_parent->erase(it); | ||||
NotifyHeaderTip(*this); | NotifyHeaderTip(*this); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,252 Lines • Show Last 20 Lines |