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