Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | |||||
std::set<const CBlockIndex *> setDirtyBlockIndex; | std::set<const CBlockIndex *> setDirtyBlockIndex; | ||||
/** Dirty block file entries. */ | /** Dirty block file entries. */ | ||||
std::set<int> setDirtyFileInfo; | std::set<int> setDirtyFileInfo; | ||||
} // namespace | } // namespace | ||||
CBlockIndex *FindForkInGlobalIndex(const CChain &chain, | CBlockIndex *FindForkInGlobalIndex(const CChain &chain, | ||||
const CBlockLocator &locator) { | const CBlockLocator &locator) { | ||||
AssertLockHeld(cs_main); | |||||
// Find the first block the caller has in the main chain | // Find the first block the caller has in the main chain | ||||
for (const uint256 &hash : locator.vHave) { | for (const uint256 &hash : locator.vHave) { | ||||
BlockMap::iterator mi = mapBlockIndex.find(hash); | CBlockIndex *pindex = LookupBlockIndex(hash); | ||||
if (mi != mapBlockIndex.end()) { | if (pindex) { | ||||
CBlockIndex *pindex = (*mi).second; | |||||
if (chain.Contains(pindex)) { | if (chain.Contains(pindex)) { | ||||
return pindex; | return pindex; | ||||
} | } | ||||
if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { | if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { | ||||
return chain.Tip(); | return chain.Tip(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 937 Lines • ▼ Show 20 Lines | bool CScriptCheck::operator()() { | ||||
return VerifyScript(scriptSig, scriptPubKey, nFlags, | return VerifyScript(scriptSig, scriptPubKey, nFlags, | ||||
CachingTransactionSignatureChecker(ptxTo, nIn, amount, | CachingTransactionSignatureChecker(ptxTo, nIn, amount, | ||||
cacheStore, txdata), | cacheStore, txdata), | ||||
&error); | &error); | ||||
} | } | ||||
int GetSpendHeight(const CCoinsViewCache &inputs) { | int GetSpendHeight(const CCoinsViewCache &inputs) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; | CBlockIndex *pindexPrev = LookupBlockIndex(inputs.GetBestBlock()); | ||||
return pindexPrev->nHeight + 1; | return pindexPrev->nHeight + 1; | ||||
} | } | ||||
bool CheckInputs(const CTransaction &tx, CValidationState &state, | bool CheckInputs(const CTransaction &tx, CValidationState &state, | ||||
const CCoinsViewCache &inputs, bool fScriptChecks, | const CCoinsViewCache &inputs, bool fScriptChecks, | ||||
const uint32_t flags, bool sigCacheStore, | const uint32_t flags, bool sigCacheStore, | ||||
bool scriptCacheStore, | bool scriptCacheStore, | ||||
const PrecomputedTransactionData &txdata, | const PrecomputedTransactionData &txdata, | ||||
▲ Show 20 Lines • Show All 2,043 Lines • ▼ Show 20 Lines | |||||
bool IsBlockFinalized(const CBlockIndex *pindex) { | bool IsBlockFinalized(const CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return pindexFinalized && | return pindexFinalized && | ||||
pindexFinalized->GetAncestor(pindex->nHeight) == pindex; | pindexFinalized->GetAncestor(pindex->nHeight) == pindex; | ||||
} | } | ||||
CBlockIndex *CChainState::AddToBlockIndex(const CBlockHeader &block) { | CBlockIndex *CChainState::AddToBlockIndex(const CBlockHeader &block) { | ||||
AssertLockHeld(cs_main); | |||||
// Check for duplicate | // Check for duplicate | ||||
uint256 hash = block.GetHash(); | uint256 hash = block.GetHash(); | ||||
BlockMap::iterator it = mapBlockIndex.find(hash); | BlockMap::iterator it = mapBlockIndex.find(hash); | ||||
if (it != mapBlockIndex.end()) { | if (it != mapBlockIndex.end()) { | ||||
return it->second; | return it->second; | ||||
} | } | ||||
// Construct new block index object | // Construct new block index object | ||||
▲ Show 20 Lines • Show All 1,121 Lines • ▼ Show 20 Lines | static FILE *OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) { | ||||
return OpenDiskFile(pos, "rev", fReadOnly); | return OpenDiskFile(pos, "rev", fReadOnly); | ||||
} | } | ||||
fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix) { | fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix) { | ||||
return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile); | return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile); | ||||
} | } | ||||
CBlockIndex *CChainState::InsertBlockIndex(const uint256 &hash) { | CBlockIndex *CChainState::InsertBlockIndex(const uint256 &hash) { | ||||
AssertLockHeld(cs_main); | |||||
if (hash.IsNull()) { | if (hash.IsNull()) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
// Return existing | // Return existing | ||||
BlockMap::iterator mi = mapBlockIndex.find(hash); | BlockMap::iterator mi = mapBlockIndex.find(hash); | ||||
if (mi != mapBlockIndex.end()) { | if (mi != mapBlockIndex.end()) { | ||||
return (*mi).second; | return (*mi).second; | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | bool static LoadBlockIndexDB(const Config &config) { | ||||
pblocktree->ReadFlag("txindex", fTxIndex); | pblocktree->ReadFlag("txindex", fTxIndex); | ||||
LogPrintf("%s: transaction index %s\n", __func__, | LogPrintf("%s: transaction index %s\n", __func__, | ||||
fTxIndex ? "enabled" : "disabled"); | fTxIndex ? "enabled" : "disabled"); | ||||
return true; | return true; | ||||
} | } | ||||
bool LoadChainTip(const Config &config) { | bool LoadChainTip(const Config &config) { | ||||
AssertLockHeld(cs_main); | |||||
if (chainActive.Tip() && | if (chainActive.Tip() && | ||||
chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) { | chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) { | ||||
return true; | return true; | ||||
} | } | ||||
if (pcoinsTip->GetBestBlock().IsNull() && mapBlockIndex.size() == 1) { | if (pcoinsTip->GetBestBlock().IsNull() && mapBlockIndex.size() == 1) { | ||||
// In case we just added the genesis block, connect it now, so | // In case we just added the genesis block, connect it now, so | ||||
// that we always have a chainActive.Tip() when we return. | // that we always have a chainActive.Tip() when we return. | ||||
LogPrintf("%s: Connecting genesis block...\n", __func__); | LogPrintf("%s: Connecting genesis block...\n", __func__); | ||||
CValidationState state; | CValidationState state; | ||||
if (!ActivateBestChain(config, state)) { | if (!ActivateBestChain(config, state)) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// Load pointer to end of best chain | // Load pointer to end of best chain | ||||
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); | CBlockIndex *pindex = LookupBlockIndex(pcoinsTip->GetBestBlock()); | ||||
if (it == mapBlockIndex.end()) { | if (!pindex) { | ||||
return false; | return false; | ||||
} | } | ||||
chainActive.SetTip(pindex); | |||||
chainActive.SetTip(it->second); | |||||
g_chainstate.PruneBlockIndexCandidates(); | g_chainstate.PruneBlockIndexCandidates(); | ||||
LogPrintf( | LogPrintf( | ||||
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n", | "Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n", | ||||
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), | chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), | ||||
FormatISO8601DateTime(chainActive.Tip()->GetBlockTime()), | FormatISO8601DateTime(chainActive.Tip()->GetBlockTime()), | ||||
GuessVerificationProgress(config.GetChainParams().TxData(), | GuessVerificationProgress(config.GetChainParams().TxData(), | ||||
▲ Show 20 Lines • Show All 518 Lines • ▼ Show 20 Lines | try { | ||||
} | } | ||||
blkdat.SetLimit(nBlockPos + nSize); | blkdat.SetLimit(nBlockPos + nSize); | ||||
blkdat.SetPos(nBlockPos); | blkdat.SetPos(nBlockPos); | ||||
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); | std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); | ||||
CBlock &block = *pblock; | CBlock &block = *pblock; | ||||
blkdat >> block; | blkdat >> block; | ||||
nRewind = blkdat.GetPos(); | nRewind = blkdat.GetPos(); | ||||
// detect out of order blocks, and store them for later | |||||
uint256 hash = block.GetHash(); | uint256 hash = block.GetHash(); | ||||
{ | |||||
LOCK(cs_main); | |||||
// detect out of order blocks, and store them for later | |||||
if (hash != chainparams.GetConsensus().hashGenesisBlock && | if (hash != chainparams.GetConsensus().hashGenesisBlock && | ||||
mapBlockIndex.find(block.hashPrevBlock) == | !LookupBlockIndex(block.hashPrevBlock)) { | ||||
mapBlockIndex.end()) { | LogPrint( | ||||
LogPrint(BCLog::REINDEX, | BCLog::REINDEX, | ||||
"%s: Out of order block %s, parent %s not known\n", | "%s: Out of order block %s, parent %s not known\n", | ||||
__func__, hash.ToString(), | __func__, hash.ToString(), | ||||
block.hashPrevBlock.ToString()); | block.hashPrevBlock.ToString()); | ||||
if (dbp) { | if (dbp) { | ||||
mapBlocksUnknownParent.insert( | mapBlocksUnknownParent.insert( | ||||
std::make_pair(block.hashPrevBlock, *dbp)); | std::make_pair(block.hashPrevBlock, *dbp)); | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
// process in case the block isn't known yet | // process in case the block isn't known yet | ||||
if (mapBlockIndex.count(hash) == 0 || | CBlockIndex *pindex = LookupBlockIndex(hash); | ||||
!mapBlockIndex[hash]->nStatus.hasData()) { | if (!pindex || !pindex->nStatus.hasData()) { | ||||
LOCK(cs_main); | |||||
CValidationState state; | CValidationState state; | ||||
if (g_chainstate.AcceptBlock(config, pblock, state, true, | if (g_chainstate.AcceptBlock(config, pblock, state, | ||||
dbp, nullptr)) { | true, dbp, nullptr)) { | ||||
nLoaded++; | nLoaded++; | ||||
} | } | ||||
if (state.IsError()) { | if (state.IsError()) { | ||||
break; | break; | ||||
} | } | ||||
} else if (hash != | } else if (hash != chainparams.GetConsensus() | ||||
chainparams.GetConsensus().hashGenesisBlock && | .hashGenesisBlock && | ||||
mapBlockIndex[hash]->nHeight % 1000 == 0) { | pindex->nHeight % 1000 == 0) { | ||||
LogPrint( | LogPrint( | ||||
BCLog::REINDEX, | BCLog::REINDEX, | ||||
"Block Import: already had block %s at height %d\n", | "Block Import: already had block %s at height %d\n", | ||||
hash.ToString(), mapBlockIndex[hash]->nHeight); | hash.ToString(), pindex->nHeight); | ||||
} | |||||
} | } | ||||
// Activate the genesis block so normal node progress can | // Activate the genesis block so normal node progress can | ||||
// continue | // continue | ||||
if (hash == chainparams.GetConsensus().hashGenesisBlock) { | if (hash == chainparams.GetConsensus().hashGenesisBlock) { | ||||
CValidationState state; | CValidationState state; | ||||
if (!ActivateBestChain(config, state)) { | if (!ActivateBestChain(config, state)) { | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 548 Lines • Show Last 20 Lines |