github.com/MetalBlockchain/metalgo@v1.11.9/snow/consensus/snowball/binary_snowball.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package snowball
     5  
     6  import "fmt"
     7  
     8  var _ Binary = (*binarySnowball)(nil)
     9  
    10  func newBinarySnowball(alphaPreference int, terminationConditions []terminationCondition, choice int) binarySnowball {
    11  	return binarySnowball{
    12  		binarySnowflake: newBinarySnowflake(alphaPreference, terminationConditions, choice),
    13  		preference:      choice,
    14  	}
    15  }
    16  
    17  // binarySnowball is the implementation of a binary snowball instance
    18  type binarySnowball struct {
    19  	// wrap the binary snowflake logic
    20  	binarySnowflake
    21  
    22  	// preference is the choice with the largest number of polls which preferred
    23  	// the color. Ties are broken by switching choice lazily
    24  	preference int
    25  
    26  	// preferenceStrength tracks the total number of network polls which
    27  	// preferred each choice
    28  	preferenceStrength [2]int
    29  }
    30  
    31  func (sb *binarySnowball) Preference() int {
    32  	// It is possible, with low probability, that the snowflake preference is
    33  	// not equal to the snowball preference when snowflake finalizes. However,
    34  	// this case is handled for completion. Therefore, if snowflake is
    35  	// finalized, then our finalized snowflake choice should be preferred.
    36  	if sb.Finalized() {
    37  		return sb.binarySnowflake.Preference()
    38  	}
    39  	return sb.preference
    40  }
    41  
    42  func (sb *binarySnowball) RecordPoll(count, choice int) {
    43  	if count >= sb.alphaPreference {
    44  		sb.preferenceStrength[choice]++
    45  		if sb.preferenceStrength[choice] > sb.preferenceStrength[1-choice] {
    46  			sb.preference = choice
    47  		}
    48  	}
    49  	sb.binarySnowflake.RecordPoll(count, choice)
    50  }
    51  
    52  func (sb *binarySnowball) String() string {
    53  	return fmt.Sprintf(
    54  		"SB(Preference = %d, PreferenceStrength[0] = %d, PreferenceStrength[1] = %d, %s)",
    55  		sb.preference,
    56  		sb.preferenceStrength[0],
    57  		sb.preferenceStrength[1],
    58  		&sb.binarySnowflake)
    59  }