versionbits.go raw

   1  package blockchain
   2  
   3  const (
   4  	// // vbLegacyBlockVersion is the highest legacy block version before the version bits scheme became active.
   5  	// vbLegacyBlockVersion = 4
   6  	// vbTopBits defines the bits to set in the version to signal that the version bits scheme is being used.
   7  	vbTopBits = 0x20000000
   8  	// vbTopMask is the bitmask to use to determine whether or not the version bits scheme is in use.
   9  	vbTopMask = 0xe0000000
  10  	// vbNumBits is the total number of bits available for use with the version bits scheme.
  11  	vbNumBits = 29
  12  	// unknownVerNumToCheck is the number of previous blocks to consider when checking for a threshold of unknown block
  13  	// versions for the purposes of warning the user.
  14  	unknownVerNumToCheck = 100
  15  	// unknownVerWarnNum is the threshold of previous blocks that have an unknown version to use for the purposes of
  16  	// warning the user.
  17  	unknownVerWarnNum = unknownVerNumToCheck / 2
  18  )
  19  
  20  // bitConditionChecker provides a thresholdConditionChecker which can be used to test whether or not a specific bit is
  21  // // set when it's not supposed to be according to the expected version based on the known deployments and the current
  22  // // state of the chain.
  23  // //
  24  // // This is useful for detecting and warning about unknown rule activations.
  25  // type bitConditionChecker struct {
  26  // 	bit   uint32
  27  // 	chain *BlockChain
  28  // }
  29  //
  30  // // Ensure the bitConditionChecker type implements the thresholdConditionChecker interface.
  31  // var _ thresholdConditionChecker = bitConditionChecker{}
  32  //
  33  // // BeginTime returns the unix timestamp for the median block time after which voting on a rule change starts (at the
  34  // // next window).
  35  // //
  36  // // Since this implementation checks for unknown rules, it returns 0 so the rule is always treated as active.
  37  // //
  38  // // This is part of the thresholdConditionChecker interface implementation.
  39  // func (c bitConditionChecker) BeginTime() uint64 {
  40  // 	return 0
  41  // }
  42  //
  43  // // EndTime returns the unix timestamp for the median block time after which an attempted rule change fails if it has not
  44  // // already been locked in or activated. Since this implementation checks for unknown rules, it returns the maximum
  45  // // possible timestamp so the rule is always treated as active.
  46  // //
  47  // // This is part of the thresholdConditionChecker interface implementation.
  48  // func (c bitConditionChecker) EndTime() uint64 {
  49  // 	return math.MaxUint64
  50  // }
  51  //
  52  // // RuleChangeActivationThreshold is the number of blocks for which the condition must be true in order to lock in a rule
  53  // // change.
  54  // //
  55  // // This implementation returns the value defined by the chain netparams the checker is associated with.
  56  // //
  57  // // This is part of the thresholdConditionChecker interface implementation.
  58  // func (c bitConditionChecker) RuleChangeActivationThreshold() uint32 {
  59  // 	return c.chain.params.RuleChangeActivationThreshold
  60  // }
  61  //
  62  // // MinerConfirmationWindow is the number of blocks in each threshold state retarget window. This implementation returns
  63  // // the value defined by the chain netparams the checker is associated with.
  64  // //
  65  // // This is part of the thresholdConditionChecker interface implementation.
  66  // func (c bitConditionChecker) MinerConfirmationWindow() uint32 {
  67  // 	return c.chain.params.MinerConfirmationWindow
  68  // }
  69  
  70  // // Condition returns true when the specific bit associated with the checker is set and it's not supposed to be according
  71  // // to the expected version based on the known deployments and the current state of the chain.
  72  // //
  73  // // This function MUST be called with the chain state lock held (for writes).
  74  // //
  75  // // This is part of the thresholdConditionChecker interface implementation.
  76  // func (c bitConditionChecker) Condition(node *BlockNode) (bool, error) {
  77  // 	conditionMask := uint32(1) << c.bit
  78  // 	version := uint32(node.version)
  79  // 	if version&vbTopMask != vbTopBits {
  80  // 		return false, nil
  81  // 	}
  82  // 	if version&conditionMask == 0 {
  83  // 		return false, nil
  84  // 	}
  85  // 	expectedVersion, e := c.chain.calcNextBlockVersion(node.parent)
  86  // 	if e != nil  {
  87  // 		// 		return false, err
  88  // 	}
  89  // 	return expectedVersion&conditionMask == 0, nil
  90  // }
  91  
  92  // // deploymentChecker provides a thresholdConditionChecker which can be used to test a specific deployment rule.
  93  // //
  94  // // This is required for properly detecting and activating consensus rule changes.
  95  // type deploymentChecker struct {
  96  // 	deployment *chaincfg.ConsensusDeployment
  97  // 	chain      *BlockChain
  98  // }
  99  
 100  // // Ensure the deploymentChecker type implements the thresholdConditionChecker interface.
 101  // var _ thresholdConditionChecker = deploymentChecker{}
 102  
 103  // // BeginTime returns the unix timestamp for the median block time after which voting on a rule change starts (at the
 104  // // next window).
 105  // //
 106  // // This implementation returns the value defined by the specific deployment the checker is associated with.
 107  // //
 108  // // This is part of the thresholdConditionChecker interface implementation.
 109  // func (c deploymentChecker) BeginTime() uint64 {
 110  // 	return c.deployment.StartTime
 111  // }
 112  
 113  // // EndTime returns the unix timestamp for the median block time after which an attempted rule change fails if it has not
 114  // // already been locked in or activated. This implementation returns the value defined by the specific deployment the
 115  // // checker is associated with.
 116  // //
 117  // // This is part of the thresholdConditionChecker interface implementation.
 118  // func (c deploymentChecker) EndTime() uint64 {
 119  // 	return c.deployment.ExpireTime
 120  // }
 121  
 122  // // RuleChangeActivationThreshold is the number of blocks for which the condition must be true in order to lock in a rule
 123  // // change.
 124  // //
 125  // // This implementation returns the value defined by the chain netparams the checker is associated with.
 126  // //
 127  // // This is part of the thresholdConditionChecker interface implementation.
 128  // func (c deploymentChecker) RuleChangeActivationThreshold() uint32 {
 129  // 	return c.chain.params.RuleChangeActivationThreshold
 130  // }
 131  
 132  // // MinerConfirmationWindow is the number of blocks in each threshold state retarget window. This implementation returns
 133  // // the value defined by the chain netparams the checker is associated with.
 134  // //
 135  // // This is part of the thresholdConditionChecker interface implementation.
 136  // func (c deploymentChecker) MinerConfirmationWindow() uint32 {
 137  // 	return c.chain.params.MinerConfirmationWindow
 138  // }
 139  
 140  // // Condition returns true when the specific bit defined by the deployment associated with the checker is set.
 141  // //
 142  // // This is part of the thresholdConditionChecker interface implementation.
 143  // func (c deploymentChecker) Condition(node *BlockNode) (bool, error) {
 144  // 	conditionMask := uint32(1) << c.deployment.BitNumber
 145  // 	version := uint32(node.version)
 146  // 	return (version&vbTopMask == vbTopBits) && (version&conditionMask != 0),
 147  // 		nil
 148  // }
 149  
 150  // // calcNextBlockVersion calculates the expected version of the block after the passed previous block node based on the
 151  // // state of started and locked in rule change deployments.
 152  // //
 153  // // This function differs from the exported CalcNextBlockVersion in that the exported version uses the current best chain
 154  // // as the previous block node while this function accepts any block node.
 155  // //
 156  // // This function MUST be called with the chain state lock held (for writes).
 157  // func (b *BlockChain) calcNextBlockVersion(prevNode *BlockNode) (uint32, error) {
 158  // 	// Set the appropriate bits for each actively defined rule deployment that is either in the process of being voted
 159  // 	// on, or locked in for the/ activation at the next threshold window change.
 160  // 	expectedVersion := uint32(vbTopBits)
 161  // 	for id := 0; id < len(b.params.Deployments); id++ {
 162  // 		deployment := &b.params.Deployments[id]
 163  // 		cache := &b.deploymentCaches[id]
 164  // 		checker := deploymentChecker{deployment: deployment, chain: b}
 165  // 		state, e := b.thresholdState(prevNode, checker, cache)
 166  // 		if e != nil  {
 167  // 			// 			return 0, err
 168  // 		}
 169  // 		if state == ThresholdStarted || state == ThresholdLockedIn {
 170  // 			expectedVersion |= uint32(1) << deployment.BitNumber
 171  // 		}
 172  // 	}
 173  // 	return expectedVersion, nil
 174  // }
 175  
 176  // // CalcNextBlockVersion calculates the expected version of the block after the end of the current best chain based on
 177  // // the state of started and locked in rule change deployments. This function is safe for concurrent access.
 178  // func (b *BlockChain) CalcNextBlockVersion() (uint32, error) {
 179  // 	b.chainLock.Lock()
 180  // 	version, e := b.calcNextBlockVersion(b.BestChain.Tip())
 181  // 	b.chainLock.Unlock()
 182  // 	return version, err
 183  // }
 184  
 185  // // warnUnknownRuleActivations displays a warning when any unknown new rules are either about to activate or have been
 186  // // activated.
 187  // //
 188  // // This will only happen once when new rules have been activated and every block for those about to be activated.
 189  // //
 190  // // This function MUST be called with the chain state lock held (for writes)
 191  // func (b *BlockChain) warnUnknownRuleActivations(node *BlockNode) (e error) {
 192  // 	// Warn if any unknown new rules are either about to activate or have already been activated.
 193  // 	for bit := uint32(0); bit < vbNumBits; bit++ {
 194  // 		checker := bitConditionChecker{bit: bit, chain: b}
 195  // 		cache := &b.warningCaches[bit]
 196  // 		state, e := b.thresholdState(node.parent, checker, cache)
 197  // 		if e != nil  {
 198  // 			// 			return e
 199  // 		}
 200  // 		switch state {
 201  // 		case ThresholdActive:
 202  // 			if !b.unknownRulesWarned {
 203  // 				Warnf("unknown new rules activated (bit %d)", bit)
 204  // 				b.unknownRulesWarned = true
 205  // 			}
 206  // 		case ThresholdLockedIn:
 207  // 			window := int32(checker.MinerConfirmationWindow())
 208  // 			activationHeight := window - (node.height % window)
 209  // 			Warnf("Unknown new rules are about to activate in %d blocks ("+
 210  // 				"bit %d)", activationHeight, bit)
 211  // 		}
 212  // 	}
 213  // 	return nil
 214  // }
 215  
 216  // warnUnknownVersions logs a warning if a high enough percentage of the last
 217  // blocks have unexpected versions.
 218  // This function MUST be called with the chain state lock held (for writes)
 219  // func (b *BlockChain) warnUnknownVersions(node *BlockNode) (e error) {
 220  // 	// Nothing to do if already warned.
 221  // 	if b.unknownVersionsWarned {
 222  // 		return nil
 223  // 	}
 224  // 	// Warn if enough previous blocks have unexpected versions.
 225  // 	numUpgraded := uint32(0)
 226  // 	for i := uint32(0); i < unknownVerNumToCheck && node != nil; i++ {
 227  // 		expectedVersion, e := b.calcNextBlockVersion(node.parent)
 228  // 		if e != nil  {
 229  // // 			return e
 230  // 		}
 231  // 		if expectedVersion > vbLegacyBlockVersion &&
 232  // 			(node.version & ^expectedVersion) != 0 {
 233  // 			numUpgraded++
 234  // 		}
 235  // 		node = node.parent
 236  // 	}
 237  // 	if numUpgraded > unknownVerWarnNum {
 238  // 		WARN{"Unknown block versions are being mined, so new " +
 239  // 			"rules might be in effect.  Are you running the " +
 240  // 			"latest version of the software?")
 241  // 		b.unknownVersionsWarned = true
 242  // 	}
 243  // 	return nil
 244  // }
 245