Skip to content

Commit

Permalink
Merge pull request #6055
Browse files Browse the repository at this point in the history
a8cdaf5 checkpoints: move the checkpoints enable boolean into main (Cory Fields)
11982d3 checkpoints: Decouple checkpoints from Params (Cory Fields)
6996823 checkpoints: make checkpoints a member of CChainParams (Cory Fields)
9f13a10 checkpoints: store mapCheckpoints in CCheckpointData rather than a pointer (Cory Fields)
  • Loading branch information
laanwj committed May 6, 2015
2 parents 40f5e8d + a8cdaf5 commit 00820f9
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 117 deletions.
94 changes: 37 additions & 57 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,51 +26,6 @@ using namespace std;
* timestamp before)
* + Contains no strange transactions
*/
static Checkpoints::MapCheckpoints mapCheckpoints =
boost::assign::map_list_of
( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
(105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
(134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
(168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
(193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
(210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
(216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
(225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
(250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
(279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
(295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
;
static const Checkpoints::CCheckpointData data = {
&mapCheckpoints,
1397080064, // * UNIX timestamp of last checkpoint block
36544669, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
60000.0 // * estimated number of transactions per day after checkpoint
};

static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of
( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
;
static const Checkpoints::CCheckpointData dataTestnet = {
&mapCheckpointsTestnet,
1337966069,
1488,
300
};

static Checkpoints::MapCheckpoints mapCheckpointsRegtest =
boost::assign::map_list_of
( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
;
static const Checkpoints::CCheckpointData dataRegtest = {
&mapCheckpointsRegtest,
0,
0,
0
};

class CMainParams : public CChainParams {
public:
Expand Down Expand Up @@ -149,11 +104,27 @@ class CMainParams : public CChainParams {
fRequireStandard = true;
fMineBlocksOnDemand = false;
fTestnetToBeDeprecatedFieldRPC = false;
}

const Checkpoints::CCheckpointData& Checkpoints() const
{
return data;
checkpointData = (Checkpoints::CCheckpointData) {
boost::assign::map_list_of
( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
(105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
(134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
(168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
(193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
(210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
(216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
(225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
(250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
(279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
(295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")),
1397080064, // * UNIX timestamp of last checkpoint block
36544669, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
60000.0 // * estimated number of transactions per day after checkpoint
};
}
};
static CMainParams mainParams;
Expand Down Expand Up @@ -205,10 +176,15 @@ class CTestNetParams : public CMainParams {
fRequireStandard = false;
fMineBlocksOnDemand = false;
fTestnetToBeDeprecatedFieldRPC = true;
}
const Checkpoints::CCheckpointData& Checkpoints() const
{
return dataTestnet;

checkpointData = (Checkpoints::CCheckpointData) {
boost::assign::map_list_of
( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")),
1337966069,
1488,
300
};

}
};
static CTestNetParams testNetParams;
Expand Down Expand Up @@ -247,10 +223,14 @@ class CRegTestParams : public CTestNetParams {
fRequireStandard = false;
fMineBlocksOnDemand = true;
fTestnetToBeDeprecatedFieldRPC = false;
}
const Checkpoints::CCheckpointData& Checkpoints() const
{
return dataRegtest;

checkpointData = (Checkpoints::CCheckpointData){
boost::assign::map_list_of
( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")),
0,
0,
0
};
}
};
static CRegTestParams regTestParams;
Expand Down
3 changes: 2 additions & 1 deletion src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class CChainParams
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0;
const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
protected:
CChainParams() {}

Expand All @@ -96,6 +96,7 @@ class CChainParams
bool fRequireStandard;
bool fMineBlocksOnDemand;
bool fTestnetToBeDeprecatedFieldRPC;
Checkpoints::CCheckpointData checkpointData;
};

/**
Expand Down
28 changes: 9 additions & 19 deletions src/checkpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,17 @@ namespace Checkpoints {
*/
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;

bool fEnabled = true;

bool CheckBlock(int nHeight, const uint256& hash)
bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash)
{
if (!fEnabled)
return true;

const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
const MapCheckpoints& checkpoints = data.mapCheckpoints;

MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
if (i == checkpoints.end()) return true;
return hash == i->second;
}

//! Guess how far we are in the verification process at the given block index
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) {
double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) {
if (pindex==NULL)
return 0.0;

Expand All @@ -51,8 +46,6 @@ namespace Checkpoints {
// Work is defined as: 1.0 per transaction before the last checkpoint, and
// fSigcheckVerificationFactor per transaction after.

const CCheckpointData &data = Params().Checkpoints();

if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
double nCheapBefore = pindex->nChainTx;
double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
Expand All @@ -70,22 +63,19 @@ namespace Checkpoints {
return fWorkBefore / (fWorkBefore + fWorkAfter);
}

int GetTotalBlocksEstimate()
int GetTotalBlocksEstimate(const CCheckpointData& data)
{
if (!fEnabled)
return 0;
const MapCheckpoints& checkpoints = data.mapCheckpoints;

const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
if (checkpoints.empty())
return 0;

return checkpoints.rbegin()->first;
}

CBlockIndex* GetLastCheckpoint()
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
{
if (!fEnabled)
return NULL;

const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
const MapCheckpoints& checkpoints = data.mapCheckpoints;

BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
{
Expand Down
12 changes: 5 additions & 7 deletions src/checkpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,22 @@ namespace Checkpoints
typedef std::map<int, uint256> MapCheckpoints;

struct CCheckpointData {
const MapCheckpoints *mapCheckpoints;
MapCheckpoints mapCheckpoints;
int64_t nTimeLastCheckpoint;
int64_t nTransactionsLastCheckpoint;
double fTransactionsPerDay;
};

//! Returns true if block passes checkpoint checks
bool CheckBlock(int nHeight, const uint256& hash);
bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash);

//! Return conservative estimate of total number of blocks, 0 if unknown
int GetTotalBlocksEstimate();
int GetTotalBlocksEstimate(const CCheckpointData& data);

//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
CBlockIndex* GetLastCheckpoint();
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data);

double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true);

extern bool fEnabled;
double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true);

} //namespace Checkpoints

Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ bool AppInit2(boost::thread_group& threadGroup)
// Checkmempool and checkblockindex default to true in regtest mode
mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks()));
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
fCheckpointsEnabled = GetBoolArg("-checkpoints", true);

// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
Expand Down
47 changes: 30 additions & 17 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ bool fHavePruned = false;
bool fPruneMode = false;
bool fIsBareMultisigStd = true;
bool fCheckBlockIndex = false;
bool fCheckpointsEnabled = true;
unsigned int nCoinCacheSize = 5000;
uint64_t nPruneTarget = 0;

Expand Down Expand Up @@ -1205,8 +1206,11 @@ CAmount GetBlockValue(int nHeight, const CAmount& nFees)

bool IsInitialBlockDownload()
{
const CChainParams& chainParams = Params();
LOCK(cs_main);
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
if (fImporting || fReindex)
return true;
if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
return true;
static bool lockIBDState = false;
if (lockIBDState)
Expand Down Expand Up @@ -1710,7 +1714,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return true;
}

bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();
bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));

// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// unless those are already completely spent.
Expand Down Expand Up @@ -1955,6 +1959,7 @@ void PruneAndFlush() {

/** Update chainActive and related internal data structures. */
void static UpdateTip(CBlockIndex *pindexNew) {
const CChainParams& chainParams = Params();
chainActive.SetTip(pindexNew);

// New best block
Expand All @@ -1964,7 +1969,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__,
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()), (unsigned int)pcoinsTip->GetCacheSize());
Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());

cvBlockChange.notify_all();

Expand Down Expand Up @@ -2248,6 +2253,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
CBlockIndex *pindexNewTip = NULL;
CBlockIndex *pindexMostWork = NULL;
const CChainParams& chainParams = Params();
do {
boost::this_thread::interruption_point();

Expand All @@ -2272,7 +2278,9 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
if (!fInitialDownload) {
uint256 hashNewTip = pindexNewTip->GetBlockHash();
// Relay inventory, but don't relay old inventory during initial block download.
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
int nBlockEstimate = 0;
if (fCheckpointsEnabled)
nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
// Don't relay blocks if pruning -- could cause a peer to try to download, resulting
// in a stalled download if the block file is pruned before the request.
if (nLocalServices & NODE_NETWORK) {
Expand Down Expand Up @@ -2602,7 +2610,8 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo

bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
const Consensus::Params& consensusParams = Params().GetConsensus();
const CChainParams& chainParams = Params();
const Consensus::Params& consensusParams = chainParams.GetConsensus();
uint256 hash = block.GetHash();
if (hash == consensusParams.hashGenesisBlock)
return true;
Expand All @@ -2612,7 +2621,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
int nHeight = pindexPrev->nHeight+1;

// Check proof of work
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, Params().GetConsensus()))
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.DoS(100, error("%s: incorrect proof of work", __func__),
REJECT_INVALID, "bad-diffbits");

Expand All @@ -2621,25 +2630,28 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");

// Check that the block chain matches the known block chain up to a checkpoint
if (!Checkpoints::CheckBlock(nHeight, hash))
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
REJECT_CHECKPOINT, "checkpoint mismatch");
if(fCheckpointsEnabled)
{
// Check that the block chain matches the known block chain up to a checkpoint
if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
REJECT_CHECKPOINT, "checkpoint mismatch");

// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
}

// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated))
{
return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
REJECT_OBSOLETE, "bad-version");
}

// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated))
{
return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
REJECT_OBSOLETE, "bad-version");
Expand Down Expand Up @@ -3026,6 +3038,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash)

bool static LoadBlockIndexDB()
{
const CChainParams& chainparams = Params();
if (!pblocktree->LoadBlockIndexGuts())
return false;

Expand Down Expand Up @@ -3128,7 +3141,7 @@ bool static LoadBlockIndexDB()
LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
Checkpoints::GuessVerificationProgress(chainActive.Tip()));
Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()));

return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ extern int nScriptCheckThreads;
extern bool fTxIndex;
extern bool fIsBareMultisigStd;
extern bool fCheckBlockIndex;
extern bool fCheckpointsEnabled;
extern unsigned int nCoinCacheSize;
extern CFeeRate minRelayTxFee;

Expand Down
Loading

0 comments on commit 00820f9

Please sign in to comment.