mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-06 05:00:12 +02:00
Merge bitcoin/bitcoin#23785: refactor: Move stuff to ChainstateManager
fab6d6b2d154893ab422dda87f3535d42c3e06f4 Move pindexBestInvalid to ChainstateManager (MarcoFalke) facd2137eceacb95e1f71c87ddc704d752b37272 Move m_failed_blocks to ChainstateManager (MarcoFalke) fa47b5c100f81c65c15b5a6afaf6c91bc0861264 Move AcceptBlockHeader to ChainstateManager (MarcoFalke) fa3d62cf7b3501a056b34c5458c14d2fe6a55bd7 Move FindForkInGlobalIndex from BlockManager to CChainState (MarcoFalke) Pull request description: Move globals or members of the wrong class to the right class. ACKs for top commit: naumenkogs: ACK fab6d6b2d154893ab422dda87f3535d42c3e06f4 Sjors: ACK fab6d6b2d154893ab422dda87f3535d42c3e06f4 shaavan: ACK fab6d6b2d154893ab422dda87f3535d42c3e06f4 Tree-SHA512: 926cbdfa22838517497bacb79ed5f521f64117c2aacf96a0176f62831b4713314a32abc0213df5ee067edf63e4a4300f752a26006d36e5aab415bb91209a271f
This commit is contained in:
commit
8c0bd871fc
@ -65,7 +65,7 @@ bool BaseIndex::Init()
|
|||||||
if (locator.IsNull()) {
|
if (locator.IsNull()) {
|
||||||
m_best_block_index = nullptr;
|
m_best_block_index = nullptr;
|
||||||
} else {
|
} else {
|
||||||
m_best_block_index = m_chainstate->m_blockman.FindForkInGlobalIndex(active_chain, locator);
|
m_best_block_index = m_chainstate->FindForkInGlobalIndex(locator);
|
||||||
}
|
}
|
||||||
m_synced = m_best_block_index.load() == active_chain.Tip();
|
m_synced = m_best_block_index.load() == active_chain.Tip();
|
||||||
if (!m_synced) {
|
if (!m_synced) {
|
||||||
|
@ -3083,7 +3083,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
// Find the last block the caller has in the main chain
|
// Find the last block the caller has in the main chain
|
||||||
const CBlockIndex* pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
|
const CBlockIndex* pindex = m_chainman.ActiveChainstate().FindForkInGlobalIndex(locator);
|
||||||
|
|
||||||
// Send the rest of the chain
|
// Send the rest of the chain
|
||||||
if (pindex)
|
if (pindex)
|
||||||
@ -3203,7 +3203,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find the last block the caller has in the main chain
|
// Find the last block the caller has in the main chain
|
||||||
pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
|
pindex = m_chainman.ActiveChainstate().FindForkInGlobalIndex(locator);
|
||||||
if (pindex)
|
if (pindex)
|
||||||
pindex = m_chainman.ActiveChain().Next(pindex);
|
pindex = m_chainman.ActiveChain().Next(pindex);
|
||||||
}
|
}
|
||||||
|
@ -494,8 +494,8 @@ public:
|
|||||||
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
|
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
const CChain& active = Assert(m_node.chainman)->ActiveChain();
|
const CChainState& active = Assert(m_node.chainman)->ActiveChainstate();
|
||||||
if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) {
|
if (CBlockIndex* fork = active.FindForkInGlobalIndex(locator)) {
|
||||||
return fork->nHeight;
|
return fork->nHeight;
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -133,11 +133,6 @@ arith_uint256 nMinimumChainWork;
|
|||||||
|
|
||||||
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
||||||
|
|
||||||
// Internal stuff
|
|
||||||
namespace {
|
|
||||||
CBlockIndex* pindexBestInvalid = nullptr;
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// Internal stuff from blockstorage ...
|
// Internal stuff from blockstorage ...
|
||||||
extern RecursiveMutex cs_LastBlockFile;
|
extern RecursiveMutex cs_LastBlockFile;
|
||||||
extern std::vector<CBlockFileInfo> vinfoBlockFile;
|
extern std::vector<CBlockFileInfo> vinfoBlockFile;
|
||||||
@ -155,23 +150,24 @@ CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
|
|||||||
return it == m_block_index.end() ? nullptr : it->second;
|
return it == m_block_index.end() ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex* BlockManager::FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
|
CBlockIndex* CChainState::FindForkInGlobalIndex(const CBlockLocator& locator) const
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
// Find the latest block common to locator and chain - we expect that
|
// Find the latest block common to locator and chain - we expect that
|
||||||
// locator.vHave is sorted descending by height.
|
// locator.vHave is sorted descending by height.
|
||||||
for (const uint256& hash : locator.vHave) {
|
for (const uint256& hash : locator.vHave) {
|
||||||
CBlockIndex* pindex = LookupBlockIndex(hash);
|
CBlockIndex* pindex{m_blockman.LookupBlockIndex(hash)};
|
||||||
if (pindex) {
|
if (pindex) {
|
||||||
if (chain.Contains(pindex))
|
if (m_chain.Contains(pindex)) {
|
||||||
return pindex;
|
return pindex;
|
||||||
if (pindex->GetAncestor(chain.Height()) == chain.Tip()) {
|
}
|
||||||
return chain.Tip();
|
if (pindex->GetAncestor(m_chain.Height()) == m_chain.Tip()) {
|
||||||
|
return m_chain.Tip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chain.Genesis();
|
return m_chain.Genesis();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
|
bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
|
||||||
@ -1478,7 +1474,7 @@ void CChainState::CheckForkWarningConditions()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pindexBestInvalid && pindexBestInvalid->nChainWork > m_chain.Tip()->nChainWork + (GetBlockProof(*m_chain.Tip()) * 6)) {
|
if (m_chainman.m_best_invalid && m_chainman.m_best_invalid->nChainWork > m_chain.Tip()->nChainWork + (GetBlockProof(*m_chain.Tip()) * 6)) {
|
||||||
LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
|
LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
|
||||||
SetfLargeWorkInvalidChainFound(true);
|
SetfLargeWorkInvalidChainFound(true);
|
||||||
} else {
|
} else {
|
||||||
@ -1489,8 +1485,9 @@ void CChainState::CheckForkWarningConditions()
|
|||||||
// Called both upon regular invalid block discovery *and* InvalidateBlock
|
// Called both upon regular invalid block discovery *and* InvalidateBlock
|
||||||
void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
|
void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
|
||||||
{
|
{
|
||||||
if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
|
if (!m_chainman.m_best_invalid || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork) {
|
||||||
pindexBestInvalid = pindexNew;
|
m_chainman.m_best_invalid = pindexNew;
|
||||||
|
}
|
||||||
if (pindexBestHeader != nullptr && pindexBestHeader->GetAncestor(pindexNew->nHeight) == pindexNew) {
|
if (pindexBestHeader != nullptr && pindexBestHeader->GetAncestor(pindexNew->nHeight) == pindexNew) {
|
||||||
pindexBestHeader = m_chain.Tip();
|
pindexBestHeader = m_chain.Tip();
|
||||||
}
|
}
|
||||||
@ -1512,7 +1509,7 @@ void CChainState::InvalidBlockFound(CBlockIndex* pindex, const BlockValidationSt
|
|||||||
{
|
{
|
||||||
if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
|
if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
|
||||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||||
m_blockman.m_failed_blocks.insert(pindex);
|
m_chainman.m_failed_blocks.insert(pindex);
|
||||||
setDirtyBlockIndex.insert(pindex);
|
setDirtyBlockIndex.insert(pindex);
|
||||||
setBlockIndexCandidates.erase(pindex);
|
setBlockIndexCandidates.erase(pindex);
|
||||||
InvalidChainFound(pindex);
|
InvalidChainFound(pindex);
|
||||||
@ -2653,8 +2650,9 @@ CBlockIndex* CChainState::FindMostWorkChain() {
|
|||||||
bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
|
bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
|
||||||
if (fFailedChain || fMissingData) {
|
if (fFailedChain || fMissingData) {
|
||||||
// Candidate chain is not usable (either invalid or missing data)
|
// Candidate chain is not usable (either invalid or missing data)
|
||||||
if (fFailedChain && (pindexBestInvalid == nullptr || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
|
if (fFailedChain && (m_chainman.m_best_invalid == nullptr || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork)) {
|
||||||
pindexBestInvalid = pindexNew;
|
m_chainman.m_best_invalid = pindexNew;
|
||||||
|
}
|
||||||
CBlockIndex *pindexFailed = pindexNew;
|
CBlockIndex *pindexFailed = pindexNew;
|
||||||
// Remove the entire chain from the set.
|
// Remove the entire chain from the set.
|
||||||
while (pindexTest != pindexFailed) {
|
while (pindexTest != pindexFailed) {
|
||||||
@ -3065,7 +3063,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
|
|||||||
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
|
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
|
||||||
setDirtyBlockIndex.insert(to_mark_failed);
|
setDirtyBlockIndex.insert(to_mark_failed);
|
||||||
setBlockIndexCandidates.erase(to_mark_failed);
|
setBlockIndexCandidates.erase(to_mark_failed);
|
||||||
m_blockman.m_failed_blocks.insert(to_mark_failed);
|
m_chainman.m_failed_blocks.insert(to_mark_failed);
|
||||||
|
|
||||||
// If any new blocks somehow arrived while we were disconnecting
|
// If any new blocks somehow arrived while we were disconnecting
|
||||||
// (above), then the pre-calculation of what should go into
|
// (above), then the pre-calculation of what should go into
|
||||||
@ -3106,11 +3104,11 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
|
|||||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), it->second)) {
|
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), it->second)) {
|
||||||
setBlockIndexCandidates.insert(it->second);
|
setBlockIndexCandidates.insert(it->second);
|
||||||
}
|
}
|
||||||
if (it->second == pindexBestInvalid) {
|
if (it->second == m_chainman.m_best_invalid) {
|
||||||
// Reset invalid block marker if it was pointing to one of those.
|
// Reset invalid block marker if it was pointing to one of those.
|
||||||
pindexBestInvalid = nullptr;
|
m_chainman.m_best_invalid = nullptr;
|
||||||
}
|
}
|
||||||
m_blockman.m_failed_blocks.erase(it->second);
|
m_chainman.m_failed_blocks.erase(it->second);
|
||||||
}
|
}
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
@ -3120,7 +3118,7 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
|
|||||||
if (pindex->nStatus & BLOCK_FAILED_MASK) {
|
if (pindex->nStatus & BLOCK_FAILED_MASK) {
|
||||||
pindex->nStatus &= ~BLOCK_FAILED_MASK;
|
pindex->nStatus &= ~BLOCK_FAILED_MASK;
|
||||||
setDirtyBlockIndex.insert(pindex);
|
setDirtyBlockIndex.insert(pindex);
|
||||||
m_blockman.m_failed_blocks.erase(pindex);
|
m_chainman.m_failed_blocks.erase(pindex);
|
||||||
}
|
}
|
||||||
pindex = pindex->pprev;
|
pindex = pindex->pprev;
|
||||||
}
|
}
|
||||||
@ -3481,14 +3479,14 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex)
|
bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
uint256 hash = block.GetHash();
|
uint256 hash = block.GetHash();
|
||||||
BlockMap::iterator miSelf = m_block_index.find(hash);
|
BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};
|
||||||
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
|
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
|
||||||
if (miSelf != m_block_index.end()) {
|
if (miSelf != m_blockman.m_block_index.end()) {
|
||||||
// Block header is already known.
|
// Block header is already known.
|
||||||
CBlockIndex* pindex = miSelf->second;
|
CBlockIndex* pindex = miSelf->second;
|
||||||
if (ppindex)
|
if (ppindex)
|
||||||
@ -3507,8 +3505,8 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
|
|||||||
|
|
||||||
// Get prev block index
|
// Get prev block index
|
||||||
CBlockIndex* pindexPrev = nullptr;
|
CBlockIndex* pindexPrev = nullptr;
|
||||||
BlockMap::iterator mi = m_block_index.find(block.hashPrevBlock);
|
BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)};
|
||||||
if (mi == m_block_index.end()) {
|
if (mi == m_blockman.m_block_index.end()) {
|
||||||
LogPrint(BCLog::VALIDATION, "%s: %s prev block not found\n", __func__, hash.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: %s prev block not found\n", __func__, hash.ToString());
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found");
|
return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found");
|
||||||
}
|
}
|
||||||
@ -3517,7 +3515,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
|
|||||||
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
|
||||||
}
|
}
|
||||||
if (!ContextualCheckBlockHeader(block, state, *this, chainparams, pindexPrev, GetAdjustedTime())) {
|
if (!ContextualCheckBlockHeader(block, state, m_blockman, chainparams, pindexPrev, GetAdjustedTime())) {
|
||||||
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3561,7 +3559,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CBlockIndex* pindex = AddToBlockIndex(block);
|
CBlockIndex* pindex{m_blockman.AddToBlockIndex(block)};
|
||||||
|
|
||||||
if (ppindex)
|
if (ppindex)
|
||||||
*ppindex = pindex;
|
*ppindex = pindex;
|
||||||
@ -3577,8 +3575,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
|
|||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
for (const CBlockHeader& header : headers) {
|
for (const CBlockHeader& header : headers) {
|
||||||
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
|
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
|
||||||
bool accepted = m_blockman.AcceptBlockHeader(
|
bool accepted{AcceptBlockHeader(header, state, chainparams, &pindex)};
|
||||||
header, state, chainparams, &pindex);
|
|
||||||
ActiveChainstate().CheckBlockIndex();
|
ActiveChainstate().CheckBlockIndex();
|
||||||
|
|
||||||
if (!accepted) {
|
if (!accepted) {
|
||||||
@ -3608,7 +3605,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
|
|||||||
CBlockIndex *pindexDummy = nullptr;
|
CBlockIndex *pindexDummy = nullptr;
|
||||||
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
|
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
|
||||||
|
|
||||||
bool accepted_header = m_blockman.AcceptBlockHeader(block, state, m_params, &pindex);
|
bool accepted_header{m_chainman.AcceptBlockHeader(block, state, m_params, &pindex)};
|
||||||
CheckBlockIndex();
|
CheckBlockIndex();
|
||||||
|
|
||||||
if (!accepted_header)
|
if (!accepted_header)
|
||||||
@ -4014,8 +4011,9 @@ bool BlockManager::LoadBlockIndex(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
|
if (pindex->nStatus & BLOCK_FAILED_MASK && (!chainman.m_best_invalid || pindex->nChainWork > chainman.m_best_invalid->nChainWork)) {
|
||||||
pindexBestInvalid = pindex;
|
chainman.m_best_invalid = pindex;
|
||||||
|
}
|
||||||
if (pindex->pprev)
|
if (pindex->pprev)
|
||||||
pindex->BuildSkip();
|
pindex->BuildSkip();
|
||||||
if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == nullptr || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
|
if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == nullptr || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
|
||||||
@ -4026,7 +4024,6 @@ bool BlockManager::LoadBlockIndex(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BlockManager::Unload() {
|
void BlockManager::Unload() {
|
||||||
m_failed_blocks.clear();
|
|
||||||
m_blocks_unlinked.clear();
|
m_blocks_unlinked.clear();
|
||||||
|
|
||||||
for (const BlockMap::value_type& entry : m_block_index) {
|
for (const BlockMap::value_type& entry : m_block_index) {
|
||||||
@ -4364,7 +4361,6 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
|
|||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
chainman.Unload();
|
chainman.Unload();
|
||||||
pindexBestInvalid = nullptr;
|
|
||||||
pindexBestHeader = nullptr;
|
pindexBestHeader = nullptr;
|
||||||
if (mempool) mempool->clear();
|
if (mempool) mempool->clear();
|
||||||
vinfoBlockFile.clear();
|
vinfoBlockFile.clear();
|
||||||
@ -5341,7 +5337,9 @@ void ChainstateManager::Unload()
|
|||||||
chainstate->UnloadBlockIndex();
|
chainstate->UnloadBlockIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_failed_blocks.clear();
|
||||||
m_blockman.Unload();
|
m_blockman.Unload();
|
||||||
|
m_best_invalid = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChainstateManager::Reset()
|
void ChainstateManager::Reset()
|
||||||
|
@ -421,26 +421,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
BlockMap m_block_index GUARDED_BY(cs_main);
|
BlockMap m_block_index GUARDED_BY(cs_main);
|
||||||
|
|
||||||
/** In order to efficiently track invalidity of headers, we keep the set of
|
|
||||||
* blocks which we tried to connect and found to be invalid here (ie which
|
|
||||||
* were set to BLOCK_FAILED_VALID since the last restart). We can then
|
|
||||||
* walk this set and check if a new header is a descendant of something in
|
|
||||||
* this set, preventing us from having to walk m_block_index when we try
|
|
||||||
* to connect a bad block and fail.
|
|
||||||
*
|
|
||||||
* While this is more complicated than marking everything which descends
|
|
||||||
* from an invalid block as invalid at the time we discover it to be
|
|
||||||
* invalid, doing so would require walking all of m_block_index to find all
|
|
||||||
* descendants. Since this case should be very rare, keeping track of all
|
|
||||||
* BLOCK_FAILED_VALID blocks in a set should be just fine and work just as
|
|
||||||
* well.
|
|
||||||
*
|
|
||||||
* Because we already walk m_block_index in height-order at startup, we go
|
|
||||||
* ahead and mark descendants of invalid blocks as FAILED_CHILD at that time,
|
|
||||||
* instead of putting things in this set.
|
|
||||||
*/
|
|
||||||
std::set<CBlockIndex*> m_failed_blocks;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
|
* All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
|
||||||
* Pruned nodes may have entries where B is missing data.
|
* Pruned nodes may have entries where B is missing data.
|
||||||
@ -470,21 +450,8 @@ public:
|
|||||||
//! Mark one block file as pruned (modify associated database entries)
|
//! Mark one block file as pruned (modify associated database entries)
|
||||||
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
/**
|
|
||||||
* If a block header hasn't already been seen, call CheckBlockHeader on it, ensure
|
|
||||||
* that it doesn't descend from an invalid block, and then add it to m_block_index.
|
|
||||||
*/
|
|
||||||
bool AcceptBlockHeader(
|
|
||||||
const CBlockHeader& block,
|
|
||||||
BlockValidationState& state,
|
|
||||||
const CChainParams& chainparams,
|
|
||||||
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
||||||
|
|
||||||
CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
/** Find the last common block between the parameter chain and a locator. */
|
|
||||||
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
||||||
|
|
||||||
//! Returns last CBlockIndex* that is a checkpoint
|
//! Returns last CBlockIndex* that is a checkpoint
|
||||||
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
@ -772,6 +739,9 @@ public:
|
|||||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||||
bool IsInitialBlockDownload() const;
|
bool IsInitialBlockDownload() const;
|
||||||
|
|
||||||
|
/** Find the last common block of this chain and a locator. */
|
||||||
|
CBlockIndex* FindForkInGlobalIndex(const CBlockLocator& locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make various assertions about the state of the block index.
|
* Make various assertions about the state of the block index.
|
||||||
*
|
*
|
||||||
@ -912,18 +882,53 @@ private:
|
|||||||
//! by the background validation chainstate.
|
//! by the background validation chainstate.
|
||||||
bool m_snapshot_validated{false};
|
bool m_snapshot_validated{false};
|
||||||
|
|
||||||
|
CBlockIndex* m_best_invalid;
|
||||||
|
friend bool BlockManager::LoadBlockIndex(const Consensus::Params&, ChainstateManager&);
|
||||||
|
|
||||||
//! Internal helper for ActivateSnapshot().
|
//! Internal helper for ActivateSnapshot().
|
||||||
[[nodiscard]] bool PopulateAndValidateSnapshot(
|
[[nodiscard]] bool PopulateAndValidateSnapshot(
|
||||||
CChainState& snapshot_chainstate,
|
CChainState& snapshot_chainstate,
|
||||||
CAutoFile& coins_file,
|
CAutoFile& coins_file,
|
||||||
const SnapshotMetadata& metadata);
|
const SnapshotMetadata& metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a block header hasn't already been seen, call CheckBlockHeader on it, ensure
|
||||||
|
* that it doesn't descend from an invalid block, and then add it to m_block_index.
|
||||||
|
*/
|
||||||
|
bool AcceptBlockHeader(
|
||||||
|
const CBlockHeader& block,
|
||||||
|
BlockValidationState& state,
|
||||||
|
const CChainParams& chainparams,
|
||||||
|
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
friend CChainState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::thread m_load_block;
|
std::thread m_load_block;
|
||||||
//! A single BlockManager instance is shared across each constructed
|
//! A single BlockManager instance is shared across each constructed
|
||||||
//! chainstate to avoid duplicating block metadata.
|
//! chainstate to avoid duplicating block metadata.
|
||||||
BlockManager m_blockman GUARDED_BY(::cs_main);
|
BlockManager m_blockman GUARDED_BY(::cs_main);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In order to efficiently track invalidity of headers, we keep the set of
|
||||||
|
* blocks which we tried to connect and found to be invalid here (ie which
|
||||||
|
* were set to BLOCK_FAILED_VALID since the last restart). We can then
|
||||||
|
* walk this set and check if a new header is a descendant of something in
|
||||||
|
* this set, preventing us from having to walk m_block_index when we try
|
||||||
|
* to connect a bad block and fail.
|
||||||
|
*
|
||||||
|
* While this is more complicated than marking everything which descends
|
||||||
|
* from an invalid block as invalid at the time we discover it to be
|
||||||
|
* invalid, doing so would require walking all of m_block_index to find all
|
||||||
|
* descendants. Since this case should be very rare, keeping track of all
|
||||||
|
* BLOCK_FAILED_VALID blocks in a set should be just fine and work just as
|
||||||
|
* well.
|
||||||
|
*
|
||||||
|
* Because we already walk m_block_index in height-order at startup, we go
|
||||||
|
* ahead and mark descendants of invalid blocks as FAILED_CHILD at that time,
|
||||||
|
* instead of putting things in this set.
|
||||||
|
*/
|
||||||
|
std::set<CBlockIndex*> m_failed_blocks;
|
||||||
|
|
||||||
//! The total number of bytes available for us to use across all in-memory
|
//! The total number of bytes available for us to use across all in-memory
|
||||||
//! coins caches. This will be split somehow across chainstates.
|
//! coins caches. This will be split somehow across chainstates.
|
||||||
int64_t m_total_coinstip_cache{0};
|
int64_t m_total_coinstip_cache{0};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user