MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ActivateBestChainStep

Method ActivateBestChainStep

src/validation.cpp:3201–3284  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

3199 * @returns true unless a system error occurred
3200 */
3201bool Chainstate::ActivateBestChainStep(BlockValidationState& state, CBlockIndex& index_most_work, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, std::vector<ConnectedBlock>& connected_blocks)
3202{
3203 AssertLockHeld(cs_main);
3204 if (m_mempool) AssertLockHeld(m_mempool->cs);
3205
3206 const CBlockIndex* pindexOldTip = m_chain.Tip();
3207 const CBlockIndex* pindexFork = m_chain.FindFork(index_most_work);
3208
3209 // Disconnect active blocks which are no longer in the best chain.
3210 bool fBlocksDisconnected = false;
3211 DisconnectedBlockTransactions disconnectpool{MAX_DISCONNECTED_TX_POOL_BYTES};
3212 while (m_chain.Tip() && m_chain.Tip() != pindexFork) {
3213 if (!DisconnectTip(state, &disconnectpool)) {
3214 // This is likely a fatal error, but keep the mempool consistent,
3215 // just in case. Only remove from the mempool in this case.
3216 MaybeUpdateMempoolForReorg(disconnectpool, false);
3217
3218 // If we're unable to disconnect a block during normal operation,
3219 // then that is a failure of our local system -- we should abort
3220 // rather than stay on a less work chain.
3221 FatalError(m_chainman.GetNotifications(), state, _("Failed to disconnect block."));
3222 return false;
3223 }
3224 fBlocksDisconnected = true;
3225 }
3226
3227 // Build list of new blocks to connect (in descending height order).
3228 std::vector<CBlockIndex*> vpindexToConnect;
3229 bool fContinue = true;
3230 int nHeight = pindexFork ? pindexFork->nHeight : -1;
3231 while (fContinue && nHeight != index_most_work.nHeight) {
3232 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3233 // a few blocks along the way.
3234 int nTargetHeight = std::min(nHeight + 32, index_most_work.nHeight);
3235 vpindexToConnect.clear();
3236 vpindexToConnect.reserve(nTargetHeight - nHeight);
3237 CBlockIndex* pindexIter = index_most_work.GetAncestor(nTargetHeight);
3238 while (pindexIter && pindexIter->nHeight != nHeight) {
3239 vpindexToConnect.push_back(pindexIter);
3240 pindexIter = pindexIter->pprev;
3241 }
3242 nHeight = nTargetHeight;
3243
3244 // Connect new blocks.
3245 for (CBlockIndex* pindexConnect : vpindexToConnect | std::views::reverse) {
3246 if (!ConnectTip(state, pindexConnect, pindexConnect == &index_most_work ? pblock : std::shared_ptr<const CBlock>(), connected_blocks, disconnectpool)) {
3247 if (state.IsInvalid()) {
3248 // The block violates a consensus rule.
3249 if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
3250 InvalidChainFound(vpindexToConnect.front());
3251 }
3252 state = BlockValidationState();
3253 fInvalidFound = true;
3254 fContinue = false;
3255 break;
3256 } else {
3257 // A system error occurred (disk space, database error, ...).
3258 // Make the mempool consistent with the current tip, just in case

Callers

nothing calls this directly

Calls 14

FatalErrorFunction · 0.85
_Function · 0.85
FindForkMethod · 0.80
IsInvalidMethod · 0.80
GetResultMethod · 0.80
HeightMethod · 0.80
TipMethod · 0.45
clearMethod · 0.45
reserveMethod · 0.45
GetAncestorMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected