Skip to content

Commit

Permalink
Reduce checkpoints' effect on consensus.
Browse files Browse the repository at this point in the history
Instead of only checking height to decide whether to disable script checks,
actually check whether a block is an ancestor of a checkpoint, up to which
headers have been validated. This means that we don't have to prevent
accepting a side branch anymore - it will be safe, just less fast to
do.

We still need to prevent being fed a multitude of low-difficulty headers
filling up our memory. The mechanism for that is unchanged for now: once
a checkpoint is reached with headers, no headers chain branching off before
that point are allowed anymore.
  • Loading branch information
sipa committed Mar 19, 2015
1 parent 29fef0b commit f2b845a
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 34 deletions.
12 changes: 0 additions & 12 deletions src/checkpoints.cpp
Expand Up @@ -25,18 +25,6 @@ namespace Checkpoints {

bool fEnabled = true;

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

const MapCheckpoints& checkpoints = *Params().Checkpoints().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) {
if (pindex==NULL)
Expand Down
3 changes: 0 additions & 3 deletions src/checkpoints.h
Expand Up @@ -26,9 +26,6 @@ struct CCheckpointData {
double fTransactionsPerDay;
};

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

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

Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Expand Up @@ -346,7 +346,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (GetBoolArg("-help-debug", false))
{
strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1));
strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Disable expensive verification for known chain history (default: %u)"), 1));
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100));
strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0));
strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0));
Expand Down
12 changes: 6 additions & 6 deletions src/main.cpp
Expand Up @@ -1756,7 +1756,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return true;
}

bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();
bool fScriptChecks = true;
CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint();
if (pindexLastCheckpoint && pindex->GetAncestor(pindexLastCheckpoint->nHeight) == pindexLastCheckpoint) {
// This block is an ancestor of a checkpoint: disable script checks
fScriptChecks = false;
}

// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// unless those are already completely spent.
Expand Down Expand Up @@ -2615,11 +2620,6 @@ 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");

// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
Expand Down
13 changes: 1 addition & 12 deletions src/test/Checkpoints_tests.cpp
Expand Up @@ -21,19 +21,8 @@ BOOST_AUTO_TEST_CASE(sanity)
{
uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));


// Wrong hashes at checkpoints should fail:
BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444));
BOOST_CHECK(!Checkpoints::CheckBlock(134444, p11111));

// ... but any hash not at a checkpoint should succeed:
BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p134444));
BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111));

BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444);
}
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit f2b845a

Please sign in to comment.