github.com/decred/dcrd/blockchain@v1.2.1/thresholdstate.go (about)

     1  // Copyright (c) 2016 The btcsuite developers
     2  // Copyright (c) 2017-2019 The Decred developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package blockchain
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"github.com/decred/dcrd/chaincfg"
    12  	"github.com/decred/dcrd/chaincfg/chainhash"
    13  )
    14  
    15  // ThresholdState define the various threshold states used when voting on
    16  // consensus changes.
    17  type ThresholdState byte
    18  
    19  // These constants are used to identify specific threshold states.
    20  //
    21  // NOTE: This section specifically does not use iota for the individual states
    22  // since these values are serialized and must be stable for long-term storage.
    23  const (
    24  	// ThresholdDefined is the first state for each deployment and is the
    25  	// state for the genesis block has by definition for all deployments.
    26  	ThresholdDefined ThresholdState = 0
    27  
    28  	// ThresholdStarted is the state for a deployment once its start time
    29  	// has been reached.
    30  	ThresholdStarted ThresholdState = 1
    31  
    32  	// ThresholdLockedIn is the state for a deployment during the retarget
    33  	// period which is after the ThresholdStarted state period and the
    34  	// number of blocks that have voted for the deployment equal or exceed
    35  	// the required number of votes for the deployment.
    36  	ThresholdLockedIn ThresholdState = 2
    37  
    38  	// ThresholdActive is the state for a deployment for all blocks after a
    39  	// retarget period in which the deployment was in the ThresholdLockedIn
    40  	// state.
    41  	ThresholdActive ThresholdState = 3
    42  
    43  	// ThresholdFailed is the state for a deployment once its expiration
    44  	// time has been reached and it did not reach the ThresholdLockedIn
    45  	// state.
    46  	ThresholdFailed ThresholdState = 4
    47  
    48  	// ThresholdInvalid is a deployment that does not exist.
    49  	ThresholdInvalid ThresholdState = 5
    50  )
    51  
    52  // thresholdStateStrings is a map of ThresholdState values back to their
    53  // constant names for pretty printing.
    54  var thresholdStateStrings = map[ThresholdState]string{
    55  	ThresholdDefined:  "ThresholdDefined",
    56  	ThresholdStarted:  "ThresholdStarted",
    57  	ThresholdLockedIn: "ThresholdLockedIn",
    58  	ThresholdActive:   "ThresholdActive",
    59  	ThresholdFailed:   "ThresholdFailed",
    60  }
    61  
    62  // String returns the ThresholdState as a human-readable name.
    63  func (t ThresholdState) String() string {
    64  	if s := thresholdStateStrings[t]; s != "" {
    65  		return s
    66  	}
    67  	return fmt.Sprintf("Unknown ThresholdState (%d)", int(t))
    68  }
    69  
    70  const (
    71  	// invalidChoice indicates an invalid choice in the
    72  	// ThresholdStateTuple.
    73  	invalidChoice = uint32(0xffffffff)
    74  )
    75  
    76  // ThresholdStateTuple contains the current state and the activated choice,
    77  // when valid.
    78  type ThresholdStateTuple struct {
    79  	// state contains the current ThresholdState.
    80  	State ThresholdState
    81  
    82  	// Choice is set to invalidChoice unless state is: ThresholdLockedIn,
    83  	// ThresholdFailed & ThresholdActive.  choice should always be
    84  	// crosschecked with invalidChoice.
    85  	Choice uint32
    86  }
    87  
    88  // thresholdStateTupleStrings is a map of ThresholdState values back to their
    89  // constant names for pretty printing.
    90  var thresholdStateTupleStrings = map[ThresholdState]string{
    91  	ThresholdDefined:  "defined",
    92  	ThresholdStarted:  "started",
    93  	ThresholdLockedIn: "lockedin",
    94  	ThresholdActive:   "active",
    95  	ThresholdFailed:   "failed",
    96  }
    97  
    98  // String returns the ThresholdStateTuple as a human-readable tuple.
    99  func (t ThresholdStateTuple) String() string {
   100  	if s := thresholdStateTupleStrings[t.State]; s != "" {
   101  		return fmt.Sprintf("%v", s)
   102  	}
   103  	return "invalid"
   104  }
   105  
   106  // newThresholdState returns an initialized ThresholdStateTuple.
   107  func newThresholdState(state ThresholdState, choice uint32) ThresholdStateTuple {
   108  	return ThresholdStateTuple{State: state, Choice: choice}
   109  }
   110  
   111  // thresholdConditionTally is returned by thresholdConditionChecker.Condition
   112  // to indicate how many votes an option received.  The isAbstain and isNo flags
   113  // are accordingly set.  Note isAbstain and isNo can NOT be both true at the
   114  // same time.
   115  type thresholdConditionTally struct {
   116  	// Vote count
   117  	count uint32
   118  
   119  	// isAbstain is the abstain (or zero vote).
   120  	isAbstain bool
   121  
   122  	// isNo is the hard no vote.
   123  	isNo bool
   124  }
   125  
   126  // thresholdConditionChecker provides a generic interface that is invoked to
   127  // determine when a consensus rule change threshold should be changed.
   128  type thresholdConditionChecker interface {
   129  	// BeginTime returns the unix timestamp for the median block time after
   130  	// which voting on a rule change starts (at the next window).
   131  	BeginTime() uint64
   132  
   133  	// EndTime returns the unix timestamp for the median block time after
   134  	// which an attempted rule change fails if it has not already been
   135  	// locked in or activated.
   136  	EndTime() uint64
   137  
   138  	// RuleChangeActivationQuorum is the minimum number of votes required
   139  	// in a voting period for before we check
   140  	// RuleChangeActivationThreshold.
   141  	RuleChangeActivationQuorum() uint32
   142  
   143  	// RuleChangeActivationThreshold is the number of votes required in
   144  	// order to lock in a rule change.
   145  	RuleChangeActivationThreshold(uint32) uint32
   146  
   147  	// RuleChangeActivationInterval is the number of blocks in each threshold
   148  	// state retarget window.
   149  	RuleChangeActivationInterval() uint32
   150  
   151  	// StakeValidationHeight is the minimum height required before votes start
   152  	// counting.
   153  	StakeValidationHeight() int64
   154  
   155  	// Condition returns an array of thresholdConditionTally that contains
   156  	// all votes.  By convention isAbstain and isNo can not be true at the
   157  	// same time.  The array is always returned in the same order so that
   158  	// the consumer can repeatedly call this function without having to
   159  	// care about said order.  Only 1 isNo vote is allowed.  By convention
   160  	// the zero value of the vote as determined by the mask is an isAbstain
   161  	// vote.
   162  	Condition(*blockNode, uint32) ([]thresholdConditionTally, error)
   163  }
   164  
   165  // thresholdStateCache provides a type to cache the threshold states of each
   166  // threshold window for a set of IDs.  It also keeps track of which entries have
   167  // been modified and therefore need to be written to the database.
   168  type thresholdStateCache struct {
   169  	dbUpdates map[chainhash.Hash]ThresholdStateTuple
   170  	entries   map[chainhash.Hash]ThresholdStateTuple
   171  }
   172  
   173  // Lookup returns the threshold state associated with the given hash along with
   174  // a boolean that indicates whether or not it is valid.
   175  func (c *thresholdStateCache) Lookup(hash chainhash.Hash) (ThresholdStateTuple, bool) {
   176  	state, ok := c.entries[hash]
   177  	return state, ok
   178  }
   179  
   180  // Update updates the cache to contain the provided hash to threshold state
   181  // mapping while properly tracking needed updates flush changes to the database.
   182  func (c *thresholdStateCache) Update(hash chainhash.Hash, state ThresholdStateTuple) {
   183  	if existing, ok := c.entries[hash]; ok && existing == state {
   184  		return
   185  	}
   186  
   187  	c.dbUpdates[hash] = state
   188  	c.entries[hash] = state
   189  }
   190  
   191  // MarkFlushed marks all of the current udpates as flushed to the database.
   192  // This is useful so the caller can ensure the needed database updates are not
   193  // lost until they have successfully been written to the database.
   194  func (c *thresholdStateCache) MarkFlushed() {
   195  	for hash := range c.dbUpdates {
   196  		delete(c.dbUpdates, hash)
   197  	}
   198  }
   199  
   200  // newThresholdCaches returns a new array of caches to be used when calculating
   201  // threshold states.
   202  func newThresholdCaches(params *chaincfg.Params) map[uint32][]thresholdStateCache {
   203  	caches := make(map[uint32][]thresholdStateCache)
   204  	for version := range params.Deployments {
   205  		caches[version] = make([]thresholdStateCache,
   206  			len(params.Deployments[version]))
   207  		for k := range caches[version] {
   208  			caches[version][k].entries = make(map[chainhash.Hash]ThresholdStateTuple)
   209  			caches[version][k].dbUpdates = make(map[chainhash.Hash]ThresholdStateTuple)
   210  		}
   211  	}
   212  	return caches
   213  }
   214  
   215  // nextThresholdState returns the current rule change threshold state for the
   216  // block AFTER the given node and deployment ID.  The cache is used to ensure
   217  // the threshold states for previous windows are only calculated once.
   218  //
   219  // This function MUST be called with the chain state lock held (for writes).
   220  func (b *BlockChain) nextThresholdState(version uint32, prevNode *blockNode, checker thresholdConditionChecker, cache *thresholdStateCache) (ThresholdStateTuple, error) {
   221  	// The threshold state for the window that contains the genesis block is
   222  	// defined by definition.
   223  	confirmationWindow := int64(checker.RuleChangeActivationInterval())
   224  	svh := checker.StakeValidationHeight()
   225  	if prevNode == nil || prevNode.height+1 < svh+confirmationWindow {
   226  		return newThresholdState(ThresholdDefined, invalidChoice), nil
   227  	}
   228  
   229  	// Get the ancestor that is the last block of the previous confirmation
   230  	// window in order to get its threshold state.  This can be done because
   231  	// the state is the same for all blocks within a given window.
   232  	wantHeight := calcWantHeight(svh,
   233  		int64(checker.RuleChangeActivationInterval()),
   234  		prevNode.height+1)
   235  	prevNode = prevNode.Ancestor(wantHeight)
   236  
   237  	// Iterate backwards through each of the previous confirmation windows
   238  	// to find the most recently cached threshold state.
   239  	var neededStates []*blockNode
   240  	for prevNode != nil {
   241  		// Nothing more to do if the state of the block is already
   242  		// cached.
   243  		if _, ok := cache.Lookup(prevNode.hash); ok {
   244  			break
   245  		}
   246  
   247  		// The start and expiration times are based on the median block
   248  		// time, so calculate it now.
   249  		medianTime := prevNode.CalcPastMedianTime()
   250  
   251  		// The state is simply defined if the start time hasn't been
   252  		// been reached yet.
   253  		if uint64(medianTime.Unix()) < checker.BeginTime() {
   254  			cache.Update(prevNode.hash, ThresholdStateTuple{
   255  				State:  ThresholdDefined,
   256  				Choice: invalidChoice,
   257  			})
   258  			break
   259  		}
   260  
   261  		// Add this node to the list of nodes that need the state
   262  		// calculated and cached.
   263  		neededStates = append(neededStates, prevNode)
   264  
   265  		// Get the ancestor that is the last block of the previous
   266  		// confirmation window.
   267  		prevNode = prevNode.RelativeAncestor(confirmationWindow)
   268  	}
   269  
   270  	// Start with the threshold state for the most recent confirmation
   271  	// window that has a cached state.
   272  	stateTuple := newThresholdState(ThresholdDefined, invalidChoice)
   273  	if prevNode != nil {
   274  		var ok bool
   275  		stateTuple, ok = cache.Lookup(prevNode.hash)
   276  		if !ok {
   277  			return newThresholdState(ThresholdFailed,
   278  					invalidChoice), AssertError(fmt.Sprintf(
   279  					"thresholdState: cache lookup failed "+
   280  						"for %v", prevNode.hash))
   281  		}
   282  	}
   283  
   284  	// Since each threshold state depends on the state of the previous
   285  	// window, iterate starting from the oldest unknown window.
   286  	for neededNum := len(neededStates) - 1; neededNum >= 0; neededNum-- {
   287  		prevNode := neededStates[neededNum]
   288  
   289  		switch stateTuple.State {
   290  		case ThresholdDefined:
   291  			// Ensure we are at the minimal require height.
   292  			if prevNode.height < svh {
   293  				stateTuple.State = ThresholdDefined
   294  				break
   295  			}
   296  
   297  			// The deployment of the rule change fails if it expires
   298  			// before it is accepted and locked in.
   299  			medianTime := prevNode.CalcPastMedianTime()
   300  			medianTimeUnix := uint64(medianTime.Unix())
   301  			if medianTimeUnix >= checker.EndTime() {
   302  				stateTuple.State = ThresholdFailed
   303  				break
   304  			}
   305  
   306  			// Make sure we are on the correct stake version.
   307  			if b.calcStakeVersion(prevNode) < version {
   308  				stateTuple.State = ThresholdDefined
   309  				break
   310  			}
   311  
   312  			// The state must remain in the defined state so long as
   313  			// a majority of the PoW miners have not upgraded.
   314  			if !b.isMajorityVersion(int32(version), prevNode,
   315  				b.chainParams.BlockRejectNumRequired) {
   316  
   317  				stateTuple.State = ThresholdDefined
   318  				break
   319  			}
   320  
   321  			// The state for the rule moves to the started state
   322  			// once its start time has been reached (and it hasn't
   323  			// already expired per the above).
   324  			if medianTimeUnix >= checker.BeginTime() {
   325  				stateTuple.State = ThresholdStarted
   326  			}
   327  
   328  		case ThresholdStarted:
   329  			// The deployment of the rule change fails if it expires
   330  			// before it is accepted and locked in.
   331  			medianTime := prevNode.CalcPastMedianTime()
   332  			if uint64(medianTime.Unix()) >= checker.EndTime() {
   333  				stateTuple.State = ThresholdFailed
   334  				break
   335  			}
   336  
   337  			// At this point, the rule change is still being voted
   338  			// on, so iterate backwards through the confirmation
   339  			// window to count all of the votes in it.
   340  			var (
   341  				counts       []thresholdConditionTally
   342  				totalVotes   uint32
   343  				abstainVotes uint32
   344  			)
   345  			countNode := prevNode
   346  			for i := int64(0); i < confirmationWindow; i++ {
   347  				c, err := checker.Condition(countNode, version)
   348  				if err != nil {
   349  					return newThresholdState(
   350  						ThresholdFailed, invalidChoice), err
   351  				}
   352  
   353  				// Create array first time around.
   354  				if len(counts) == 0 {
   355  					counts = make([]thresholdConditionTally, len(c))
   356  				}
   357  
   358  				// Tally votes.
   359  				for k := range c {
   360  					counts[k].count += c[k].count
   361  					counts[k].isAbstain = c[k].isAbstain
   362  					counts[k].isNo = c[k].isNo
   363  					if c[k].isAbstain {
   364  						abstainVotes += c[k].count
   365  					} else {
   366  						totalVotes += c[k].count
   367  					}
   368  				}
   369  
   370  				countNode = countNode.parent
   371  			}
   372  
   373  			// Determine if we have reached quorum.
   374  			totalNonAbstainVotes := uint32(0)
   375  			for _, v := range counts {
   376  				if v.isAbstain && !v.isNo {
   377  					continue
   378  				}
   379  				totalNonAbstainVotes += v.count
   380  			}
   381  			if totalNonAbstainVotes < checker.RuleChangeActivationQuorum() {
   382  				break
   383  			}
   384  
   385  			// The state is locked in if the number of blocks in the
   386  			// period that voted for the rule change meets the
   387  			// activation threshold.
   388  			for k, v := range counts {
   389  				// We require at least 10% quorum on all votes.
   390  				if v.count < checker.RuleChangeActivationThreshold(totalVotes) {
   391  					continue
   392  				}
   393  				// Something went over the threshold
   394  				switch {
   395  				case !v.isAbstain && !v.isNo:
   396  					// One of the choices has
   397  					// reached majority.
   398  					stateTuple.State = ThresholdLockedIn
   399  					stateTuple.Choice = uint32(k)
   400  				case !v.isAbstain && v.isNo:
   401  					// No choice.  Only 1 No per
   402  					// vote is allowed.  A No vote
   403  					// is required though.
   404  					stateTuple.State = ThresholdFailed
   405  					stateTuple.Choice = uint32(k)
   406  				case v.isAbstain && !v.isNo:
   407  					// This is the abstain case.
   408  					// The statemachine is not
   409  					// supposed to change.
   410  					continue
   411  				case v.isAbstain && v.isNo:
   412  					// Invalid choice.
   413  					stateTuple.State = ThresholdFailed
   414  					stateTuple.Choice = uint32(k)
   415  				}
   416  				break
   417  			}
   418  
   419  		case ThresholdLockedIn:
   420  			// The new rule becomes active when its previous state
   421  			// was locked in.
   422  			stateTuple.State = ThresholdActive
   423  
   424  		// Nothing to do if the previous state is active or failed since
   425  		// they are both terminal states.
   426  		case ThresholdActive:
   427  		case ThresholdFailed:
   428  		}
   429  
   430  		// Update the cache to avoid recalculating the state in the
   431  		// future.
   432  		cache.Update(prevNode.hash, stateTuple)
   433  	}
   434  
   435  	return stateTuple, nil
   436  }
   437  
   438  // deploymentState returns the current rule change threshold for a given stake
   439  // version and deploymentID.  The threshold is evaluated from the point of view
   440  // of the block node passed in as the first argument to this method.
   441  //
   442  // It is important to note that, as the variable name indicates, this function
   443  // expects the block node prior to the block for which the deployment state is
   444  // desired.  In other words, the returned deployment state is for the block
   445  // AFTER the passed node.
   446  //
   447  // This function MUST be called with the chain state lock held (for writes).
   448  func (b *BlockChain) deploymentState(prevNode *blockNode, version uint32, deploymentID string) (ThresholdStateTuple, error) {
   449  	for k := range b.chainParams.Deployments[version] {
   450  		if b.chainParams.Deployments[version][k].Vote.Id == deploymentID {
   451  			checker := deploymentChecker{
   452  				deployment: &b.chainParams.Deployments[version][k],
   453  				chain:      b,
   454  			}
   455  			cache := &b.deploymentCaches[version][k]
   456  			return b.nextThresholdState(version, prevNode, checker, cache)
   457  		}
   458  	}
   459  
   460  	invalidState := ThresholdStateTuple{
   461  		State:  ThresholdInvalid,
   462  		Choice: invalidChoice,
   463  	}
   464  	return invalidState, DeploymentError(deploymentID)
   465  }
   466  
   467  // stateLastChanged returns the node at which the provided consensus deployment
   468  // agenda last changed state.  The function will return nil if the state has
   469  // never changed.
   470  //
   471  // This function MUST be called with the chain state lock held (for writes).
   472  func (b *BlockChain) stateLastChanged(version uint32, node *blockNode, checker thresholdConditionChecker, cache *thresholdStateCache) (*blockNode, error) {
   473  	// No state changes are possible if the chain is not yet past stake
   474  	// validation height and had a full interval to change.
   475  	confirmationInterval := int64(checker.RuleChangeActivationInterval())
   476  	svh := checker.StakeValidationHeight()
   477  	if node == nil || node.height < svh+confirmationInterval {
   478  		return nil, nil
   479  	}
   480  
   481  	// Determine the current state.  Notice that nextThresholdState always
   482  	// calculates the state for the block after the provided one, so use the
   483  	// parent to get the state for the requested block.
   484  	curState, err := b.nextThresholdState(version, node.parent, checker, cache)
   485  	if err != nil {
   486  		return nil, err
   487  	}
   488  
   489  	// Determine the first block of the current confirmation interval in order
   490  	// to determine block at which the state possibly changed.  Since the state
   491  	// can only change at an interval boundary, loop backwards one interval at
   492  	// a time to determine when (and if) the state changed.
   493  	finalNodeHeight := calcWantHeight(svh, confirmationInterval, node.height)
   494  	node = node.Ancestor(finalNodeHeight + 1)
   495  	priorStateChangeNode := node
   496  	for node != nil && node.parent != nil {
   497  		// As previously mentioned, nextThresholdState always calculates the
   498  		// state for the block after the provided one, so use the parent to get
   499  		// the state of the block itself.
   500  		state, err := b.nextThresholdState(version, node.parent, checker, cache)
   501  		if err != nil {
   502  			return nil, err
   503  		}
   504  
   505  		if state.State != curState.State {
   506  			return priorStateChangeNode, nil
   507  		}
   508  
   509  		// Get the ancestor that is the first block of the previous confirmation
   510  		// interval.
   511  		priorStateChangeNode = node
   512  		node = node.RelativeAncestor(confirmationInterval)
   513  	}
   514  
   515  	return nil, nil
   516  }
   517  
   518  // StateLastChangedHeight returns the height at which the provided consensus
   519  // deployment agenda last changed state.  Note that, unlike the ThresholdState
   520  // function, this function returns the information as of the passed block hash.
   521  //
   522  // This function is safe for concurrent access.
   523  func (b *BlockChain) StateLastChangedHeight(hash *chainhash.Hash, version uint32, deploymentID string) (int64, error) {
   524  	// NOTE: The requirement for the node being fully validated here is strictly
   525  	// stronger than what is actually required.  In reality, all that is needed
   526  	// is for the block data for the node and all of its ancestors to be
   527  	// available, but there is not currently any tracking to be able to
   528  	// efficiently determine that state.
   529  	node := b.index.LookupNode(hash)
   530  	if node == nil || !b.index.NodeStatus(node).KnownValid() {
   531  		return 0, HashError(hash.String())
   532  	}
   533  
   534  	// Fetch the treshold state cache for the provided deployment id as well as
   535  	// the condition checker.
   536  	var cache *thresholdStateCache
   537  	var checker thresholdConditionChecker
   538  	for k := range b.chainParams.Deployments[version] {
   539  		if b.chainParams.Deployments[version][k].Vote.Id == deploymentID {
   540  			checker = deploymentChecker{
   541  				deployment: &b.chainParams.Deployments[version][k],
   542  				chain:      b,
   543  			}
   544  			cache = &b.deploymentCaches[version][k]
   545  			break
   546  		}
   547  	}
   548  
   549  	if cache == nil {
   550  		return 0, fmt.Errorf("threshold state cache for agenda with "+
   551  			"deployment id (%s) not found", deploymentID)
   552  	}
   553  
   554  	// Find the node at which the current state changed.
   555  	b.chainLock.Lock()
   556  	stateNode, err := b.stateLastChanged(version, node, checker, cache)
   557  	b.chainLock.Unlock()
   558  	if err != nil {
   559  		return 0, err
   560  	}
   561  
   562  	var height int64
   563  	if stateNode != nil {
   564  		height = stateNode.height
   565  	}
   566  	return height, nil
   567  }
   568  
   569  // NextThresholdState returns the current rule change threshold state of the
   570  // given deployment ID for the block AFTER the provided block hash.
   571  //
   572  // This function is safe for concurrent access.
   573  func (b *BlockChain) NextThresholdState(hash *chainhash.Hash, version uint32, deploymentID string) (ThresholdStateTuple, error) {
   574  	// NOTE: The requirement for the node being fully validated here is strictly
   575  	// stronger than what is actually required.  In reality, all that is needed
   576  	// is for the block data for the node and all of its ancestors to be
   577  	// available, but there is not currently any tracking to be able to
   578  	// efficiently determine that state.
   579  	node := b.index.LookupNode(hash)
   580  	if node == nil || !b.index.NodeStatus(node).KnownValid() {
   581  		invalidState := ThresholdStateTuple{
   582  			State:  ThresholdInvalid,
   583  			Choice: invalidChoice,
   584  		}
   585  		return invalidState, HashError(hash.String())
   586  	}
   587  
   588  	b.chainLock.Lock()
   589  	state, err := b.deploymentState(node, version, deploymentID)
   590  	b.chainLock.Unlock()
   591  	return state, err
   592  }
   593  
   594  // isLNFeaturesAgendaActive returns whether or not the LN features agenda vote,
   595  // as defined in DCP0002 and DCP0003 has passed and is now active from the point
   596  // of view of the passed block node.
   597  //
   598  // It is important to note that, as the variable name indicates, this function
   599  // expects the block node prior to the block for which the deployment state is
   600  // desired.  In other words, the returned deployment state is for the block
   601  // AFTER the passed node.
   602  //
   603  // This function MUST be called with the chain state lock held (for writes).
   604  func (b *BlockChain) isLNFeaturesAgendaActive(prevNode *blockNode) (bool, error) {
   605  	// Determine the correct deployment version for the LN features consensus
   606  	// vote as defined in DCP0002 and DCP0003 or treat it as active when voting
   607  	// is not enabled for the current network.
   608  	const deploymentID = chaincfg.VoteIDLNFeatures
   609  	deploymentVer, ok := b.deploymentVers[deploymentID]
   610  	if !ok {
   611  		return true, nil
   612  	}
   613  
   614  	state, err := b.deploymentState(prevNode, deploymentVer, deploymentID)
   615  	if err != nil {
   616  		return false, err
   617  	}
   618  
   619  	// NOTE: The choice field of the return threshold state is not examined
   620  	// here because there is only one possible choice that can be active for
   621  	// the agenda, which is yes, so there is no need to check it.
   622  	return state.State == ThresholdActive, nil
   623  
   624  }
   625  
   626  // IsLNFeaturesAgendaActive returns whether or not the LN features agenda vote,
   627  // as defined in DCP0002 and DCP0003 has passed and is now active for the block
   628  // AFTER the current best chain block.
   629  //
   630  // This function is safe for concurrent access.
   631  func (b *BlockChain) IsLNFeaturesAgendaActive() (bool, error) {
   632  	b.chainLock.Lock()
   633  	isActive, err := b.isLNFeaturesAgendaActive(b.bestChain.Tip())
   634  	b.chainLock.Unlock()
   635  	return isActive, err
   636  }
   637  
   638  // isFixSeqLocksAgendaActive returns whether or not the fix sequence locks
   639  // agenda vote, as defined in DCP0004 has passed and is now active from the
   640  // point of view of the passed block node.
   641  //
   642  // It is important to note that, as the variable name indicates, this function
   643  // expects the block node prior to the block for which the deployment state is
   644  // desired.  In other words, the returned deployment state is for the block
   645  // AFTER the passed node.
   646  //
   647  // This function MUST be called with the chain state lock held (for writes).
   648  func (b *BlockChain) isFixSeqLocksAgendaActive(prevNode *blockNode) (bool, error) {
   649  	// Determine the correct deployment version for the fix sequence locks
   650  	// consensus vote as defined in DCP0004 or treat it as active when voting
   651  	// is not enabled for the current network.
   652  	const deploymentID = chaincfg.VoteIDFixLNSeqLocks
   653  	deploymentVer, ok := b.deploymentVers[deploymentID]
   654  	if !ok {
   655  		return true, nil
   656  	}
   657  
   658  	state, err := b.deploymentState(prevNode, deploymentVer, deploymentID)
   659  	if err != nil {
   660  		return false, err
   661  	}
   662  
   663  	// NOTE: The choice field of the return threshold state is not examined
   664  	// here because there is only one possible choice that can be active for
   665  	// the agenda, which is yes, so there is no need to check it.
   666  	return state.State == ThresholdActive, nil
   667  }
   668  
   669  // IsFixSeqLocksAgendaActive returns whether or not whether or not the fix
   670  // sequence locks agenda vote, as defined in DCP0004 has passed and is now
   671  // active for the block AFTER the current best chain block.
   672  //
   673  // This function is safe for concurrent access.
   674  func (b *BlockChain) IsFixSeqLocksAgendaActive() (bool, error) {
   675  	b.chainLock.Lock()
   676  	isActive, err := b.isFixSeqLocksAgendaActive(b.bestChain.Tip())
   677  	b.chainLock.Unlock()
   678  	return isActive, err
   679  }
   680  
   681  // VoteCounts is a compacted struct that is used to message vote counts.
   682  type VoteCounts struct {
   683  	Total        uint32
   684  	TotalAbstain uint32
   685  	VoteChoices  []uint32
   686  }
   687  
   688  // getVoteCounts returns the vote counts for the specified version for the
   689  // current rule change activation interval.
   690  //
   691  // This function MUST be called with the chain state lock held (for writes).
   692  func (b *BlockChain) getVoteCounts(node *blockNode, version uint32, d *chaincfg.ConsensusDeployment) (VoteCounts, error) {
   693  	// Don't try to count votes before the stake validation height since there
   694  	// could not possibly have been any.
   695  	svh := b.chainParams.StakeValidationHeight
   696  	if node.height < svh {
   697  		return VoteCounts{
   698  			VoteChoices: make([]uint32, len(d.Vote.Choices)),
   699  		}, nil
   700  	}
   701  
   702  	// Calculate the final height of the prior interval.
   703  	rcai := int64(b.chainParams.RuleChangeActivationInterval)
   704  	height := calcWantHeight(svh, rcai, node.height)
   705  
   706  	result := VoteCounts{
   707  		VoteChoices: make([]uint32, len(d.Vote.Choices)),
   708  	}
   709  	countNode := node
   710  	for countNode.height > height {
   711  		for _, vote := range countNode.votes {
   712  			// Wrong versions do not count.
   713  			if vote.Version != version {
   714  				continue
   715  			}
   716  
   717  			// Increase total votes.
   718  			result.Total++
   719  
   720  			index := d.Vote.VoteIndex(vote.Bits)
   721  			if index == -1 {
   722  				// Invalid votes are treated as abstain.
   723  				result.TotalAbstain++
   724  				continue
   725  			} else if d.Vote.Choices[index].IsAbstain {
   726  				result.TotalAbstain++
   727  			}
   728  			result.VoteChoices[index]++
   729  		}
   730  
   731  		countNode = countNode.parent
   732  	}
   733  
   734  	return result, nil
   735  }
   736  
   737  // GetVoteCounts returns the vote counts for the specified version and
   738  // deployment identifier for the current rule change activation interval.
   739  //
   740  // This function is safe for concurrent access.
   741  func (b *BlockChain) GetVoteCounts(version uint32, deploymentID string) (VoteCounts, error) {
   742  	for k := range b.chainParams.Deployments[version] {
   743  		deployment := &b.chainParams.Deployments[version][k]
   744  		if deployment.Vote.Id == deploymentID {
   745  			b.chainLock.Lock()
   746  			counts, err := b.getVoteCounts(b.bestChain.Tip(), version, deployment)
   747  			b.chainLock.Unlock()
   748  			return counts, err
   749  		}
   750  	}
   751  	return VoteCounts{}, DeploymentError(deploymentID)
   752  }
   753  
   754  // CountVoteVersion returns the total number of version votes for the current
   755  // rule change activation interval.
   756  //
   757  // This function is safe for concurrent access.
   758  func (b *BlockChain) CountVoteVersion(version uint32) (uint32, error) {
   759  	b.chainLock.Lock()
   760  	defer b.chainLock.Unlock()
   761  	countNode := b.bestChain.Tip()
   762  
   763  	// Don't try to count votes before the stake validation height since there
   764  	// could not possibly have been any.
   765  	svh := b.chainParams.StakeValidationHeight
   766  	if countNode.height < svh {
   767  		return 0, nil
   768  	}
   769  
   770  	// Calculate the final height of the prior interval.
   771  	rcai := int64(b.chainParams.RuleChangeActivationInterval)
   772  	height := calcWantHeight(svh, rcai, countNode.height)
   773  
   774  	total := uint32(0)
   775  	for countNode.height > height {
   776  		for _, vote := range countNode.votes {
   777  			// Wrong versions do not count.
   778  			if vote.Version != version {
   779  				continue
   780  			}
   781  
   782  			// Increase total votes.
   783  			total++
   784  		}
   785  
   786  		countNode = countNode.parent
   787  	}
   788  
   789  	return total, nil
   790  }