MCPcopy Create free account
hub / github.com/ElementsProject/elements / InvalidateBlock

Method InvalidateBlock

src/validation.cpp:3336–3479  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3334}
3335
3336bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex)
3337{
3338 AssertLockNotHeld(m_chainstate_mutex);
3339 AssertLockNotHeld(::cs_main);
3340
3341 // Genesis block can't be invalidated
3342 assert(pindex);
3343 if (pindex->nHeight == 0) return false;
3344
3345 CBlockIndex* to_mark_failed = pindex;
3346 bool pindex_was_in_chain = false;
3347 int disconnected = 0;
3348
3349 // We do not allow ActivateBestChain() to run while InvalidateBlock() is
3350 // running, as that could cause the tip to change while we disconnect
3351 // blocks.
3352 LOCK(m_chainstate_mutex);
3353
3354 // We'll be acquiring and releasing cs_main below, to allow the validation
3355 // callbacks to run. However, we should keep the block index in a
3356 // consistent state as we disconnect blocks -- in particular we need to
3357 // add equal-work blocks to setBlockIndexCandidates as we disconnect.
3358 // To avoid walking the block index repeatedly in search of candidates,
3359 // build a map once so that we can look up candidate blocks by chain
3360 // work as we go.
3361 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
3362
3363 {
3364 LOCK(cs_main);
3365 for (const auto& entry : m_blockman.m_block_index) {
3366 CBlockIndex *candidate = entry.second;
3367 // We don't need to put anything in our active chain into the
3368 // multimap, because those candidates will be found and considered
3369 // as we disconnect.
3370 // Instead, consider only non-active-chain blocks that have at
3371 // least as much work as where we expect the new tip to end up.
3372 if (!m_chain.Contains(candidate) &&
3373 !CBlockIndexWorkComparator()(candidate, pindex->pprev) &&
3374 candidate->IsValid(BLOCK_VALID_TRANSACTIONS) &&
3375 candidate->HaveTxsDownloaded()) {
3376 candidate_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate));
3377 }
3378 }
3379 }
3380
3381 // Disconnect (descendants of) pindex, and mark them invalid.
3382 while (true) {
3383 if (ShutdownRequested()) break;
3384
3385 // Make sure the queue of validation callbacks doesn't grow unboundedly.
3386 LimitValidationInterfaceQueue();
3387
3388 LOCK(cs_main);
3389 // Lock for as long as disconnectpool is in scope to make sure MaybeUpdateMempoolForReorg is
3390 // called after DisconnectTip without unlocking in between
3391 LOCK(MempoolMutex());
3392 if (!m_chain.Contains(pindex)) break;
3393 pindex_was_in_chain = true;

Callers 2

BOOST_AUTO_TEST_CASEFunction · 0.80
invalidateblockFunction · 0.80

Calls 13

ShutdownRequestedFunction · 0.85
GetSynchronizationStateFunction · 0.85
HaveTxsDownloadedMethod · 0.80
lower_boundMethod · 0.80
NotifyBlockTipMethod · 0.80
ContainsMethod · 0.45
IsValidMethod · 0.45
insertMethod · 0.45
TipMethod · 0.45
eraseMethod · 0.45
endMethod · 0.45

Tested by 1

BOOST_AUTO_TEST_CASEFunction · 0.64