Skip to content

Commit

Permalink
merge bitcoin#23785: Move stuff to ChainstateManager
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Jul 19, 2024
1 parent b402fd5 commit 732e871
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 82 deletions.
2 changes: 1 addition & 1 deletion src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool BaseIndex::Init()
if (locator.IsNull()) {
m_best_block_index = nullptr;
} else {
m_best_block_index = m_chainstate->m_blockman.FindForkInGlobalIndex(active_chain, locator);
m_best_block_index = m_chainstate->FindForkInGlobalIndex(locator);
}

// Note: this will latch to true immediately if the user starts up with an empty
Expand Down
4 changes: 2 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3934,7 +3934,7 @@ void PeerManagerImpl::ProcessMessage(
LOCK(cs_main);

// 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
if (pindex)
Expand Down Expand Up @@ -4054,7 +4054,7 @@ void PeerManagerImpl::ProcessMessage(
else
{
// 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)
pindex = m_chainman.ActiveChain().Next(pindex);
}
Expand Down
4 changes: 2 additions & 2 deletions src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,8 +762,8 @@ class ChainImpl : public Chain
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
{
LOCK(cs_main);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) {
const CChainState& active = Assert(m_node.chainman)->ActiveChainstate();
if (CBlockIndex* fork = active.FindForkInGlobalIndex(locator)) {
return fork->nHeight;
}
return std::nullopt;
Expand Down
87 changes: 43 additions & 44 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,6 @@ arith_uint256 nMinimumChainWork;

CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);

// Internal stuff
namespace {
CBlockIndex* pindexBestInvalid = nullptr;
} // namespace

// Internal stuff from blockstorage ...
extern RecursiveMutex cs_LastBlockFile;
extern std::vector<CBlockFileInfo> vinfoBlockFile;
Expand All @@ -164,20 +159,21 @@ CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
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);

// Find the latest block common to locator and chain - we expect that
// locator.vHave is sorted descending by height.
for (const uint256& hash : locator.vHave) {
CBlockIndex* pindex = LookupBlockIndex(hash);
CBlockIndex* pindex{m_blockman.LookupBlockIndex(hash)};
if (pindex) {
if (chain.Contains(pindex))
if (m_chain.Contains(pindex)) {
return pindex;
}
}
}
return chain.Genesis();
return m_chain.Genesis();
}

bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr);
Expand Down Expand Up @@ -1319,7 +1315,7 @@ void CChainState::CheckForkWarningConditions()
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 which has higher work (at least ~6 blocks worth of work) than our best chain.\nChain state database corruption likely.\n", __func__);
SetfLargeWorkInvalidChainFound(true);
} else {
Expand All @@ -1333,8 +1329,9 @@ void CChainState::InvalidChainFound(CBlockIndex* pindexNew)

statsClient.inc("warnings.InvalidChainFound", 1.0f);

if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
pindexBestInvalid = pindexNew;
if (!m_chainman.m_best_invalid || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork) {
m_chainman.m_best_invalid = pindexNew;
}
if (pindexBestHeader != nullptr && pindexBestHeader->GetAncestor(pindexNew->nHeight) == pindexNew) {
pindexBestHeader = m_chain.Tip();
}
Expand Down Expand Up @@ -1373,7 +1370,7 @@ void CChainState::InvalidBlockFound(CBlockIndex *pindex, const BlockValidationSt
statsClient.inc("warnings.InvalidBlockFound", 1.0f);
if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID;
m_blockman.m_failed_blocks.insert(pindex);
m_chainman.m_failed_blocks.insert(pindex);
setDirtyBlockIndex.insert(pindex);
setBlockIndexCandidates.erase(pindex);
InvalidChainFound(pindex);
Expand Down Expand Up @@ -2814,8 +2811,9 @@ CBlockIndex* CChainState::FindMostWorkChain() {
bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
if (fFailedChain || fMissingData || fConflictingChain) {
// Candidate chain is not usable (either invalid or conflicting or missing data)
if (fFailedChain && (pindexBestInvalid == nullptr || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
pindexBestInvalid = pindexNew;
if (fFailedChain && (m_chainman.m_best_invalid == nullptr || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork)) {
m_chainman.m_best_invalid = pindexNew;
}
CBlockIndex *pindexFailed = pindexNew;
// Remove the entire chain from the set.
while (pindexTest != pindexFailed) {
Expand Down Expand Up @@ -3181,7 +3179,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
const CBlockIndex* pindexOldTip = m_chain.Tip();

if (pindex == pindexBestHeader) {
pindexBestInvalid = pindexBestHeader;
m_chainman.m_best_invalid = pindexBestHeader;
pindexBestHeader = pindexBestHeader->pprev;
}

Expand All @@ -3199,7 +3197,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
assert(invalid_walk_tip->pprev == m_chain.Tip());

if (pindexOldTip == pindexBestHeader) {
pindexBestInvalid = pindexBestHeader;
m_chainman.m_best_invalid = pindexBestHeader;
pindexBestHeader = pindexBestHeader->pprev;
}

Expand Down Expand Up @@ -3248,7 +3246,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(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
// (above), then the pre-calculation of what should go into
Expand Down Expand Up @@ -3382,10 +3380,10 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
AssertLockHeld(cs_main);

if (!pindex) {
if (pindexBestInvalid && pindexBestInvalid->GetAncestor(m_chain.Height()) == m_chain.Tip()) {
if (m_chainman.m_best_invalid && m_chainman.m_best_invalid->GetAncestor(m_chain.Height()) == m_chain.Tip()) {
LogPrintf("%s: the best known invalid block (%s) is ahead of our tip, reconsidering\n",
__func__, pindexBestInvalid->GetBlockHash().ToString());
pindex = pindexBestInvalid;
__func__, m_chainman.m_best_invalid->GetBlockHash().ToString());
pindex = m_chainman.m_best_invalid;
} else {
return;
}
Expand All @@ -3402,11 +3400,11 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && !(it->second->nStatus & BLOCK_CONFLICT_CHAINLOCK) && it->second->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), 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.
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++;
}
Expand All @@ -3419,17 +3417,17 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && !(pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK) && pindex->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), pindex)) {
setBlockIndexCandidates.insert(pindex);
}
if (pindex == pindexBestInvalid) {
if (pindex == m_chainman.m_best_invalid) {
// 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(pindex);
m_chainman.m_failed_blocks.erase(pindex);
// Mark all nearest BLOCK_FAILED_CHILD descendants (if any) as BLOCK_FAILED_VALID
auto itp = m_blockman.m_prev_block_index.equal_range(pindex->GetBlockHash());
for (auto jt = itp.first; jt != itp.second; ++jt) {
if (jt->second->nStatus & BLOCK_FAILED_CHILD) {
jt->second->nStatus |= BLOCK_FAILED_VALID;
m_blockman.m_failed_blocks.insert(jt->second);
m_chainman.m_failed_blocks.insert(jt->second);
setDirtyBlockIndex.insert(jt->second);
setBlockIndexCandidates.erase(jt->second);
}
Expand Down Expand Up @@ -3769,16 +3767,16 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
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);
// Check for duplicate
uint256 hash = block.GetHash();
BlockMap::iterator miSelf = m_block_index.find(hash);

// TODO : ENABLE BLOCK CACHE IN SPECIFIC CASES
BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
if (miSelf != m_block_index.end()) {
if (miSelf != m_blockman.m_block_index.end()) {
// Block header is already known.
CBlockIndex* pindex = miSelf->second;
if (ppindex)
Expand All @@ -3801,8 +3799,8 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS

// Get prev block index
CBlockIndex* pindexPrev = nullptr;
BlockMap::iterator mi = m_block_index.find(block.hashPrevBlock);
if (mi == m_block_index.end()) {
BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)};
if (mi == m_blockman.m_block_index.end()) {
LogPrintf("ERROR: %s: prev block not found\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found");
}
Expand All @@ -3820,8 +3818,9 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-prevblk-chainlock");
}

if (!ContextualCheckBlockHeader(block, state, *this, chainparams, pindexPrev, GetAdjustedTime()))
if (!ContextualCheckBlockHeader(block, state, m_blockman, chainparams, pindexPrev, GetAdjustedTime())) {
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), state.ToString());
}

/* Determine if this block descends from any block which has been found
* invalid (m_failed_blocks), then mark pindexPrev and any blocks between
Expand Down Expand Up @@ -3863,14 +3862,14 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
}

if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
if (miSelf == m_block_index.end()) {
AddToBlockIndex(block, hash, BLOCK_CONFLICT_CHAINLOCK);
if (miSelf == m_blockman.m_block_index.end()) {
m_blockman.AddToBlockIndex(block, hash, BLOCK_CONFLICT_CHAINLOCK);
}
LogPrintf("ERROR: %s: header %s conflicts with chainlock\n", __func__, hash.ToString());
return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-chainlock");
}
}
CBlockIndex* pindex = AddToBlockIndex(block, hash);
CBlockIndex* pindex{m_blockman.AddToBlockIndex(block, hash)};

if (ppindex)
*ppindex = pindex;
Expand All @@ -3889,8 +3888,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
LOCK(cs_main);
for (const CBlockHeader& header : headers) {
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
bool accepted = m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex);
bool accepted{AcceptBlockHeader(header, state, chainparams, &pindex)};
ActiveChainstate().CheckBlockIndex();

if (!accepted) {
Expand Down Expand Up @@ -3925,7 +3923,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
CBlockIndex *pindexDummy = nullptr;
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();

if (!accepted_header)
Expand Down Expand Up @@ -4348,8 +4346,9 @@ bool BlockManager::LoadBlockIndex(
}
}
}
if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
pindexBestInvalid = pindex;
if (pindex->nStatus & BLOCK_FAILED_MASK && (!chainman.m_best_invalid || pindex->nChainWork > chainman.m_best_invalid->nChainWork)) {
chainman.m_best_invalid = pindex;
}
if (pindex->pprev)
pindex->BuildSkip();
if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == nullptr || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
Expand All @@ -4360,7 +4359,6 @@ bool BlockManager::LoadBlockIndex(
}

void BlockManager::Unload() {
m_failed_blocks.clear();
m_blocks_unlinked.clear();

for (const BlockMap::value_type& entry : m_block_index) {
Expand Down Expand Up @@ -4790,7 +4788,6 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
{
LOCK(cs_main);
chainman.Unload();
pindexBestInvalid = nullptr;
pindexBestHeader = nullptr;
if (mempool) mempool->clear();
vinfoBlockFile.clear();
Expand Down Expand Up @@ -5808,7 +5805,9 @@ void ChainstateManager::Unload()
chainstate->UnloadBlockIndex();
}

m_failed_blocks.clear();
m_blockman.Unload();
m_best_invalid = nullptr;
}

void ChainstateManager::Reset()
Expand Down
Loading

0 comments on commit 732e871

Please sign in to comment.