You're looking for validation.h
and its corresponding .cpp source file.
You should start at CChainState::ActivateBestChain
. This subroutine calls CChainState::ActivateBestChainStep
which runs the logic you're interested in - stepping one by one of the blocks, cleaning up and reorg'ing from lowest to highest PoW.
First, ActivateBestChainStep
walks the chain in a while
loop: while (m_chain.Tip() && m_chain.Tip() != pindexFork)
cleaning up blocks which are not in the best chain using DisconnectTip(state, chainparams, &disconnectpool)
. This partly answers your question - all the blocks which aren't in the best chain are weeded out here.
It then walks through the current CBlockIndex
organizing blocks using the next while loop: while (fContinue && nHeight != pindexMostWork->nHeight)
. pindexMostWork
is a CBlockIndex
that contains the blocks with most work. Inside there is a loop which selects the blocks it should connect to the best chain: while (pindexIter && pindexIter->nHeight != nHeight)
. It pushes the candidate blocks onto a locally allocated vector std::vector<CBlockIndex*> vpindexToConnect;
.
Next it iterates this new vector in reverse, pushing the blocks with lowest work first: for (CBlockIndex *pindexConnect : reverse_iterate(vpindexToConnect))
connecting each to the tip. The last connected block will be the block with the highest work index. This builds a chain sorted from lowest to highest work.
Several places in the code call ActivateBestChain
, among them:
invalidateblock
and reconsiderblock
in rpc/blockchain.cpp
ThreadImport
in init.cpp
ProcessGetBlockData
and Processmessage
in net_processing.cpp
- Several subroutines in
validation.cpp
itself
You can use any of the above to trace how and when a new best chain is activated. I think the most interesting ones are in net_processing.cpp
as those are the ones triggered by messages received from the network.