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

Method ActivateBestChainStep

src/validation.cpp:3063–3152  ·  view source on GitHub ↗

* Try to make some progress towards making pindexMostWork the active block. * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork. * * @returns true unless a system error occurred */

Source from the content-addressed store, hash-verified

3061 * @returns true unless a system error occurred
3062 */
3063bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace, bool& fStall)
3064{
3065 AssertLockHeld(cs_main);
3066 if (m_mempool) AssertLockHeld(m_mempool->cs);
3067
3068 const CBlockIndex* pindexOldTip = m_chain.Tip();
3069 const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork);
3070
3071 // Disconnect active blocks which are no longer in the best chain.
3072 bool fBlocksDisconnected = false;
3073 DisconnectedBlockTransactions disconnectpool;
3074 while (m_chain.Tip() && m_chain.Tip() != pindexFork) {
3075 if (!DisconnectTip(state, &disconnectpool)) {
3076 // This is likely a fatal error, but keep the mempool consistent,
3077 // just in case. Only remove from the mempool in this case.
3078 MaybeUpdateMempoolForReorg(disconnectpool, false);
3079
3080 // If we're unable to disconnect a block during normal operation,
3081 // then that is a failure of our local system -- we should abort
3082 // rather than stay on a less work chain.
3083 AbortNode(state, "Failed to disconnect block; see debug.log for details");
3084 return false;
3085 }
3086 fBlocksDisconnected = true;
3087 }
3088
3089 // Build list of new blocks to connect (in descending height order).
3090 std::vector<CBlockIndex*> vpindexToConnect;
3091 bool fContinue = true;
3092 int nHeight = pindexFork ? pindexFork->nHeight : -1;
3093 while (fContinue && nHeight != pindexMostWork->nHeight) {
3094 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3095 // a few blocks along the way.
3096 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
3097 vpindexToConnect.clear();
3098 vpindexToConnect.reserve(nTargetHeight - nHeight);
3099 CBlockIndex* pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3100 while (pindexIter && pindexIter->nHeight != nHeight) {
3101 vpindexToConnect.push_back(pindexIter);
3102 pindexIter = pindexIter->pprev;
3103 }
3104 nHeight = nTargetHeight;
3105
3106 // Connect new blocks.
3107 for (CBlockIndex* pindexConnect : reverse_iterate(vpindexToConnect)) {
3108 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool, fStall)) {
3109 if (state.IsInvalid()) {
3110 // The block violates a consensus rule.
3111 if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
3112 InvalidChainFound(vpindexToConnect.front());
3113 }
3114 state = BlockValidationState();
3115 fInvalidFound = true;
3116 fContinue = false;
3117 break;
3118 } else {
3119 // A system error occurred (disk space, database error, ...).
3120 // Make the mempool consistent with the current tip, just in case

Callers

nothing calls this directly

Calls 13

reverse_iterateFunction · 0.85
FindForkMethod · 0.80
GetAncestorMethod · 0.80
IsInvalidMethod · 0.80
GetResultMethod · 0.80
HeightMethod · 0.80
AbortNodeFunction · 0.70
TipMethod · 0.45
clearMethod · 0.45
reserveMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected