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:
parent
bfbaff9fae
commit
9cdc1b8afd
4 changed files with 38 additions and 143 deletions
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue