diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -92,6 +92,38 @@ */ CCriticalSection m_cs_chainstate; + /** + * Every received block is assigned a unique and increasing identifier, so + * we know which one to give priority in case of a fork. + * Blocks loaded from disk are assigned id 0, so start the counter at 1. + */ + std::atomic nBlockSequenceId{1}; + /** Decreasing counter (used by subsequent preciousblock calls). */ + int32_t nBlockReverseSequenceId = -1; + /** chainwork for the last block that preciousblock has been applied to. */ + arith_uint256 nLastPreciousChainwork = 0; + + /** + * In order to efficiently track invalidity of headers, we keep the set of + * blocks which we tried to connect and found to be invalid here (ie which + * were set to BLOCK_FAILED_VALID since the last restart). We can then + * walk this set and check if a new header is a descendant of something in + * this set, preventing us from having to walk mapBlockIndex when we try + * to connect a bad block and fail. + * + * While this is more complicated than marking everything which descends + * from an invalid block as invalid at the time we discover it to be + * invalid, doing so would require walking all of mapBlockIndex to find all + * descendants. Since this case should be very rare, keeping track of all + * BLOCK_FAILED_VALID blocks in a set should be just fine and work just as + * well. + * + * Because we already walk mapBlockIndex in height-order at startup, we go + * ahead and mark descendants of invalid blocks as FAILED_CHILD at that + * time, instead of putting things in this set. + */ + std::set g_failed_blocks; + public: CChain chainActive; BlockMap mapBlockIndex; @@ -238,38 +270,6 @@ */ bool fCheckForPruning = false; -/** - * Every received block is assigned a unique and increasing identifier, so we - * know which one to give priority in case of a fork. - * Blocks loaded from disk are assigned id 0, so start the counter at 1. - */ -std::atomic nBlockSequenceId{1}; -/** Decreasing counter (used by subsequent preciousblock calls). */ -int32_t nBlockReverseSequenceId = -1; -/** chainwork for the last block that preciousblock has been applied to. */ -arith_uint256 nLastPreciousChainwork = 0; - -/** - * In order to efficiently track invalidity of headers, we keep the set of - * blocks which we tried to connect and found to be invalid here (ie which - * were set to BLOCK_FAILED_VALID since the last restart). We can then - * walk this set and check if a new header is a descendant of something in - * this set, preventing us from having to walk mapBlockIndex when we try - * to connect a bad block and fail. - * - * While this is more complicated than marking everything which descends - * from an invalid block as invalid at the time we discover it to be - * invalid, doing so would require walking all of mapBlockIndex to find all - * descendants. Since this case should be very rare, keeping track of all - * BLOCK_FAILED_VALID blocks in a set should be just fine and work just as - * well. - * - * Because we already walk mapBlockIndex in height-order at startup, we go - * ahead and mark descendants of invalid blocks as FAILED_CHILD at that time, - * instead of putting things in this set. - */ -std::set g_failed_blocks; - /** Dirty block index entries. */ std::set setDirtyBlockIndex; @@ -2125,13 +2125,8 @@ FlushStateToDisk(chainparams, state, FlushStateMode::NONE); } -/** - * Update chainActive and related internal data structures when adding a new - * block to the chain tip. - */ +/** Check warning conditions and do some notifications on new chain tip set. */ static void UpdateTip(const Config &config, CBlockIndex *pindexNew) { - chainActive.SetTip(pindexNew); - // New best block g_mempool.AddTransactionsUpdated(1); @@ -2141,17 +2136,16 @@ g_best_block_cv.notify_all(); } - LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu " - "date='%s' progress=%f cache=%.1fMiB(%utxo)\n", - __func__, chainActive.Tip()->GetBlockHash().ToString(), - chainActive.Height(), chainActive.Tip()->nVersion, - log(chainActive.Tip()->nChainWork.getdouble()) / log(2.0), - (unsigned long)chainActive.Tip()->nChainTx, - FormatISO8601DateTime(chainActive.Tip()->GetBlockTime()), - GuessVerificationProgress(config.GetChainParams().TxData(), - chainActive.Tip()), - pcoinsTip->DynamicMemoryUsage() * (1.0 / (1 << 20)), - pcoinsTip->GetCacheSize()); + LogPrintf( + "%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu " + "date='%s' progress=%f cache=%.1fMiB(%utxo)\n", + __func__, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, + pindexNew->nVersion, log(pindexNew->nChainWork.getdouble()) / log(2.0), + (unsigned long)pindexNew->nChainTx, + FormatISO8601DateTime(pindexNew->GetBlockTime()), + GuessVerificationProgress(config.GetChainParams().TxData(), pindexNew), + pcoinsTip->DynamicMemoryUsage() * (1.0 / (1 << 20)), + pcoinsTip->GetCacheSize()); } /** @@ -2223,6 +2217,8 @@ pindexFinalized = pindexDelete->pprev; } + chainActive.SetTip(pindexDelete->pprev); + // Update chainActive and related variables. UpdateTip(config, pindexDelete->pprev); // Let wallets know transactions went from 1-confirmed to @@ -2494,6 +2490,7 @@ } // Update chainActive & related variables. + chainActive.SetTip(pindexNew); UpdateTip(config, pindexNew); int64_t nTime6 = GetTimeMicros(); @@ -4932,6 +4929,8 @@ // May NOT be used after any connections are up as much of the peer-processing // logic assumes a consistent block index state void CChainState::UnloadBlockIndex() { + nBlockSequenceId = 1; + g_failed_blocks.clear(); setBlockIndexCandidates.clear(); } @@ -4951,9 +4950,7 @@ mapBlocksUnlinked.clear(); vinfoBlockFile.clear(); nLastBlockFile = 0; - nBlockSequenceId = 1; setDirtyBlockIndex.clear(); - g_failed_blocks.clear(); setDirtyFileInfo.clear(); for (BlockMap::value_type &entry : mapBlockIndex) {