2020-03-10 12:20:34 -07:00
|
|
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
|
|
|
|
package snowball
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// binarySnowflake is the implementation of a binary snowflake instance
|
|
|
|
type binarySnowflake struct {
|
2020-03-20 23:26:22 -07:00
|
|
|
// wrap the binary slush logic
|
|
|
|
binarySlush
|
2020-03-10 12:20:34 -07:00
|
|
|
|
|
|
|
// confidence tracks the number of successful polls in a row that have
|
|
|
|
// returned the preference
|
|
|
|
confidence int
|
|
|
|
|
|
|
|
// beta is the number of consecutive successful queries required for
|
|
|
|
// finalization.
|
|
|
|
beta int
|
|
|
|
|
|
|
|
// finalized prevents the state from changing after the required number of
|
|
|
|
// consecutive polls has been reached
|
|
|
|
finalized bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize implements the BinarySnowflake interface
|
|
|
|
func (sf *binarySnowflake) Initialize(beta, choice int) {
|
2020-03-20 23:26:22 -07:00
|
|
|
sf.binarySlush.Initialize(choice)
|
2020-03-10 12:20:34 -07:00
|
|
|
sf.beta = beta
|
|
|
|
}
|
|
|
|
|
|
|
|
// RecordSuccessfulPoll implements the BinarySnowflake interface
|
|
|
|
func (sf *binarySnowflake) RecordSuccessfulPoll(choice int) {
|
2020-03-20 23:26:22 -07:00
|
|
|
if sf.finalized {
|
2020-03-10 12:20:34 -07:00
|
|
|
return // This instace is already decided.
|
|
|
|
}
|
|
|
|
|
2020-03-20 23:26:22 -07:00
|
|
|
if preference := sf.Preference(); preference == choice {
|
2020-03-10 12:20:34 -07:00
|
|
|
sf.confidence++
|
|
|
|
} else {
|
|
|
|
// confidence is set to 1 because there has already been 1 successful
|
|
|
|
// poll, namely this poll.
|
|
|
|
sf.confidence = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
sf.finalized = sf.confidence >= sf.beta
|
2020-03-20 23:26:22 -07:00
|
|
|
sf.binarySlush.RecordSuccessfulPoll(choice)
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// RecordUnsuccessfulPoll implements the BinarySnowflake interface
|
|
|
|
func (sf *binarySnowflake) RecordUnsuccessfulPoll() { sf.confidence = 0 }
|
|
|
|
|
|
|
|
// Finalized implements the BinarySnowflake interface
|
|
|
|
func (sf *binarySnowflake) Finalized() bool { return sf.finalized }
|
|
|
|
|
|
|
|
func (sf *binarySnowflake) String() string {
|
2020-03-20 23:26:22 -07:00
|
|
|
return fmt.Sprintf("SF(Confidence = %d, Finalized = %v, %s)",
|
2020-03-10 12:20:34 -07:00
|
|
|
sf.confidence,
|
2020-03-20 23:26:22 -07:00
|
|
|
sf.finalized,
|
|
|
|
&sf.binarySlush)
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|