Skip to content

Commit

Permalink
Error driven snowflake multi counter (#3092)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronbuchwald committed Jun 12, 2024
1 parent 41e46d1 commit 5002b82
Show file tree
Hide file tree
Showing 17 changed files with 503 additions and 233 deletions.
4 changes: 2 additions & 2 deletions snow/consensus/snowball/binary_snowball.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import "fmt"

var _ Binary = (*binarySnowball)(nil)

func newBinarySnowball(alphaPreference int, alphaConfidence int, beta int, choice int) binarySnowball {
func newBinarySnowball(alphaPreference int, terminationConditions []terminationCondition, choice int) binarySnowball {
return binarySnowball{
binarySnowflake: newBinarySnowflake(alphaPreference, alphaConfidence, beta, choice),
binarySnowflake: newBinarySnowflake(alphaPreference, terminationConditions, choice),
preference: choice,
}
}
Expand Down
23 changes: 14 additions & 9 deletions snow/consensus/snowball/binary_snowball_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ func TestBinarySnowball(t *testing.T) {

alphaPreference, alphaConfidence := 2, 3
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newBinarySnowball(alphaPreference, alphaConfidence, beta, red)
sb := newBinarySnowball(alphaPreference, terminationConditions, red)
require.Equal(red, sb.Preference())
require.False(sb.Finalized())

Expand Down Expand Up @@ -47,8 +48,9 @@ func TestBinarySnowballRecordPollPreference(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newBinarySnowball(alphaPreference, alphaConfidence, beta, red)
sb := newBinarySnowball(alphaPreference, terminationConditions, red)
require.Equal(red, sb.Preference())
require.False(sb.Finalized())

Expand All @@ -72,7 +74,7 @@ func TestBinarySnowballRecordPollPreference(t *testing.T) {
require.Equal(red, sb.Preference())
require.True(sb.Finalized())

expected := "SB(Preference = 0, PreferenceStrength[0] = 4, PreferenceStrength[1] = 1, SF(Confidence = 2, Finalized = true, SL(Preference = 0)))"
expected := "SB(Preference = 0, PreferenceStrength[0] = 4, PreferenceStrength[1] = 1, SF(Confidence = [2], Finalized = true, SL(Preference = 0)))"
require.Equal(expected, sb.String())
}

Expand All @@ -84,8 +86,9 @@ func TestBinarySnowballRecordUnsuccessfulPoll(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newBinarySnowball(alphaPreference, alphaConfidence, beta, red)
sb := newBinarySnowball(alphaPreference, terminationConditions, red)
require.Equal(red, sb.Preference())
require.False(sb.Finalized())

Expand All @@ -103,7 +106,7 @@ func TestBinarySnowballRecordUnsuccessfulPoll(t *testing.T) {
require.Equal(blue, sb.Preference())
require.True(sb.Finalized())

expected := "SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 3, SF(Confidence = 2, Finalized = true, SL(Preference = 1)))"
expected := "SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 3, SF(Confidence = [2], Finalized = true, SL(Preference = 1)))"
require.Equal(expected, sb.String())
}

Expand All @@ -115,8 +118,9 @@ func TestBinarySnowballAcceptWeirdColor(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newBinarySnowball(alphaPreference, alphaConfidence, beta, red)
sb := newBinarySnowball(alphaPreference, terminationConditions, red)

require.Equal(red, sb.Preference())
require.False(sb.Finalized())
Expand Down Expand Up @@ -144,7 +148,7 @@ func TestBinarySnowballAcceptWeirdColor(t *testing.T) {
require.Equal(blue, sb.Preference())
require.True(sb.Finalized())

expected := "SB(Preference = 1, PreferenceStrength[0] = 2, PreferenceStrength[1] = 2, SF(Confidence = 2, Finalized = true, SL(Preference = 0)))"
expected := "SB(Preference = 1, PreferenceStrength[0] = 2, PreferenceStrength[1] = 2, SF(Confidence = [2], Finalized = true, SL(Preference = 0)))"
require.Equal(expected, sb.String())
}

Expand All @@ -156,8 +160,9 @@ func TestBinarySnowballLockColor(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 1
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newBinarySnowball(alphaPreference, alphaConfidence, beta, red)
sb := newBinarySnowball(alphaPreference, terminationConditions, red)

sb.RecordPoll(alphaConfidence, red)

Expand All @@ -175,6 +180,6 @@ func TestBinarySnowballLockColor(t *testing.T) {
require.Equal(red, sb.Preference())
require.True(sb.Finalized())

expected := "SB(Preference = 1, PreferenceStrength[0] = 1, PreferenceStrength[1] = 3, SF(Confidence = 1, Finalized = true, SL(Preference = 0)))"
expected := "SB(Preference = 1, PreferenceStrength[0] = 1, PreferenceStrength[1] = 3, SF(Confidence = [1], Finalized = true, SL(Preference = 0)))"
require.Equal(expected, sb.String())
}
19 changes: 7 additions & 12 deletions snow/consensus/snowball/binary_snowflake.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@ import "fmt"

var _ Binary = (*binarySnowflake)(nil)

func newBinarySnowflake(alphaPreference, alphaConfidence, beta, choice int) binarySnowflake {
func newBinarySnowflake(alphaPreference int, terminationConditions []terminationCondition, choice int) binarySnowflake {
return binarySnowflake{
binarySlush: newBinarySlush(choice),
alphaPreference: alphaPreference,
terminationConditions: []terminationCondition{
{
alphaConfidence: alphaConfidence,
beta: beta,
},
},
confidence: make([]int, 1),
binarySlush: newBinarySlush(choice),
alphaPreference: alphaPreference,
terminationConditions: terminationConditions,
confidence: make([]int, len(terminationConditions)),
}
}

Expand Down Expand Up @@ -94,8 +89,8 @@ func (sf *binarySnowflake) Finalized() bool {
}

func (sf *binarySnowflake) String() string {
return fmt.Sprintf("SF(Confidence = %d, Finalized = %v, %s)",
sf.confidence[0],
return fmt.Sprintf("SF(Confidence = %v, Finalized = %v, %s)",
sf.confidence,
sf.finalized,
&sf.binarySlush)
}
44 changes: 43 additions & 1 deletion snow/consensus/snowball/binary_snowflake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ func TestBinarySnowflake(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sf := newBinarySnowflake(alphaPreference, alphaConfidence, beta, red)
sf := newBinarySnowflake(alphaPreference, terminationConditions, red)

require.Equal(red, sf.Preference())
require.False(sf.Finalized())
Expand Down Expand Up @@ -50,3 +51,44 @@ func TestBinarySnowflake(t *testing.T) {
require.Equal(blue, sf.Preference())
require.True(sf.Finalized())
}

type binarySnowflakeTest struct {
require *require.Assertions

binarySnowflake
}

func newBinarySnowflakeTest(t *testing.T, alphaPreference int, terminationConditions []terminationCondition) snowflakeTest[int] {
require := require.New(t)

return &binarySnowflakeTest{
require: require,
binarySnowflake: newBinarySnowflake(alphaPreference, terminationConditions, 0),
}
}

func (sf *binarySnowflakeTest) RecordPoll(count int, choice int) {
sf.binarySnowflake.RecordPoll(count, choice)
}

func (sf *binarySnowflakeTest) AssertEqual(expectedConfidences []int, expectedFinalized bool, expectedPreference int) {
sf.require.Equal(expectedPreference, sf.Preference())
sf.require.Equal(expectedConfidences, sf.binarySnowflake.confidence)
sf.require.Equal(expectedFinalized, sf.Finalized())
}

func TestBinarySnowflakeErrorDrivenSingleChoice(t *testing.T) {
for _, test := range getErrorDrivenSnowflakeSingleChoiceSuite[int]() {
t.Run(test.name, func(t *testing.T) {
test.f(t, newBinarySnowflakeTest, 0)
})
}
}

func TestBinarySnowflakeErrorDrivenMultiChoice(t *testing.T) {
for _, test := range getErrorDrivenSnowflakeMultiChoiceSuite[int]() {
t.Run(test.name, func(t *testing.T) {
test.f(t, newBinarySnowflakeTest, 0, 1)
})
}
}
8 changes: 4 additions & 4 deletions snow/consensus/snowball/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ var (
type snowballFactory struct{}

func (snowballFactory) NewNnary(params Parameters, choice ids.ID) Nnary {
sb := newNnarySnowball(params.AlphaPreference, params.AlphaConfidence, params.Beta, choice)
sb := newNnarySnowball(params.AlphaPreference, newSingleTerminationCondition(params.AlphaConfidence, params.Beta), choice)
return &sb
}

func (snowballFactory) NewUnary(params Parameters) Unary {
sb := newUnarySnowball(params.AlphaPreference, params.AlphaConfidence, params.Beta)
sb := newUnarySnowball(params.AlphaPreference, newSingleTerminationCondition(params.AlphaConfidence, params.Beta))
return &sb
}

type snowflakeFactory struct{}

func (snowflakeFactory) NewNnary(params Parameters, choice ids.ID) Nnary {
sf := newNnarySnowflake(params.AlphaPreference, params.AlphaConfidence, params.Beta, choice)
sf := newNnarySnowflake(params.AlphaPreference, newSingleTerminationCondition(params.AlphaConfidence, params.Beta), choice)
return &sf
}

func (snowflakeFactory) NewUnary(params Parameters) Unary {
sf := newUnarySnowflake(params.AlphaPreference, params.AlphaConfidence, params.Beta)
sf := newUnarySnowflake(params.AlphaPreference, newSingleTerminationCondition(params.AlphaConfidence, params.Beta))
return &sf
}
2 changes: 1 addition & 1 deletion snow/consensus/snowball/flat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ func TestFlat(t *testing.T) {
require.Equal(Green, f.Preference())
require.True(f.Finalized())

expected := "SB(Preference = 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w, PreferenceStrength = 4, SF(Confidence = 2, Finalized = true, SL(Preference = 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w)))"
expected := "SB(Preference = 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w, PreferenceStrength = 4, SF(Confidence = [2], Finalized = true, SL(Preference = 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w)))"
require.Equal(expected, f.String())
}
4 changes: 2 additions & 2 deletions snow/consensus/snowball/nnary_snowball.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (

var _ Nnary = (*nnarySnowball)(nil)

func newNnarySnowball(alphaPreference, alphaConfidence, beta int, choice ids.ID) nnarySnowball {
func newNnarySnowball(alphaPreference int, terminationConditions []terminationCondition, choice ids.ID) nnarySnowball {
return nnarySnowball{
nnarySnowflake: newNnarySnowflake(alphaPreference, alphaConfidence, beta, choice),
nnarySnowflake: newNnarySnowflake(alphaPreference, terminationConditions, choice),
preference: choice,
preferenceStrength: make(map[ids.ID]int),
}
Expand Down
14 changes: 9 additions & 5 deletions snow/consensus/snowball/nnary_snowball_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ func TestNnarySnowball(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newNnarySnowball(alphaPreference, alphaConfidence, beta, Red)
sb := newNnarySnowball(alphaPreference, terminationConditions, Red)
sb.Add(Blue)
sb.Add(Green)

Expand Down Expand Up @@ -56,8 +57,9 @@ func TestVirtuousNnarySnowball(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 1
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newNnarySnowball(alphaPreference, alphaConfidence, beta, Red)
sb := newNnarySnowball(alphaPreference, terminationConditions, Red)

require.Equal(Red, sb.Preference())
require.False(sb.Finalized())
Expand All @@ -72,8 +74,9 @@ func TestNarySnowballRecordUnsuccessfulPoll(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newNnarySnowball(alphaPreference, alphaConfidence, beta, Red)
sb := newNnarySnowball(alphaPreference, terminationConditions, Red)
sb.Add(Blue)

require.Equal(Red, sb.Preference())
Expand All @@ -95,7 +98,7 @@ func TestNarySnowballRecordUnsuccessfulPoll(t *testing.T) {
require.Equal(Blue, sb.Preference())
require.True(sb.Finalized())

expected := "SB(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, PreferenceStrength = 3, SF(Confidence = 2, Finalized = true, SL(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES)))"
expected := "SB(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, PreferenceStrength = 3, SF(Confidence = [2], Finalized = true, SL(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES)))"
require.Equal(expected, sb.String())

for i := 0; i < 4; i++ {
Expand All @@ -111,8 +114,9 @@ func TestNarySnowballDifferentSnowflakeColor(t *testing.T) {

alphaPreference, alphaConfidence := 1, 2
beta := 2
terminationConditions := newSingleTerminationCondition(alphaConfidence, beta)

sb := newNnarySnowball(alphaPreference, alphaConfidence, beta, Red)
sb := newNnarySnowball(alphaPreference, terminationConditions, Red)
sb.Add(Blue)

require.Equal(Red, sb.Preference())
Expand Down
19 changes: 7 additions & 12 deletions snow/consensus/snowball/nnary_snowflake.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,12 @@ import (

var _ Nnary = (*nnarySnowflake)(nil)

func newNnarySnowflake(alphaPreference, alphaConfidence, beta int, choice ids.ID) nnarySnowflake {
func newNnarySnowflake(alphaPreference int, terminationConditions []terminationCondition, choice ids.ID) nnarySnowflake {
return nnarySnowflake{
nnarySlush: newNnarySlush(choice),
alphaPreference: alphaPreference,
terminationConditions: []terminationCondition{
{
alphaConfidence: alphaConfidence,
beta: beta,
},
},
confidence: make([]int, 1),
nnarySlush: newNnarySlush(choice),
alphaPreference: alphaPreference,
terminationConditions: terminationConditions,
confidence: make([]int, len(terminationConditions)),
}
}

Expand Down Expand Up @@ -101,8 +96,8 @@ func (sf *nnarySnowflake) Finalized() bool {
}

func (sf *nnarySnowflake) String() string {
return fmt.Sprintf("SF(Confidence = %d, Finalized = %v, %s)",
sf.confidence[0],
return fmt.Sprintf("SF(Confidence = %v, Finalized = %v, %s)",
sf.confidence,
sf.finalized,
&sf.nnarySlush)
}
Loading

0 comments on commit 5002b82

Please sign in to comment.