diff --git a/params.go b/params.go index 04afb756b..a909145a6 100644 --- a/params.go +++ b/params.go @@ -28,6 +28,18 @@ var ( testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) ) +// Checkpoint identifies a known good point in the block chain. Using +// checkpoints allows a few optimizations for old blocks during initial download +// and also prevents forks from old blocks. +// +// Each checkpoint is selected based upon several factors. See the +// documentation for btcchain.IsCheckpointCandidate for details on the selection +// criteria. +type Checkpoint struct { + Height int64 + Hash *btcwire.ShaHash +} + // Params defines a Bitcoin network by its parameters. These parameters may be // used by Bitcoin applications to differentiate networks as well as addresses // and keys for one network from those intended for use on another network. @@ -43,6 +55,19 @@ type Params struct { SubsidyHalvingInterval int32 ResetMinDifficulty bool + // Checkpoints ordered from oldest to newest. + Checkpoints []Checkpoint + + // Reject version 1 blocks once a majority of the network has upgraded. + // This is part of BIP0034. + BlockV1RejectNumRequired uint64 + BlockV1RejectNumToCheck uint64 + + // Ensure coinbase starts with serialized block heights for version 2 + // blocks or newer once a majority of the network has upgraded. + CoinbaseBlockHeightNumRequired uint64 + CoinbaseBlockHeightNumToCheck uint64 + // Mempool parameters RelayNonStdTxs bool @@ -65,6 +90,37 @@ var MainNetParams = Params{ SubsidyHalvingInterval: 210000, ResetMinDifficulty: false, + // Checkpoints ordered from oldest to newest. + Checkpoints: []Checkpoint{ + {11111, newShaHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, + {33333, newShaHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, + {74000, newShaHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, + {105000, newShaHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, + {134444, newShaHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, + {168000, newShaHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, + {193000, newShaHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, + {210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, + {216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, + {225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, + {250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, + {267300, newShaHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, + {279000, newShaHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, + {300255, newShaHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")}, + }, + + // Reject version 1 blocks once a majority of the network has upgraded. + // 95% (950 / 1000) + // This is part of BIP0034. + BlockV1RejectNumRequired: 950, + BlockV1RejectNumToCheck: 1000, + + // Ensure coinbase starts with serialized block heights for version 2 + // blocks or newer once a majority of the network has upgraded. + // 75% (750 / 1000) + // This is part of BIP0034. + CoinbaseBlockHeightNumRequired: 750, + CoinbaseBlockHeightNumToCheck: 1000, + // Mempool parameters RelayNonStdTxs: false, @@ -89,6 +145,22 @@ var RegressionNetParams = Params{ SubsidyHalvingInterval: 150, ResetMinDifficulty: true, + // Checkpoints ordered from oldest to newest. + Checkpoints: nil, + + // Reject version 1 blocks once a majority of the network has upgraded. + // 75% (75 / 100) + // This is part of BIP0034. + BlockV1RejectNumRequired: 75, + BlockV1RejectNumToCheck: 100, + + // Ensure coinbase starts with serialized block heights for version 2 + // blocks or newer once a majority of the network has upgraded. + // 51% (51 / 100) + // This is part of BIP0034. + CoinbaseBlockHeightNumRequired: 51, + CoinbaseBlockHeightNumToCheck: 100, + // Mempool parameters RelayNonStdTxs: true, @@ -113,6 +185,24 @@ var TestNet3Params = Params{ SubsidyHalvingInterval: 210000, ResetMinDifficulty: true, + // Checkpoints ordered from oldest to newest. + Checkpoints: []Checkpoint{ + {546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, + }, + + // Reject version 1 blocks once a majority of the network has upgraded. + // 75% (75 / 100) + // This is part of BIP0034. + BlockV1RejectNumRequired: 75, + BlockV1RejectNumToCheck: 100, + + // Ensure coinbase starts with serialized block heights for version 2 + // blocks or newer once a majority of the network has upgraded. + // 51% (51 / 100) + // This is part of BIP0034. + CoinbaseBlockHeightNumRequired: 51, + CoinbaseBlockHeightNumToCheck: 100, + // Mempool parameters RelayNonStdTxs: true, @@ -177,3 +267,22 @@ func Register(params *Params) error { nets[params.Net] = params return nil } + +// newShaHashFromStr converts the passed big-endian hex string into a +// btcwire.ShaHash. It only differs from the one available in btcwire in that +// it panics on an error since it will only (and must only) be called with +// hard-coded, and therefore known good, hashes. +func newShaHashFromStr(hexStr string) *btcwire.ShaHash { + sha, err := btcwire.NewShaHashFromStr(hexStr) + if err != nil { + // Ordinarily I don't like panics in library code since it + // can take applications down without them having a chance to + // recover which is extremely annoying, however an exception is + // being made in this case because the only way this can panic + // is if there is an error in the hard-coded hashes. Thus it + // will only ever potentially panic on init and therefore is + // 100% predictable. + panic(err) + } + return sha +}