From e41632c9fb5d32491e7f394b7b3a82f6cb5897cb Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 22 Oct 2016 05:33:25 +0000 Subject: [PATCH] IBD check uses minimumchain work instead of checkpoints. This introduces a 'minimum chain work' chainparam which is intended to be the known amount of work in the chain for the network at the time of software release. If you don't have this much work, you're not yet caught up. This is used instead of the count of blocks test from checkpoints. This criteria is trivial to keep updated as there is no element of subjectivity, trust, or position dependence to it. It is also a more reliable metric of sync status than a block count. --- doc/release-process.md | 2 ++ src/chainparams.cpp | 10 ++++++++++ src/consensus/params.h | 1 + src/main.cpp | 6 ++++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 93a8e8362..cde355287 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -24,6 +24,8 @@ Check that there are no surprising performance regressions: Ensure that new performance metrics appear on that site. +Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc. + ### Protocol Safety Checks: If this release changes the behavior of the protocol or fixes a serious diff --git a/src/chainparams.cpp b/src/chainparams.cpp index aa346f954..4aa9f8d6b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -106,6 +106,9 @@ public: consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000281b32ff3198a1"); + /** * The message start string should be awesome! ⓩ❤ */ @@ -268,6 +271,9 @@ public: consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000001d0c4d9cd"); + pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0x1a; pchMessageStart[2] = 0xf9; @@ -317,6 +323,7 @@ public: fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; + checkpointData = (CCheckpointData) { boost::assign::map_list_of (0, consensus.hashGenesisBlock) @@ -380,6 +387,9 @@ public: consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00"); + pchMessageStart[0] = 0xaa; pchMessageStart[1] = 0xe8; pchMessageStart[2] = 0x3f; diff --git a/src/consensus/params.h b/src/consensus/params.h index 38cf65fb6..c21607046 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -98,6 +98,7 @@ struct Params { int64_t AveragingWindowTimespan() const { return nPowAveragingWindow * nPowTargetSpacing; } int64_t MinActualTimespan() const { return (AveragingWindowTimespan() * (100 - nPowMaxAdjustUp )) / 100; } int64_t MaxActualTimespan() const { return (AveragingWindowTimespan() * (100 + nPowMaxAdjustDown)) / 100; } + uint256 nMinimumChainWork; }; } // namespace Consensus diff --git a/src/main.cpp b/src/main.cpp index 311b35aae..cc8571b38 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1740,7 +1740,9 @@ bool IsInitialBlockDownload() return false; if (fImporting || fReindex) return true; - if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints())) + if (chainActive.Tip() == NULL) + return true; + if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) return true; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge); @@ -1758,7 +1760,7 @@ void CheckForkWarningConditions() { AssertLockHeld(cs_main); // Before we get past initial download, we cannot reliably alert about forks - // (we assume we don't get stuck on a fork before the last checkpoint) + // (we assume we don't get stuck on a fork before finishing our initial sync) if (IsInitialBlockDownload()) return;