From 0ec16f35d6b8d9f1fe876f1405f105f6e5aa0933 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 16 Nov 2013 18:40:55 +0100 Subject: [PATCH] Move only: extract WriteChainState and UpdatedTip from SetBestChain. --- src/main.cpp | 123 ++++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8c60a26b38..6e1919c9a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1746,6 +1746,66 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C return true; } +bool static WriteChainState(CValidationState &state) { + if (!IsInitialBlockDownload() || pcoinsTip->GetCacheSize() > nCoinCacheSize) { + // Typical CCoins structures on disk are around 100 bytes in size. + // Pushing a new one to the database can cause it to be written + // twice (once in the log, and once in the tables). This is already + // an overestimation, as most will delete an existing entry or + // overwrite one. Still, use a conservative safety factor of 2. + if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize())) + return state.Error(); + FlushBlockFile(); + pblocktree->Sync(); + if (!pcoinsTip->Flush()) + return state.Abort(_("Failed to write to coin database")); + } + return true; +} + +void static UpdateTip(CBlockIndex *pindexNew) { + chainActive.SetTip(pindexNew); + + // Update best block in wallet (so we can detect restored wallets) + bool fIsInitialDownload = IsInitialBlockDownload(); + if ((chainActive.Height() % 20160) == 0 || (!fIsInitialDownload && (chainActive.Height() % 144) == 0)) + g_signals.SetBestChain(chainActive.GetLocator()); + + // New best block + nTimeBestReceived = GetTime(); + mempool.AddTransactionsUpdated(1); + LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n", + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), + Checkpoints::GuessVerificationProgress(chainActive.Tip())); + + // Check the version of the last 100 blocks to see if we need to upgrade: + if (!fIsInitialDownload) + { + int nUpgraded = 0; + const CBlockIndex* pindex = chainActive.Tip(); + for (int i = 0; i < 100 && pindex != NULL; i++) + { + if (pindex->nVersion > CBlock::CURRENT_VERSION) + ++nUpgraded; + pindex = pindex->pprev; + } + if (nUpgraded > 0) + LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION); + if (nUpgraded > 100/2) + // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: + strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); + } + + std::string strCmd = GetArg("-blocknotify", ""); + + if (!fIsInitialDownload && !strCmd.empty()) + { + boost::replace_all(strCmd, "%s", chainActive.Tip()->GetBlockHash().GetHex()); + boost::thread t(runCommand, strCmd); // thread runs free + } +} + bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) { mempool.check(pcoinsTip); @@ -1839,27 +1899,8 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) if (fBenchmark) LogPrintf("- Flush %i transactions: %.2fms (%.4fms/tx)\n", nModified, 0.001 * nTime, 0.001 * nTime / nModified); - // Make sure it's successfully written to disk before changing memory structure - bool fIsInitialDownload = IsInitialBlockDownload(); - if (!fIsInitialDownload || pcoinsTip->GetCacheSize() > nCoinCacheSize) { - // Typical CCoins structures on disk are around 100 bytes in size. - // Pushing a new one to the database can cause it to be written - // twice (once in the log, and once in the tables). This is already - // an overestimation, as most will delete an existing entry or - // overwrite one. Still, use a conservative safety factor of 2. - if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize())) - return state.Error(); - FlushBlockFile(); - pblocktree->Sync(); - if (!pcoinsTip->Flush()) - return state.Abort(_("Failed to write to coin database")); - } - - // At this point, all changes have been done to the database. - // Proceed by updating the memory structures. - - // Register new best chain - chainActive.SetTip(pindexNew); + if (!WriteChainState(state)) + return false; // Resurrect memory transactions that were in the disconnected branch BOOST_FOREACH(CTransaction& tx, vResurrect) { @@ -1877,48 +1918,10 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) mempool.check(pcoinsTip); - // Update best block in wallet (so we can detect restored wallets) - if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0)) - g_signals.SetBestChain(chainActive.GetLocator(pindexNew)); - - // New best block - nTimeBestReceived = GetTime(); - mempool.AddTransactionsUpdated(1); - LogPrintf("SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n", - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainActive.Tip())); - - // Check the version of the last 100 blocks to see if we need to upgrade: - if (!fIsInitialDownload) - { - int nUpgraded = 0; - const CBlockIndex* pindex = chainActive.Tip(); - for (int i = 0; i < 100 && pindex != NULL; i++) - { - if (pindex->nVersion > CBlock::CURRENT_VERSION) - ++nUpgraded; - pindex = pindex->pprev; - } - if (nUpgraded > 0) - LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION); - if (nUpgraded > 100/2) - // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: - strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); - } - - std::string strCmd = GetArg("-blocknotify", ""); - - if (!fIsInitialDownload && !strCmd.empty()) - { - boost::replace_all(strCmd, "%s", chainActive.Tip()->GetBlockHash().GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free - } - + UpdateTip(pindexNew); return true; } - bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos) { // Check for duplicate