diff --git a/snow/consensus/snowball/binary_snowball_test.go b/snow/consensus/snowball/binary_snowball_test.go index bd0d7fcf8cd4..968743ef36a8 100644 --- a/snow/consensus/snowball/binary_snowball_test.go +++ b/snow/consensus/snowball/binary_snowball_test.go @@ -19,26 +19,25 @@ func TestBinarySnowball(t *testing.T) { beta := 2 terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) - sf := newBinarySnowflake(alphaPreference, terminationConditions, red) - - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb := newBinarySnowball(alphaPreference, terminationConditions, red) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, red) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.True(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.True(sb.Finalized()) } func TestBinarySnowballRecordPollPreference(t *testing.T) { @@ -51,32 +50,32 @@ func TestBinarySnowballRecordPollPreference(t *testing.T) { beta := 2 terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) - sf := newBinarySnowflake(alphaPreference, terminationConditions, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb := newBinarySnowball(alphaPreference, terminationConditions, red) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, red) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaPreference, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaPreference, red) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, red) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, red) - require.Equal(red, sf.Preference()) - require.True(sf.Finalized()) + sb.RecordPoll(alphaConfidence, red) + require.Equal(red, sb.Preference()) + require.True(sb.Finalized()) - expected := "SF(Confidence = [2], Finalized = true, SL(Preference = 0))" - require.Equal(expected, sf.String()) + expected := "SB(Preference = 0, PreferenceStrength[0] = 4, PreferenceStrength[1] = 1, SF(Confidence = [2], Finalized = true, SL(Preference = 0)))" + require.Equal(expected, sb.String()) } func TestBinarySnowballRecordUnsuccessfulPoll(t *testing.T) { @@ -89,26 +88,26 @@ func TestBinarySnowballRecordUnsuccessfulPoll(t *testing.T) { beta := 2 terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) - sf := newBinarySnowflake(alphaPreference, terminationConditions, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + sb := newBinarySnowball(alphaPreference, terminationConditions, red) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordUnsuccessfulPoll() + sb.RecordUnsuccessfulPoll() - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.False(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.True(sf.Finalized()) + sb.RecordPoll(alphaConfidence, blue) + require.Equal(blue, sb.Preference()) + require.True(sb.Finalized()) - expected := "SF(Confidence = [2], Finalized = true, SL(Preference = 1))" - require.Equal(expected, sf.String()) + expected := "SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 3, SF(Confidence = [2], Finalized = true, SL(Preference = 1)))" + require.Equal(expected, sb.String()) } func TestBinarySnowballAcceptWeirdColor(t *testing.T) { @@ -121,36 +120,36 @@ func TestBinarySnowballAcceptWeirdColor(t *testing.T) { beta := 2 terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) - sf := newBinarySnowflake(alphaPreference, terminationConditions, red) + sb := newBinarySnowball(alphaPreference, terminationConditions, red) - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, red) - sf.RecordUnsuccessfulPoll() + sb.RecordPoll(alphaConfidence, red) + sb.RecordUnsuccessfulPoll() - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, red) + sb.RecordPoll(alphaConfidence, red) - sf.RecordUnsuccessfulPoll() + sb.RecordUnsuccessfulPoll() - require.Equal(red, sf.Preference()) - require.False(sf.Finalized()) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) + sb.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.False(sf.Finalized()) + require.Equal(red, sb.Preference()) + require.False(sb.Finalized()) - sf.RecordPoll(alphaConfidence, blue) + sb.RecordPoll(alphaConfidence, blue) - require.Equal(blue, sf.Preference()) - require.True(sf.Finalized()) + require.Equal(blue, sb.Preference()) + require.True(sb.Finalized()) - expected := "SF(Confidence = [2], Finalized = true, SL(Preference = 0))" - require.Equal(expected, sf.String()) + expected := "SB(Preference = 1, PreferenceStrength[0] = 2, PreferenceStrength[1] = 2, SF(Confidence = [2], Finalized = true, SL(Preference = 0)))" + require.Equal(expected, sb.String()) } func TestBinarySnowballLockColor(t *testing.T) { diff --git a/snow/consensus/snowball/nnary_snowball_test.go b/snow/consensus/snowball/nnary_snowball_test.go new file mode 100644 index 000000000000..8a5e66143db2 --- /dev/null +++ b/snow/consensus/snowball/nnary_snowball_test.go @@ -0,0 +1,133 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package snowball + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNnarySnowball(t *testing.T) { + require := require.New(t) + + alphaPreference, alphaConfidence := 1, 2 + beta := 2 + terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) + + sb := newNnarySnowball(alphaPreference, terminationConditions, Red) + sb.Add(Blue) + sb.Add(Green) + + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Blue) + require.Equal(Blue, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Red) + require.Equal(Blue, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaPreference, Red) + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Red) + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaPreference, Blue) + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Blue) + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Blue) + require.Equal(Blue, sb.Preference()) + require.True(sb.Finalized()) +} + +func TestVirtuousNnarySnowball(t *testing.T) { + require := require.New(t) + + alphaPreference, alphaConfidence := 1, 2 + beta := 1 + terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) + + sb := newNnarySnowball(alphaPreference, terminationConditions, Red) + + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Red) + require.Equal(Red, sb.Preference()) + require.True(sb.Finalized()) +} + +func TestNarySnowballRecordUnsuccessfulPoll(t *testing.T) { + require := require.New(t) + + alphaPreference, alphaConfidence := 1, 2 + beta := 2 + terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) + + sb := newNnarySnowball(alphaPreference, terminationConditions, Red) + sb.Add(Blue) + + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Blue) + require.Equal(Blue, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordUnsuccessfulPoll() + + sb.RecordPoll(alphaConfidence, Blue) + + require.Equal(Blue, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Blue) + + require.Equal(Blue, sb.Preference()) + require.True(sb.Finalized()) + + 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++ { + sb.RecordPoll(alphaConfidence, Red) + + require.Equal(Blue, sb.Preference()) + require.True(sb.Finalized()) + } +} + +func TestNarySnowballDifferentSnowflakeColor(t *testing.T) { + require := require.New(t) + + alphaPreference, alphaConfidence := 1, 2 + beta := 2 + terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) + + sb := newNnarySnowball(alphaPreference, terminationConditions, Red) + sb.Add(Blue) + + require.Equal(Red, sb.Preference()) + require.False(sb.Finalized()) + + sb.RecordPoll(alphaConfidence, Blue) + + require.Equal(Blue, sb.nnarySnowflake.Preference()) + + sb.RecordPoll(alphaConfidence, Red) + + require.Equal(Blue, sb.Preference()) + require.Equal(Red, sb.nnarySnowflake.Preference()) +} diff --git a/snow/consensus/snowball/unary_snowball_test.go b/snow/consensus/snowball/unary_snowball_test.go new file mode 100644 index 000000000000..007d2ab53090 --- /dev/null +++ b/snow/consensus/snowball/unary_snowball_test.go @@ -0,0 +1,76 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package snowball + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func UnarySnowballStateTest(t *testing.T, sb *unarySnowball, expectedPreferenceStrength int, expectedConfidence []int, expectedFinalized bool) { + require := require.New(t) + + require.Equal(expectedPreferenceStrength, sb.preferenceStrength) + require.Equal(expectedConfidence, sb.confidence) + require.Equal(expectedFinalized, sb.Finalized()) +} + +func TestUnarySnowball(t *testing.T) { + require := require.New(t) + + alphaPreference, alphaConfidence := 1, 2 + beta := 2 + terminationConditions := newSingleTerminationCondition(alphaConfidence, beta) + + sb := newUnarySnowball(alphaPreference, terminationConditions) + + sb.RecordPoll(alphaConfidence) + UnarySnowballStateTest(t, &sb, 1, []int{1}, false) + + sb.RecordPoll(alphaPreference) + UnarySnowballStateTest(t, &sb, 2, []int{0}, false) + + sb.RecordPoll(alphaConfidence) + UnarySnowballStateTest(t, &sb, 3, []int{1}, false) + + sb.RecordUnsuccessfulPoll() + UnarySnowballStateTest(t, &sb, 3, []int{0}, false) + + sb.RecordPoll(alphaConfidence) + UnarySnowballStateTest(t, &sb, 4, []int{1}, false) + + sbCloneIntf := sb.Clone() + require.IsType(&unarySnowball{}, sbCloneIntf) + sbClone := sbCloneIntf.(*unarySnowball) + + UnarySnowballStateTest(t, sbClone, 4, []int{1}, false) + + binarySnowball := sbClone.Extend(0) + + expected := "SB(Preference = 0, PreferenceStrength[0] = 4, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0)))" + require.Equal(expected, binarySnowball.String()) + + binarySnowball.RecordUnsuccessfulPoll() + for i := 0; i < 5; i++ { + require.Zero(binarySnowball.Preference()) + require.False(binarySnowball.Finalized()) + binarySnowball.RecordPoll(alphaConfidence, 1) + binarySnowball.RecordUnsuccessfulPoll() + } + + require.Equal(1, binarySnowball.Preference()) + require.False(binarySnowball.Finalized()) + + binarySnowball.RecordPoll(alphaConfidence, 1) + require.Equal(1, binarySnowball.Preference()) + require.False(binarySnowball.Finalized()) + + binarySnowball.RecordPoll(alphaConfidence, 1) + require.Equal(1, binarySnowball.Preference()) + require.True(binarySnowball.Finalized()) + + expected = "SB(PreferenceStrength = 4, SF(Confidence = [1], Finalized = false))" + require.Equal(expected, sb.String()) +} diff --git a/snow/consensus/snowman/mixed_test.go b/snow/consensus/snowman/mixed_test.go index a5b30d19dad9..f495923e6e87 100644 --- a/snow/consensus/snowman/mixed_test.go +++ b/snow/consensus/snowman/mixed_test.go @@ -33,15 +33,15 @@ func TestConvergenceSnowFlakeSnowBall(t *testing.T) { t.Run(fmt.Sprintf("%d nodes", numNodes), func(t *testing.T) { n := NewNetwork(params, 10, prng.NewMT19937()) for i := 0; i < numNodes; i++ { - var sm Consensus + var sbFactory snowball.Factory if i%2 == 0 { - factory := TopologicalFactory{factory: snowball.SnowflakeFactory} - sm = factory.New() + sbFactory = snowball.SnowflakeFactory } else { - factory := TopologicalFactory{factory: snowball.SnowballFactory} - sm = factory.New() + sbFactory = snowball.SnowballFactory } + factory := TopologicalFactory{factory: sbFactory} + sm := factory.New() require.NoError(n.AddNode(t, sm)) }