Which blocks get to be checkpoints, and why is one block chosen to be a checkpoint, rather than another block? And where can I find a list of checkpoint blocks?
2 Answers
At least in Bitcoin Core, none. Checkpoints are legacy and will likely be removed at some point.
Checkpoints were originally introduced as a way to enable skipping of signatures in the historical chain, without being vulnerable to accepting an alternate history. That role has now been overtaken by the assumevalid
concept (a block hash that is known to be good, but doesn't prevent accepting another chain).
Checkpoints have also been used as a heuristic to know what block headers are acceptable before validating an entire block. That role was removed with headers-first synchronization in 0.10. We now only download a block after we already know its proof of work and difficulty are acceptable.
They have also been used as a measure for validation progress (so Bitcoin-Qt can show a progress bar during validation). That role has been replaced with just statistics data that doesn't affect validation.
The only thing checkpoints still serve for is preventing a low-difficulty headers attack, where your node gets spammed by a large number of long, low difficulty chain branches, making it go out of memory. Due to the existing checkpoints (up to height 295000), this is a very costly attack already.
You can find the list in bitcoin source code.
These are the current checkpoints (from git revision c091b99
):
checkpointData = (CCheckpointData) {
{
{ 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")},
}
};
It doesn't really matter how they are chosen, but notice the following comments found in the source:
/**
* What makes a good checkpoint block?
* + Is surrounded by blocks with reasonable timestamps
* (no blocks before with a timestamp after, none after with
* timestamp before)
* + Contains no strange transactions
*/
Anyway, as long as they are inserted at regular intervals everything is fine. This answer gives a hint at what is their purpose.