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"
|
|
|
|
)
|
|
|
|
|
|
|
|
// binarySnowball is the implementation of a binary snowball instance
|
|
|
|
type binarySnowball struct {
|
2020-03-20 18:26:52 -07:00
|
|
|
// wrap the binary snowflake logic
|
|
|
|
binarySnowflake
|
|
|
|
|
2020-03-10 12:20:34 -07:00
|
|
|
// preference is the choice with the largest number of successful polls.
|
|
|
|
// Ties are broken by switching choice lazily
|
|
|
|
preference int
|
|
|
|
|
|
|
|
// numSuccessfulPolls tracks the total number of successful network polls of
|
|
|
|
// the 0 and 1 choices
|
|
|
|
numSuccessfulPolls [2]int
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize implements the BinarySnowball interface
|
|
|
|
func (sb *binarySnowball) Initialize(beta, choice int) {
|
2020-03-20 18:26:52 -07:00
|
|
|
sb.binarySnowflake.Initialize(beta, choice)
|
2020-03-20 23:26:22 -07:00
|
|
|
sb.preference = choice
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Preference implements the BinarySnowball interface
|
|
|
|
func (sb *binarySnowball) Preference() int {
|
|
|
|
// It is possible, with low probability, that the snowflake preference is
|
|
|
|
// not equal to the snowball preference when snowflake finalizes. However,
|
|
|
|
// this case is handled for completion. Therefore, if snowflake is
|
|
|
|
// finalized, then our finalized snowflake choice should be preferred.
|
|
|
|
if sb.Finalized() {
|
2020-03-20 18:26:52 -07:00
|
|
|
return sb.binarySnowflake.Preference()
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
return sb.preference
|
|
|
|
}
|
|
|
|
|
|
|
|
// RecordSuccessfulPoll implements the BinarySnowball interface
|
|
|
|
func (sb *binarySnowball) RecordSuccessfulPoll(choice int) {
|
|
|
|
sb.numSuccessfulPolls[choice]++
|
|
|
|
if sb.numSuccessfulPolls[choice] > sb.numSuccessfulPolls[1-choice] {
|
|
|
|
sb.preference = choice
|
|
|
|
}
|
2020-03-20 18:26:52 -07:00
|
|
|
sb.binarySnowflake.RecordSuccessfulPoll(choice)
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sb *binarySnowball) String() string {
|
|
|
|
return fmt.Sprintf(
|
2020-03-20 23:26:22 -07:00
|
|
|
"SB(Preference = %d, NumSuccessfulPolls[0] = %d, NumSuccessfulPolls[1] = %d, %s)",
|
2020-03-10 12:20:34 -07:00
|
|
|
sb.preference,
|
|
|
|
sb.numSuccessfulPolls[0],
|
|
|
|
sb.numSuccessfulPolls[1],
|
2020-03-20 18:26:52 -07:00
|
|
|
&sb.binarySnowflake)
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|