blockchain: Remove isMajorityVersion code.

Now that all softforking is done via BIP0009 versionbits, replace the
old isMajorityVersion deployment mechanism with hard coded historical
block heights at which they became active.

Since the activation heights vary per network, this adds new parameters
to the chaincfg.Params struct for them and sets the correct heights at
which each softfork became active on each chain.

It should be noted that this is a technically hard fork since the
behavior of alternate chain history is different with these hard-coded
activation heights as opposed to the old isMajorityVersion code.  In
particular, an alternate chain history could activate one of the soft
forks earlier than these hard-coded heights which means the old code
would reject blocks which violate the new soft fork rules whereas this
new code would not.

However, all of the soft forks this refers to were activated so far in
the chain history there is there is no way a reorg that long could
happen and checkpoints reject alternate chains before the most recent
checkpoint anyways.  Furthermore, the same change was made in Bitcoin
Core so this needs to be changed to be consistent anyways.
This commit is contained in:
Dave Collins 2016-10-19 14:24:42 -05:00
parent bfbaff9fae
commit 9cdc1b8afd
No known key found for this signature in database
GPG key ID: B8904D9D9C93D1F2
4 changed files with 38 additions and 143 deletions

View file

@ -654,35 +654,6 @@ func (b *BlockChain) removeBlockNode(node *blockNode) error {
return nil
}
// isMajorityVersion determines if a previous number of blocks in the chain
// starting with startNode are at least the minimum passed version.
//
// This function MUST be called with the chain state lock held (for writes).
func (b *BlockChain) isMajorityVersion(minVer int32, startNode *blockNode, numRequired uint64) bool {
numFound := uint64(0)
iterNode := startNode
for i := uint64(0); i < b.chainParams.BlockUpgradeNumToCheck &&
numFound < numRequired && iterNode != nil; i++ {
// This node has a version that is at least the minimum version.
if iterNode.version >= minVer {
numFound++
}
// Get the previous block node. This function is used over
// simply accessing iterNode.parent directly as it will
// dynamically create previous block nodes as needed. This
// helps allow only the pieces of the chain that are needed
// to remain in memory.
var err error
iterNode, err = b.getPrevNodeFromNode(iterNode)
if err != nil {
break
}
}
return numFound >= numRequired
}
// calcPastMedianTime calculates the median time of the previous few blocks
// prior to, and including, the passed block node. It is primarily used to
// validate new blocks have sane timestamps.

View file

@ -103,6 +103,9 @@ var regressionNetParams = &chaincfg.Params{
PowLimit: regressionPowLimit,
PowLimitBits: 0x207fffff,
CoinbaseMaturity: 100,
BIP0034Height: 100000000, // Not active - Permit ver 1 blocks
BIP0065Height: 1351, // Used by regression tests
BIP0066Height: 1251, // Used by regression tests
SubsidyReductionInterval: 150,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
@ -114,16 +117,6 @@ var regressionNetParams = &chaincfg.Params{
// Checkpoints ordered from oldest to newest.
Checkpoints: nil,
// Enforce current block version once majority of the network has
// upgraded.
// 75% (750 / 1000)
// Reject previous block versions once a majority of the network has
// upgraded.
// 95% (950 / 1000)
BlockEnforceNumRequired: 750,
BlockRejectNumRequired: 950,
BlockUpgradeNumToCheck: 1000,
// Mempool parameters
RelayNonStdTxs: true,

View file

@ -710,38 +710,19 @@ func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode
return ruleError(ErrForkTooOld, str)
}
if !fastAdd {
// Reject version 3 blocks once a majority of the network has
// upgraded. This is part of BIP0065.
if header.Version < 4 && b.isMajorityVersion(4, prevNode,
b.chainParams.BlockRejectNumRequired) {
// Reject outdated block versions once a majority of the network
// has upgraded. These were originally voted on by BIP0034,
// BIP0065, and BIP0066.
params := b.chainParams
if header.Version < 2 && blockHeight >= params.BIP0034Height ||
header.Version < 3 && blockHeight >= params.BIP0066Height ||
header.Version < 4 && blockHeight >= params.BIP0065Height {
str := "new blocks with version %d are no longer valid"
str = fmt.Sprintf(str, header.Version)
return ruleError(ErrBlockVersionTooOld, str)
}
// Reject version 2 blocks once a majority of the network has
// upgraded. This is part of BIP0066.
if header.Version < 3 && b.isMajorityVersion(3, prevNode,
b.chainParams.BlockRejectNumRequired) {
str := "new blocks with version %d are no longer valid"
str = fmt.Sprintf(str, header.Version)
return ruleError(ErrBlockVersionTooOld, str)
}
// Reject version 1 blocks once a majority of the network has
// upgraded. This is part of BIP0034.
if header.Version < 2 && b.isMajorityVersion(2, prevNode,
b.chainParams.BlockRejectNumRequired) {
str := "new blocks with version %d are no longer valid"
str = fmt.Sprintf(str, header.Version)
return ruleError(ErrBlockVersionTooOld, str)
}
}
return nil
}
@ -791,8 +772,7 @@ func (b *BlockChain) checkBlockContext(block *btcutil.Block, prevNode *blockNode
// once a majority of the network has upgraded. This is part of
// BIP0034.
if ShouldHaveSerializedBlockHeight(header) &&
b.isMajorityVersion(serializedHeightVersion, prevNode,
b.chainParams.BlockEnforceNumRequired) {
blockHeight >= b.chainParams.BIP0034Height {
coinbaseTx := block.Transactions()[0]
err := checkSerializedHeight(coinbaseTx, blockHeight)
@ -1126,16 +1106,6 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
runScripts = false
}
// Get the previous block node. This function is used over simply
// accessing node.parent directly as it will dynamically create previous
// block nodes as needed. This helps allow only the pieces of the chain
// that are needed to remain in memory.
prevNode, err := b.getPrevNodeFromNode(node)
if err != nil {
log.Errorf("getPrevNodeFromNode: %v", err)
return err
}
// Blocks created after the BIP0016 activation time need to have the
// pay-to-script-hash checks enabled.
var scriptFlags txscript.ScriptFlags
@ -1143,22 +1113,16 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
scriptFlags |= txscript.ScriptBip16
}
// Enforce DER signatures for block versions 3+ once the majority of the
// network has upgraded to the enforcement threshold. This is part of
// BIP0066.
// Enforce DER signatures for block versions 3+ once the historical
// activation threshold has been reached. This is part of BIP0066.
blockHeader := &block.MsgBlock().Header
if blockHeader.Version >= 3 && b.isMajorityVersion(3, prevNode,
b.chainParams.BlockEnforceNumRequired) {
if blockHeader.Version >= 3 && node.height >= b.chainParams.BIP0066Height {
scriptFlags |= txscript.ScriptVerifyDERSignatures
}
// Enforce CHECKLOCKTIMEVERIFY for block versions 4+ once the majority
// of the network has upgraded to the enforcement threshold. This is
// part of BIP0065.
if blockHeader.Version >= 4 && b.isMajorityVersion(4, prevNode,
b.chainParams.BlockEnforceNumRequired) {
// Enforce CHECKLOCKTIMEVERIFY for block versions 4+ once the historical
// activation threshold has been reached. This is part of BIP0065.
if blockHeader.Version >= 4 && node.height >= b.chainParams.BIP0065Height {
scriptFlags |= txscript.ScriptVerifyCheckLockTimeVerify
}

View file

@ -123,6 +123,12 @@ type Params struct {
// block in compact form.
PowLimitBits uint32
// These fields define the block heights at which the specified softfork
// BIP became active.
BIP0034Height int32
BIP0065Height int32
BIP0066Height int32
// CoinbaseMaturity is the number of blocks required before newly mined
// coins (coinbase transactions) can be spent.
CoinbaseMaturity uint16
@ -164,17 +170,6 @@ type Params struct {
// Checkpoints ordered from oldest to newest.
Checkpoints []Checkpoint
// Enforce current block version once network has
// upgraded. This is part of BIP0034.
BlockEnforceNumRequired uint64
// Reject previous block versions once network has
// upgraded. This is part of BIP0034.
BlockRejectNumRequired uint64
// The number of nodes to check. This is part of BIP0034.
BlockUpgradeNumToCheck uint64
// These fields are related to voting on consensus rule changes as
// defined by BIP0009.
//
@ -229,6 +224,9 @@ var MainNetParams = Params{
GenesisHash: &genesisHash,
PowLimit: mainPowLimit,
PowLimitBits: 0x1d00ffff,
BIP0034Height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8
BIP0065Height: 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
BIP0066Height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
@ -260,16 +258,6 @@ var MainNetParams = Params{
{382320, newHashFromStr("00000000000000000a8dc6ed5b133d0eb2fd6af56203e4159789b092defd8ab2")},
},
// Enforce current block version once majority of the network has
// upgraded.
// 75% (750 / 1000)
// Reject previous block versions once a majority of the network has
// upgraded.
// 95% (950 / 1000)
BlockEnforceNumRequired: 750,
BlockRejectNumRequired: 950,
BlockUpgradeNumToCheck: 1000,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
@ -316,6 +304,9 @@ var RegressionNetParams = Params{
PowLimit: regressionPowLimit,
PowLimitBits: 0x207fffff,
CoinbaseMaturity: 100,
BIP0034Height: 100000000, // Not active - Permit ver 1 blocks
BIP0065Height: 1351, // Used by regression tests
BIP0066Height: 1251, // Used by regression tests
SubsidyReductionInterval: 150,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
@ -327,16 +318,6 @@ var RegressionNetParams = Params{
// Checkpoints ordered from oldest to newest.
Checkpoints: nil,
// Enforce current block version once majority of the network has
// upgraded.
// 75% (750 / 1000)
// Reject previous block versions once a majority of the network has
// upgraded.
// 95% (950 / 1000)
BlockEnforceNumRequired: 750,
BlockRejectNumRequired: 950,
BlockUpgradeNumToCheck: 1000,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
@ -387,6 +368,9 @@ var TestNet3Params = Params{
GenesisHash: &testNet3GenesisHash,
PowLimit: testNet3PowLimit,
PowLimitBits: 0x1d00ffff,
BIP0034Height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8
BIP0065Height: 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
BIP0066Height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
@ -401,16 +385,6 @@ var TestNet3Params = Params{
{546, newHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")},
},
// Enforce current block version once majority of the network has
// upgraded.
// 51% (51 / 100)
// Reject previous block versions once a majority of the network has
// upgraded.
// 75% (75 / 100)
BlockEnforceNumRequired: 51,
BlockRejectNumRequired: 75,
BlockUpgradeNumToCheck: 100,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
@ -460,6 +434,9 @@ var SimNetParams = Params{
GenesisHash: &simNetGenesisHash,
PowLimit: simNetPowLimit,
PowLimitBits: 0x207fffff,
BIP0034Height: 0, // Always active on simnet
BIP0065Height: 0, // Always active on simnet
BIP0066Height: 0, // Always active on simnet
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
@ -472,16 +449,6 @@ var SimNetParams = Params{
// Checkpoints ordered from oldest to newest.
Checkpoints: nil,
// Enforce current block version once majority of the network has
// upgraded.
// 51% (51 / 100)
// Reject previous block versions once a majority of the network has
// upgraded.
// 75% (75 / 100)
BlockEnforceNumRequired: 51,
BlockRejectNumRequired: 75,
BlockUpgradeNumToCheck: 100,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as: