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 }