Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,226 Lines • ▼ Show 20 Lines | void NotifyEntryRemoved(CTransactionRef txRemoved, | ||||
assert(!blocksConnected.back().pindex); | assert(!blocksConnected.back().pindex); | ||||
if (reason == MemPoolRemovalReason::CONFLICT) { | if (reason == MemPoolRemovalReason::CONFLICT) { | ||||
blocksConnected.back().conflictedTxs->emplace_back( | blocksConnected.back().conflictedTxs->emplace_back( | ||||
std::move(txRemoved)); | std::move(txRemoved)); | ||||
} | } | ||||
} | } | ||||
}; | }; | ||||
static bool FinalizeBlockInternal(const Config &config, CValidationState &state, | bool CChainState::MarkBlockAsFinal(const Config &config, | ||||
const CBlockIndex *pindex) | CValidationState &state, | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | const CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (pindex->nStatus.isInvalid()) { | if (pindex->nStatus.isInvalid()) { | ||||
// We try to finalize an invalid block. | // We try to finalize an invalid block. | ||||
LogPrintf("ERROR: %s: Trying to finalize invalid block %s\n", __func__, | LogPrintf("ERROR: %s: Trying to finalize invalid block %s\n", __func__, | ||||
pindex->GetBlockHash().ToString()); | pindex->GetBlockHash().ToString()); | ||||
return state.Invalid(ValidationInvalidReason::CACHED_INVALID, | return state.Invalid(ValidationInvalidReason::CACHED_INVALID, | ||||
REJECT_INVALID, "finalize-invalid-block"); | REJECT_INVALID, "finalize-invalid-block"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", | ||||
pindexNew->GetBlockHash().ToString(), | pindexNew->GetBlockHash().ToString(), | ||||
FormatStateMessage(state)); | FormatStateMessage(state)); | ||||
} | } | ||||
// Update the finalized block. | // Update the finalized block. | ||||
const CBlockIndex *pindexToFinalize = | const CBlockIndex *pindexToFinalize = | ||||
FindBlockToFinalize(config, pindexNew); | FindBlockToFinalize(config, pindexNew); | ||||
if (pindexToFinalize && | if (pindexToFinalize && | ||||
!FinalizeBlockInternal(config, state, pindexToFinalize)) { | !MarkBlockAsFinal(config, state, pindexToFinalize)) { | ||||
return error("ConnectTip(): FinalizeBlock %s failed (%s)", | return error("ConnectTip(): MarkBlockAsFinal %s failed (%s)", | ||||
pindexNew->GetBlockHash().ToString(), | pindexNew->GetBlockHash().ToString(), | ||||
FormatStateMessage(state)); | FormatStateMessage(state)); | ||||
} | } | ||||
nTime3 = GetTimeMicros(); | nTime3 = GetTimeMicros(); | ||||
nTimeConnectTotal += nTime3 - nTime2; | nTimeConnectTotal += nTime3 - nTime2; | ||||
LogPrint(BCLog::BENCH, | LogPrint(BCLog::BENCH, | ||||
" - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", | " - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", | ||||
▲ Show 20 Lines • Show All 518 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool ActivateBestChain(const Config &config, CValidationState &state, | bool ActivateBestChain(const Config &config, CValidationState &state, | ||||
std::shared_ptr<const CBlock> pblock) { | std::shared_ptr<const CBlock> pblock) { | ||||
return ::ChainstateActive().ActivateBestChain(config, state, | return ::ChainstateActive().ActivateBestChain(config, state, | ||||
std::move(pblock)); | std::move(pblock)); | ||||
} | } | ||||
bool CChainState::FinalizeBlock(const Config &config, CValidationState &state, | |||||
CBlockIndex *pindex) { | |||||
AssertLockHeld(cs_main); | |||||
if (!MarkBlockAsFinal(config, state, pindex)) { | |||||
// state is set by MarkBlockAsFinal. | |||||
return false; | |||||
} | |||||
// We have a valid candidate, make sure it is not parked. | |||||
if (pindex->nStatus.isOnParkedChain()) { | |||||
UnparkBlock(pindex); | |||||
} | |||||
// If the finalized block is not on the active chain, we may need to rewind. | |||||
if (!::ChainActive().Contains(pindex)) { | |||||
const CBlockIndex *pindexFork = ::ChainActive().FindFork(pindex); | |||||
CBlockIndex *pindexToInvalidate = ::ChainActive().Next(pindexFork); | |||||
if (pindexToInvalidate) { | |||||
return InvalidateBlock(config, state, pindexToInvalidate); | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
bool CChainState::PreciousBlock(const Config &config, CValidationState &state, | bool CChainState::PreciousBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) { | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (pindex->nChainWork < m_chain.Tip()->nChainWork) { | if (pindex->nChainWork < m_chain.Tip()->nChainWork) { | ||||
// Nothing to do, this block is not at the tip. | // Nothing to do, this block is not at the tip. | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | bool CChainState::UnwindBlock(const Config &config, CValidationState &state, | ||||
// Only notify about a new block tip if the active chain was modified. | // Only notify about a new block tip if the active chain was modified. | ||||
if (pindex_was_in_chain) { | if (pindex_was_in_chain) { | ||||
uiInterface.NotifyBlockTip(IsInitialBlockDownload(), | uiInterface.NotifyBlockTip(IsInitialBlockDownload(), | ||||
to_mark_failed_or_parked->pprev); | to_mark_failed_or_parked->pprev); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state, | |||||
CBlockIndex *pindex) { | |||||
AssertLockHeld(cs_main); | |||||
if (!FinalizeBlockInternal(config, state, pindex)) { | |||||
// state is set by FinalizeBlockInternal. | |||||
return false; | |||||
} | |||||
// We have a valid candidate, make sure it is not parked. | |||||
if (pindex->nStatus.isOnParkedChain()) { | |||||
UnparkBlock(pindex); | |||||
} | |||||
// If the finalized block is not on the active chain, we may need to rewind. | |||||
if (!::ChainActive().Contains(pindex)) { | |||||
const CBlockIndex *pindexFork = ::ChainActive().FindFork(pindex); | |||||
CBlockIndex *pindexToInvalidate = ::ChainActive().Next(pindexFork); | |||||
if (pindexToInvalidate) { | |||||
return InvalidateBlock(config, state, pindexToInvalidate); | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
bool InvalidateBlock(const Config &config, CValidationState &state, | bool InvalidateBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) { | ||||
return ::ChainstateActive().UnwindBlock(config, state, pindex, true); | return ::ChainstateActive().UnwindBlock(config, state, pindex, true); | ||||
} | } | ||||
bool ParkBlock(const Config &config, CValidationState &state, | bool ParkBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) { | ||||
return ::ChainstateActive().UnwindBlock(config, state, pindex, false); | return ::ChainstateActive().UnwindBlock(config, state, pindex, false); | ||||
▲ Show 20 Lines • Show All 2,545 Lines • Show Last 20 Lines |