* Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */
| 2895 | * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. |
| 2896 | */ |
| 2897 | static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock, const BlockSource& blockSource, bool& fInvalidFound) { |
| 2898 | AssertLockHeld(cs_main); |
| 2899 | const CBlockIndex *pindexOldTip = chainActive.Tip(); |
| 2900 | const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); |
| 2901 | |
| 2902 | // Disconnect active blocks which are no longer in the best chain. |
| 2903 | bool fBlocksDisconnected = false; |
| 2904 | while (chainActive.Tip() && chainActive.Tip() != pindexFork) { |
| 2905 | if (!DisconnectTip(state)) |
| 2906 | return false; |
| 2907 | fBlocksDisconnected = true; |
| 2908 | } |
| 2909 | |
| 2910 | // Build list of new blocks to connect. |
| 2911 | std::vector<CBlockIndex*> vpindexToConnect; |
| 2912 | bool fContinue = true; |
| 2913 | int nHeight = pindexFork ? pindexFork->nHeight : -1; |
| 2914 | while (fContinue && nHeight != pindexMostWork->nHeight) { |
| 2915 | // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need |
| 2916 | // a few blocks along the way. |
| 2917 | int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); |
| 2918 | vpindexToConnect.clear(); |
| 2919 | vpindexToConnect.reserve(nTargetHeight - nHeight); |
| 2920 | CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); |
| 2921 | while (pindexIter && pindexIter->nHeight != nHeight) { |
| 2922 | vpindexToConnect.push_back(pindexIter); |
| 2923 | pindexIter = pindexIter->pprev; |
| 2924 | } |
| 2925 | nHeight = nTargetHeight; |
| 2926 | |
| 2927 | // Connect new blocks. |
| 2928 | BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
| 2929 | CBlock* mostWork = pindexConnect == pindexMostWork ? pblock : nullptr; |
| 2930 | if (!ConnectTip(state, pindexConnect, mostWork, blockSource)) { |
| 2931 | if (state.IsInvalid()) { |
| 2932 | // The block violates a consensus rule. |
| 2933 | if (!state.CorruptionPossible()) |
| 2934 | InvalidChainFound(vpindexToConnect.back()); |
| 2935 | state = CValidationState(); |
| 2936 | fInvalidFound = true; |
| 2937 | fContinue = false; |
| 2938 | break; |
| 2939 | } else { |
| 2940 | // A system error occurred (disk space, database error, ...). |
| 2941 | return false; |
| 2942 | } |
| 2943 | } else { |
| 2944 | PruneBlockIndexCandidates(); |
| 2945 | if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { |
| 2946 | // We're in a better position than we were. Return temporarily to release the lock. |
| 2947 | fContinue = false; |
| 2948 | break; |
| 2949 | } |
| 2950 | } |
| 2951 | } |
| 2952 | } |
| 2953 | |
| 2954 | // If we reorged back across the UAHF, clear the pool to be sure it doesn't contain tx invalid before the fork |
no test coverage detected