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