LoadChainTip requires cs_main to be locked. Under some conditions, it may call ActivateBestChain. However, ActivateBestChain requires cs_main NOT to be taken when called.
return g_chainstate.ReplayBlocks(params, view);
}
void CChainState::EraseBlockData(CBlockIndex* index)
{
    AssertLockHeld(cs_main);
    assert(!m_chain.Contains(index)); 
    
    index->nStatus = std::min<unsigned int>(index->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) | (index->nStatus & ~BLOCK_VALID_MASK);
    
    index->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
    
    index->nFile = 0;
    index->nDataPos = 0;
    index->nUndoPos = 0;
    
    index->nTx = 0;
    index->nChainTx = 0;
    index->nSequenceId = 0;
    
    setDirtyBlockIndex.insert(index);
    
    setBlockIndexCandidates.erase(index);
    std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> ret = mapBlocksUnlinked.equal_range(index->pprev);
    while (ret.first != ret.second) {
        if (ret.first->second == index) {
            mapBlocksUnlinked.erase(ret.first++);
        } else {