github.com/MetalBlockchain/metalgo@v1.11.9/snow/consensus/snowball/tree_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  //nolint:goconst
     5  package snowball
     6  
     7  import (
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  	"gonum.org/v1/gonum/mathext/prng"
    13  
    14  	"github.com/MetalBlockchain/metalgo/ids"
    15  	"github.com/MetalBlockchain/metalgo/utils/bag"
    16  )
    17  
    18  const initialUnaryDescription = "SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [0, 256)"
    19  
    20  func TestSnowballSingleton(t *testing.T) {
    21  	require := require.New(t)
    22  
    23  	params := Parameters{
    24  		K:               1,
    25  		AlphaPreference: 1,
    26  		AlphaConfidence: 1,
    27  		Beta:            2,
    28  	}
    29  	tree := NewTree(SnowballFactory, params, Red)
    30  
    31  	require.False(tree.Finalized())
    32  
    33  	oneRed := bag.Of(Red)
    34  	require.True(tree.RecordPoll(oneRed))
    35  	require.False(tree.Finalized())
    36  
    37  	empty := bag.Bag[ids.ID]{}
    38  	require.False(tree.RecordPoll(empty))
    39  	require.False(tree.Finalized())
    40  
    41  	require.True(tree.RecordPoll(oneRed))
    42  	require.False(tree.Finalized())
    43  
    44  	require.True(tree.RecordPoll(oneRed))
    45  	require.Equal(Red, tree.Preference())
    46  	require.True(tree.Finalized())
    47  
    48  	tree.Add(Blue)
    49  
    50  	require.True(tree.Finalized())
    51  
    52  	// Because the tree is already finalized, RecordPoll can return either true
    53  	// or false.
    54  	oneBlue := bag.Of(Blue)
    55  	tree.RecordPoll(oneBlue)
    56  	require.Equal(Red, tree.Preference())
    57  	require.True(tree.Finalized())
    58  }
    59  
    60  func TestSnowballRecordUnsuccessfulPoll(t *testing.T) {
    61  	require := require.New(t)
    62  
    63  	params := Parameters{
    64  		K:               1,
    65  		AlphaPreference: 1,
    66  		AlphaConfidence: 1,
    67  		Beta:            3,
    68  	}
    69  	tree := NewTree(SnowballFactory, params, Red)
    70  
    71  	require.False(tree.Finalized())
    72  
    73  	oneRed := bag.Of(Red)
    74  	require.True(tree.RecordPoll(oneRed))
    75  
    76  	tree.RecordUnsuccessfulPoll()
    77  
    78  	require.True(tree.RecordPoll(oneRed))
    79  	require.False(tree.Finalized())
    80  
    81  	require.True(tree.RecordPoll(oneRed))
    82  	require.False(tree.Finalized())
    83  
    84  	require.True(tree.RecordPoll(oneRed))
    85  	require.Equal(Red, tree.Preference())
    86  	require.True(tree.Finalized())
    87  }
    88  
    89  func TestSnowballBinary(t *testing.T) {
    90  	require := require.New(t)
    91  
    92  	params := Parameters{
    93  		K:               1,
    94  		AlphaPreference: 1,
    95  		AlphaConfidence: 1,
    96  		Beta:            2,
    97  	}
    98  	tree := NewTree(SnowballFactory, params, Red)
    99  	tree.Add(Blue)
   100  
   101  	require.Equal(Red, tree.Preference())
   102  	require.False(tree.Finalized())
   103  
   104  	oneBlue := bag.Of(Blue)
   105  	require.True(tree.RecordPoll(oneBlue))
   106  	require.Equal(Blue, tree.Preference())
   107  	require.False(tree.Finalized())
   108  
   109  	oneRed := bag.Of(Red)
   110  	require.True(tree.RecordPoll(oneRed))
   111  	require.Equal(Blue, tree.Preference())
   112  	require.False(tree.Finalized())
   113  
   114  	require.True(tree.RecordPoll(oneBlue))
   115  	require.Equal(Blue, tree.Preference())
   116  	require.False(tree.Finalized())
   117  
   118  	require.True(tree.RecordPoll(oneBlue))
   119  	require.Equal(Blue, tree.Preference())
   120  	require.True(tree.Finalized())
   121  }
   122  
   123  func TestSnowballLastBinary(t *testing.T) {
   124  	require := require.New(t)
   125  
   126  	zero := ids.Empty
   127  	one := ids.ID{
   128  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   129  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   130  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   131  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
   132  	}
   133  
   134  	params := Parameters{
   135  		K:               1,
   136  		AlphaPreference: 1,
   137  		AlphaConfidence: 1,
   138  		Beta:            2,
   139  	}
   140  	tree := NewTree(SnowballFactory, params, zero)
   141  	tree.Add(one)
   142  
   143  	// Should do nothing
   144  	tree.Add(one)
   145  
   146  	expected := `SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [0, 255)
   147      SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 255`
   148  	require.Equal(expected, tree.String())
   149  	require.Equal(zero, tree.Preference())
   150  	require.False(tree.Finalized())
   151  
   152  	oneBag := bag.Of(one)
   153  	require.True(tree.RecordPoll(oneBag))
   154  	require.Equal(one, tree.Preference())
   155  	require.False(tree.Finalized())
   156  
   157  	expected = `SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [0, 255)
   158      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 255`
   159  	require.Equal(expected, tree.String())
   160  
   161  	require.True(tree.RecordPoll(oneBag))
   162  	require.Equal(one, tree.Preference())
   163  	require.True(tree.Finalized())
   164  
   165  	expected = "SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = [2], Finalized = true, SL(Preference = 1))) Bit = 255"
   166  	require.Equal(expected, tree.String())
   167  }
   168  
   169  func TestSnowballFirstBinary(t *testing.T) {
   170  	require := require.New(t)
   171  
   172  	zero := ids.Empty
   173  	one := ids.ID{0x01}
   174  
   175  	params := Parameters{
   176  		K:               1,
   177  		AlphaPreference: 1,
   178  		AlphaConfidence: 1,
   179  		Beta:            2,
   180  	}
   181  	tree := NewTree(SnowballFactory, params, zero)
   182  	tree.Add(one)
   183  
   184  	expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   185      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   186      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   187  	require.Equal(expected, tree.String())
   188  	require.Equal(zero, tree.Preference())
   189  	require.False(tree.Finalized())
   190  
   191  	oneBag := bag.Of(one)
   192  	require.True(tree.RecordPoll(oneBag))
   193  	require.Equal(one, tree.Preference())
   194  	require.False(tree.Finalized())
   195  
   196  	expected = `SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 0
   197      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   198      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [1, 256)`
   199  	require.Equal(expected, tree.String())
   200  
   201  	require.True(tree.RecordPoll(oneBag))
   202  	require.Equal(one, tree.Preference())
   203  	require.True(tree.Finalized())
   204  
   205  	expected = `SB(PreferenceStrength = 2, SF(Confidence = [2], Finalized = true)) Bits = [1, 256)`
   206  	require.Equal(expected, tree.String())
   207  }
   208  
   209  func TestSnowballAddDecidedFirstBit(t *testing.T) {
   210  	require := require.New(t)
   211  
   212  	zero := ids.Empty
   213  	c1000 := ids.ID{0x01}
   214  	c1100 := ids.ID{0x03}
   215  	c0110 := ids.ID{0x06}
   216  
   217  	params := Parameters{
   218  		K:               1,
   219  		AlphaPreference: 1,
   220  		AlphaConfidence: 1,
   221  		Beta:            2,
   222  	}
   223  	tree := NewTree(SnowballFactory, params, zero)
   224  	tree.Add(c1000)
   225  	tree.Add(c1100)
   226  
   227  	expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   228      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   229      SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 1
   230          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   231          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   232  	require.Equal(expected, tree.String())
   233  	require.Equal(zero, tree.Preference())
   234  	require.False(tree.Finalized())
   235  
   236  	oneBag := bag.Of(c1000)
   237  	require.True(tree.RecordPoll(oneBag))
   238  	require.Equal(c1000, tree.Preference())
   239  	require.False(tree.Finalized())
   240  
   241  	expected = `SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 0
   242      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   243      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   244          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   245          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   246  	require.Equal(expected, tree.String())
   247  
   248  	threeBag := bag.Of(c1100)
   249  	require.True(tree.RecordPoll(threeBag))
   250  	require.Equal(c1000, tree.Preference())
   251  	require.False(tree.Finalized())
   252  
   253  	expected = `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   254      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   255      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)`
   256  	require.Equal(expected, tree.String())
   257  
   258  	// Adding six should have no effect because the first bit is already decided
   259  	tree.Add(c0110)
   260  	require.Equal(expected, tree.String())
   261  }
   262  
   263  func TestSnowballAddPreviouslyRejected(t *testing.T) {
   264  	require := require.New(t)
   265  
   266  	zero := ids.ID{0b00000000}
   267  	one := ids.ID{0b00000001}
   268  	two := ids.ID{0b00000010}
   269  
   270  	params := Parameters{
   271  		K:               1,
   272  		AlphaPreference: 1,
   273  		AlphaConfidence: 1,
   274  		Beta:            2,
   275  	}
   276  	tree := NewTree(SnowballFactory, params, zero)
   277  	tree.Add(two)
   278  
   279  	{
   280  		expected := `SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [0, 1)
   281      SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 1
   282          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   283          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   284  		require.Equal(expected, tree.String())
   285  		require.Equal(zero, tree.Preference())
   286  		require.False(tree.Finalized())
   287  	}
   288  
   289  	zeroBag := bag.Of(zero)
   290  	require.True(tree.RecordPoll(zeroBag))
   291  
   292  	{
   293  		expected := `SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [0, 1)
   294      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   295          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   296          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   297  		require.Equal(expected, tree.String())
   298  		require.Equal(zero, tree.Preference())
   299  		require.False(tree.Finalized())
   300  	}
   301  
   302  	twoBag := bag.Of(two)
   303  	require.True(tree.RecordPoll(twoBag))
   304  
   305  	{
   306  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   307      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   308      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)`
   309  		require.Equal(expected, tree.String())
   310  		require.Equal(zero, tree.Preference())
   311  		require.False(tree.Finalized())
   312  	}
   313  
   314  	tree.Add(one)
   315  
   316  	{
   317  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   318      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   319      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)`
   320  		require.Equal(expected, tree.String())
   321  		require.Equal(zero, tree.Preference())
   322  		require.False(tree.Finalized())
   323  	}
   324  }
   325  
   326  func TestSnowballNewUnary(t *testing.T) {
   327  	require := require.New(t)
   328  
   329  	zero := ids.ID{0b00000000}
   330  	one := ids.ID{0b00000001}
   331  
   332  	params := Parameters{
   333  		K:               1,
   334  		AlphaPreference: 1,
   335  		AlphaConfidence: 1,
   336  		Beta:            3,
   337  	}
   338  	tree := NewTree(SnowballFactory, params, zero)
   339  	tree.Add(one)
   340  
   341  	{
   342  		expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   343      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   344      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   345  		require.Equal(expected, tree.String())
   346  		require.Equal(zero, tree.Preference())
   347  		require.False(tree.Finalized())
   348  	}
   349  
   350  	oneBag := bag.Of(one)
   351  	require.True(tree.RecordPoll(oneBag))
   352  
   353  	{
   354  		expected := `SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 0
   355      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   356      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [1, 256)`
   357  		require.Equal(expected, tree.String())
   358  		require.Equal(one, tree.Preference())
   359  		require.False(tree.Finalized())
   360  	}
   361  
   362  	require.True(tree.RecordPoll(oneBag))
   363  
   364  	{
   365  		expected := `SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = [2], Finalized = false, SL(Preference = 1))) Bit = 0
   366      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   367      SB(PreferenceStrength = 2, SF(Confidence = [2], Finalized = false)) Bits = [1, 256)`
   368  		require.Equal(expected, tree.String())
   369  		require.Equal(one, tree.Preference())
   370  		require.False(tree.Finalized())
   371  	}
   372  }
   373  
   374  func TestSnowballTransitiveReset(t *testing.T) {
   375  	require := require.New(t)
   376  
   377  	zero := ids.ID{0b00000000}
   378  	two := ids.ID{0b00000010}
   379  	eight := ids.ID{0b00001000}
   380  
   381  	params := Parameters{
   382  		K:               1,
   383  		AlphaPreference: 1,
   384  		AlphaConfidence: 1,
   385  		Beta:            2,
   386  	}
   387  	tree := NewTree(SnowballFactory, params, zero)
   388  	tree.Add(two)
   389  	tree.Add(eight)
   390  
   391  	{
   392  		expected := `SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [0, 1)
   393      SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 1
   394          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 3)
   395              SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 3
   396                  SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [4, 256)
   397                  SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [4, 256)
   398          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   399  		require.Equal(expected, tree.String())
   400  		require.Equal(zero, tree.Preference())
   401  		require.False(tree.Finalized())
   402  	}
   403  
   404  	zeroBag := bag.Of(zero)
   405  	require.True(tree.RecordPoll(zeroBag))
   406  
   407  	{
   408  		expected := `SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [0, 1)
   409      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   410          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 3)
   411              SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 3
   412                  SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [4, 256)
   413                  SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [4, 256)
   414          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   415  		require.Equal(expected, tree.String())
   416  		require.Equal(zero, tree.Preference())
   417  		require.False(tree.Finalized())
   418  	}
   419  
   420  	emptyBag := bag.Bag[ids.ID]{}
   421  	require.False(tree.RecordPoll(emptyBag))
   422  
   423  	{
   424  		expected := `SB(PreferenceStrength = 1, SF(Confidence = [0], Finalized = false)) Bits = [0, 1)
   425      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   426          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 3)
   427              SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 3
   428                  SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [4, 256)
   429                  SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [4, 256)
   430          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   431  		require.Equal(expected, tree.String())
   432  		require.Equal(zero, tree.Preference())
   433  		require.False(tree.Finalized())
   434  	}
   435  
   436  	require.True(tree.RecordPoll(zeroBag))
   437  
   438  	{
   439  		expected := `SB(PreferenceStrength = 2, SF(Confidence = [1], Finalized = false)) Bits = [0, 1)
   440      SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   441          SB(PreferenceStrength = 2, SF(Confidence = [1], Finalized = false)) Bits = [2, 3)
   442              SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 3
   443                  SB(PreferenceStrength = 2, SF(Confidence = [1], Finalized = false)) Bits = [4, 256)
   444                  SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [4, 256)
   445          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   446  		require.Equal(expected, tree.String())
   447  		require.Equal(zero, tree.Preference())
   448  		require.False(tree.Finalized())
   449  	}
   450  
   451  	require.True(tree.RecordPoll(zeroBag))
   452  
   453  	{
   454  		expected := "SB(PreferenceStrength = 3, SF(Confidence = [2], Finalized = true)) Bits = [4, 256)"
   455  		require.Equal(expected, tree.String())
   456  		require.Equal(zero, tree.Preference())
   457  		require.True(tree.Finalized())
   458  	}
   459  }
   460  
   461  func TestSnowballTrinary(t *testing.T) {
   462  	require := require.New(t)
   463  
   464  	params := Parameters{
   465  		K:               1,
   466  		AlphaPreference: 1,
   467  		AlphaConfidence: 1,
   468  		Beta:            2,
   469  	}
   470  	tree := NewTree(SnowballFactory, params, Green)
   471  	tree.Add(Red)
   472  	tree.Add(Blue)
   473  
   474  	//       *
   475  	//      / \
   476  	//     R   *
   477  	//        / \
   478  	//       G   B
   479  
   480  	require.Equal(Green, tree.Preference())
   481  	require.False(tree.Finalized())
   482  
   483  	redBag := bag.Of(Red)
   484  	require.True(tree.RecordPoll(redBag))
   485  	require.Equal(Red, tree.Preference())
   486  	require.False(tree.Finalized())
   487  
   488  	blueBag := bag.Of(Blue)
   489  	require.True(tree.RecordPoll(blueBag))
   490  	require.Equal(Red, tree.Preference())
   491  	require.False(tree.Finalized())
   492  
   493  	// Here is a case where voting for a color makes a different color become
   494  	// the preferred color. This is intended behavior.
   495  	greenBag := bag.Of(Green)
   496  	require.True(tree.RecordPoll(greenBag))
   497  	require.Equal(Blue, tree.Preference())
   498  	require.False(tree.Finalized())
   499  
   500  	// Red has already been rejected here, so this is not a successful poll.
   501  	require.False(tree.RecordPoll(redBag))
   502  	require.Equal(Blue, tree.Preference())
   503  	require.False(tree.Finalized())
   504  
   505  	require.True(tree.RecordPoll(greenBag))
   506  	require.Equal(Green, tree.Preference())
   507  	require.False(tree.Finalized())
   508  }
   509  
   510  func TestSnowballCloseTrinary(t *testing.T) {
   511  	require := require.New(t)
   512  
   513  	yellow := ids.ID{0x01}
   514  	cyan := ids.ID{0x02}
   515  	magenta := ids.ID{0x03}
   516  
   517  	params := Parameters{
   518  		K:               1,
   519  		AlphaPreference: 1,
   520  		AlphaConfidence: 1,
   521  		Beta:            2,
   522  	}
   523  	tree := NewTree(SnowballFactory, params, yellow)
   524  	tree.Add(cyan)
   525  	tree.Add(magenta)
   526  
   527  	//       *
   528  	//      / \
   529  	//     C   *
   530  	//        / \
   531  	//       Y   M
   532  
   533  	require.Equal(yellow, tree.Preference())
   534  	require.False(tree.Finalized())
   535  
   536  	yellowBag := bag.Of(yellow)
   537  	require.True(tree.RecordPoll(yellowBag))
   538  	require.Equal(yellow, tree.Preference())
   539  	require.False(tree.Finalized())
   540  
   541  	magentaBag := bag.Of(magenta)
   542  	require.True(tree.RecordPoll(magentaBag))
   543  	require.Equal(yellow, tree.Preference())
   544  	require.False(tree.Finalized())
   545  
   546  	// Cyan has already been rejected here, so these are not successful polls.
   547  	cyanBag := bag.Of(cyan)
   548  	require.False(tree.RecordPoll(cyanBag))
   549  	require.Equal(yellow, tree.Preference())
   550  	require.False(tree.Finalized())
   551  
   552  	require.False(tree.RecordPoll(cyanBag))
   553  	require.Equal(yellow, tree.Preference())
   554  	require.False(tree.Finalized())
   555  }
   556  
   557  func TestSnowballResetChild(t *testing.T) {
   558  	require := require.New(t)
   559  
   560  	c0000 := ids.ID{0x00} // 0000
   561  	c0100 := ids.ID{0x02} // 0100
   562  	c1000 := ids.ID{0x01} // 1000
   563  
   564  	params := Parameters{
   565  		K:               1,
   566  		AlphaPreference: 1,
   567  		AlphaConfidence: 1,
   568  		Beta:            2,
   569  	}
   570  	tree := NewTree(SnowballFactory, params, c0000)
   571  	tree.Add(c0100)
   572  	tree.Add(c1000)
   573  
   574  	require.Equal(c0000, tree.Preference())
   575  	require.False(tree.Finalized())
   576  
   577  	c0000Bag := bag.Of(c0000)
   578  	require.True(tree.RecordPoll(c0000Bag))
   579  
   580  	{
   581  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   582      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   583          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   584          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   585      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   586  		require.Equal(expected, tree.String())
   587  		require.Equal(c0000, tree.Preference())
   588  		require.False(tree.Finalized())
   589  	}
   590  
   591  	emptyBag := bag.Bag[ids.ID]{}
   592  	require.False(tree.RecordPoll(emptyBag))
   593  
   594  	{
   595  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   596      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   597          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   598          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   599      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   600  		require.Equal(expected, tree.String())
   601  		require.Equal(c0000, tree.Preference())
   602  		require.False(tree.Finalized())
   603  	}
   604  
   605  	require.True(tree.RecordPoll(c0000Bag))
   606  
   607  	{
   608  		expected := `SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   609      SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   610          SB(PreferenceStrength = 2, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   611          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   612      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   613  		require.Equal(expected, tree.String())
   614  		require.Equal(c0000, tree.Preference())
   615  		require.False(tree.Finalized())
   616  	}
   617  }
   618  
   619  func TestSnowballResetSibling(t *testing.T) {
   620  	require := require.New(t)
   621  
   622  	c0000 := ids.ID{0x00} // 0000
   623  	c0100 := ids.ID{0x02} // 0100
   624  	c1000 := ids.ID{0x01} // 1000
   625  
   626  	params := Parameters{
   627  		K:               1,
   628  		AlphaPreference: 1,
   629  		AlphaConfidence: 1,
   630  		Beta:            2,
   631  	}
   632  	tree := NewTree(SnowballFactory, params, c0000)
   633  	tree.Add(c0100)
   634  	tree.Add(c1000)
   635  
   636  	require.Equal(c0000, tree.Preference())
   637  	require.False(tree.Finalized())
   638  
   639  	c0100Bag := bag.Of(c0100)
   640  	require.True(tree.RecordPoll(c0100Bag))
   641  
   642  	{
   643  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   644      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   645          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   646          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   647      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   648  		require.Equal(expected, tree.String())
   649  		require.Equal(c0100, tree.Preference())
   650  		require.False(tree.Finalized())
   651  	}
   652  
   653  	c1000Bag := bag.Of(c1000)
   654  	require.True(tree.RecordPoll(c1000Bag))
   655  
   656  	{
   657  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 0
   658      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   659          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   660          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   661      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [1, 256)`
   662  		require.Equal(expected, tree.String())
   663  		require.Equal(c0100, tree.Preference())
   664  		require.False(tree.Finalized())
   665  	}
   666  
   667  	require.True(tree.RecordPoll(c0100Bag))
   668  
   669  	{
   670  		expected := `SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   671      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   672          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   673          SB(PreferenceStrength = 2, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)
   674      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [1, 256)`
   675  		require.Equal(expected, tree.String())
   676  		require.Equal(c0100, tree.Preference())
   677  		require.False(tree.Finalized())
   678  	}
   679  }
   680  
   681  func TestSnowball5Colors(t *testing.T) {
   682  	require := require.New(t)
   683  
   684  	numColors := 5
   685  	params := Parameters{
   686  		K:               5,
   687  		AlphaPreference: 5,
   688  		AlphaConfidence: 5,
   689  		Beta:            20,
   690  	}
   691  
   692  	colors := []ids.ID{}
   693  	for i := 0; i < numColors; i++ {
   694  		colors = append(colors, ids.Empty.Prefix(uint64(i)))
   695  	}
   696  
   697  	tree0 := NewTree(SnowballFactory, params, colors[4])
   698  
   699  	tree0.Add(colors[0])
   700  	tree0.Add(colors[1])
   701  	tree0.Add(colors[2])
   702  	tree0.Add(colors[3])
   703  
   704  	tree1 := NewTree(SnowballFactory, params, colors[3])
   705  
   706  	tree1.Add(colors[0])
   707  	tree1.Add(colors[1])
   708  	tree1.Add(colors[2])
   709  	tree1.Add(colors[4])
   710  
   711  	s1 := tree0.String()
   712  	s2 := tree1.String()
   713  	require.Equal(strings.Count(s1, "    "), strings.Count(s2, "    "))
   714  }
   715  
   716  func TestSnowballFineGrained(t *testing.T) {
   717  	require := require.New(t)
   718  
   719  	c0000 := ids.ID{0x00}
   720  	c1000 := ids.ID{0x01}
   721  	c1100 := ids.ID{0x03}
   722  	c0010 := ids.ID{0x04}
   723  
   724  	params := Parameters{
   725  		K:               1,
   726  		AlphaPreference: 1,
   727  		AlphaConfidence: 1,
   728  		Beta:            2,
   729  	}
   730  	tree := NewTree(SnowballFactory, params, c0000)
   731  
   732  	require.Equal(initialUnaryDescription, tree.String())
   733  	require.Equal(c0000, tree.Preference())
   734  	require.False(tree.Finalized())
   735  
   736  	tree.Add(c1100)
   737  
   738  	{
   739  		expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   740      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   741      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   742  		require.Equal(expected, tree.String())
   743  		require.Equal(c0000, tree.Preference())
   744  		require.False(tree.Finalized())
   745  	}
   746  
   747  	tree.Add(c1000)
   748  
   749  	{
   750  		expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   751      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   752      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 1))) Bit = 1
   753          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   754          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   755  		require.Equal(expected, tree.String())
   756  		require.Equal(c0000, tree.Preference())
   757  		require.False(tree.Finalized())
   758  	}
   759  
   760  	tree.Add(c0010)
   761  
   762  	{
   763  		expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   764      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 2)
   765          SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 2
   766              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   767              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   768      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 1))) Bit = 1
   769          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   770          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   771  		require.Equal(expected, tree.String())
   772  		require.Equal(c0000, tree.Preference())
   773  		require.False(tree.Finalized())
   774  	}
   775  
   776  	c0000Bag := bag.Of(c0000)
   777  	require.True(tree.RecordPoll(c0000Bag))
   778  
   779  	{
   780  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   781      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [1, 2)
   782          SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 2
   783              SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [3, 256)
   784              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   785      SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 1))) Bit = 1
   786          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   787          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)`
   788  		require.Equal(expected, tree.String())
   789  		require.Equal(c0000, tree.Preference())
   790  		require.False(tree.Finalized())
   791  	}
   792  
   793  	c0010Bag := bag.Of(c0010)
   794  	require.True(tree.RecordPoll(c0010Bag))
   795  
   796  	{
   797  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 2
   798      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [3, 256)
   799      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [3, 256)`
   800  		require.Equal(expected, tree.String())
   801  		require.Equal(c0000, tree.Preference())
   802  		require.False(tree.Finalized())
   803  	}
   804  
   805  	require.True(tree.RecordPoll(c0010Bag))
   806  	{
   807  		expected := "SB(PreferenceStrength = 2, SF(Confidence = [2], Finalized = true)) Bits = [3, 256)"
   808  		require.Equal(expected, tree.String())
   809  		require.Equal(c0010, tree.Preference())
   810  		require.True(tree.Finalized())
   811  	}
   812  }
   813  
   814  func TestSnowballDoubleAdd(t *testing.T) {
   815  	require := require.New(t)
   816  
   817  	params := Parameters{
   818  		K:               1,
   819  		AlphaPreference: 1,
   820  		AlphaConfidence: 1,
   821  		Beta:            3,
   822  	}
   823  	tree := NewTree(SnowballFactory, params, Red)
   824  	tree.Add(Red)
   825  
   826  	require.Equal(initialUnaryDescription, tree.String())
   827  	require.Equal(Red, tree.Preference())
   828  	require.False(tree.Finalized())
   829  }
   830  
   831  func TestSnowballConsistent(t *testing.T) {
   832  	require := require.New(t)
   833  
   834  	var (
   835  		numColors = 50
   836  		numNodes  = 100
   837  		params    = Parameters{
   838  			K:               20,
   839  			AlphaPreference: 15,
   840  			AlphaConfidence: 15,
   841  			Beta:            20,
   842  		}
   843  		seed   uint64 = 0
   844  		source        = prng.NewMT19937()
   845  	)
   846  
   847  	n := NewNetwork(SnowballFactory, params, numColors, source)
   848  
   849  	source.Seed(seed)
   850  	for i := 0; i < numNodes; i++ {
   851  		n.AddNode(NewTree)
   852  	}
   853  
   854  	for !n.Finalized() && !n.Disagreement() {
   855  		n.Round()
   856  	}
   857  
   858  	require.True(n.Agreement())
   859  }
   860  
   861  func TestSnowballFilterBinaryChildren(t *testing.T) {
   862  	require := require.New(t)
   863  
   864  	c0000 := ids.ID{0b00000000}
   865  	c1000 := ids.ID{0b00000001}
   866  	c0100 := ids.ID{0b00000010}
   867  	c0010 := ids.ID{0b00000100}
   868  
   869  	params := Parameters{
   870  		K:               1,
   871  		AlphaPreference: 1,
   872  		AlphaConfidence: 1,
   873  		Beta:            2,
   874  	}
   875  	tree := NewTree(SnowballFactory, params, c0000)
   876  
   877  	require.Equal(initialUnaryDescription, tree.String())
   878  	require.Equal(c0000, tree.Preference())
   879  	require.False(tree.Finalized())
   880  
   881  	tree.Add(c1000)
   882  
   883  	{
   884  		expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   885      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)
   886      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   887  		require.Equal(expected, tree.String())
   888  		require.Equal(c0000, tree.Preference())
   889  		require.False(tree.Finalized())
   890  	}
   891  
   892  	tree.Add(c0010)
   893  
   894  	{
   895  		expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 0
   896      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 2)
   897          SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = [0], Finalized = false, SL(Preference = 0))) Bit = 2
   898              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   899              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   900      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   901  		require.Equal(expected, tree.String())
   902  		require.Equal(c0000, tree.Preference())
   903  		require.False(tree.Finalized())
   904  	}
   905  
   906  	c0000Bag := bag.Of(c0000)
   907  	require.True(tree.RecordPoll(c0000Bag))
   908  
   909  	{
   910  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   911      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [1, 2)
   912          SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 2
   913              SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [3, 256)
   914              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   915      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   916  		require.Equal(expected, tree.String())
   917  		require.Equal(c0000, tree.Preference())
   918  		require.False(tree.Finalized())
   919  	}
   920  
   921  	tree.Add(c0100)
   922  
   923  	{
   924  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 0
   925      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 1
   926          SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 2
   927              SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [3, 256)
   928              SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   929          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [2, 256)
   930      SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [1, 256)`
   931  		require.Equal(expected, tree.String())
   932  		require.Equal(c0000, tree.Preference())
   933  		require.False(tree.Finalized())
   934  	}
   935  
   936  	c0100Bag := bag.Of(c0100)
   937  	require.True(tree.RecordPoll(c0100Bag))
   938  
   939  	{
   940  		expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = [1], Finalized = false, SL(Preference = 1))) Bit = 1
   941      SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = [1], Finalized = false, SL(Preference = 0))) Bit = 2
   942          SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [3, 256)
   943          SB(PreferenceStrength = 0, SF(Confidence = [0], Finalized = false)) Bits = [3, 256)
   944      SB(PreferenceStrength = 1, SF(Confidence = [1], Finalized = false)) Bits = [2, 256)`
   945  		require.Equal(expected, tree.String())
   946  		require.Equal(c0000, tree.Preference())
   947  		require.False(tree.Finalized())
   948  	}
   949  }
   950  
   951  func TestSnowballRecordPreferencePollBinary(t *testing.T) {
   952  	require := require.New(t)
   953  
   954  	params := Parameters{
   955  		K:               3,
   956  		AlphaPreference: 2,
   957  		AlphaConfidence: 3,
   958  		Beta:            2,
   959  	}
   960  	tree := NewTree(SnowballFactory, params, Red)
   961  	tree.Add(Blue)
   962  	require.Equal(Red, tree.Preference())
   963  	require.False(tree.Finalized())
   964  
   965  	threeBlue := bag.Of(Blue, Blue, Blue)
   966  	require.True(tree.RecordPoll(threeBlue))
   967  	require.Equal(Blue, tree.Preference())
   968  	require.False(tree.Finalized())
   969  
   970  	twoRed := bag.Of(Red, Red)
   971  	require.True(tree.RecordPoll(twoRed))
   972  	require.Equal(Blue, tree.Preference())
   973  	require.False(tree.Finalized())
   974  
   975  	threeRed := bag.Of(Red, Red, Red)
   976  	require.True(tree.RecordPoll(threeRed))
   977  	require.Equal(Red, tree.Preference())
   978  	require.False(tree.Finalized())
   979  
   980  	require.True(tree.RecordPoll(threeRed))
   981  	require.Equal(Red, tree.Preference())
   982  	require.True(tree.Finalized())
   983  }
   984  
   985  func TestSnowballRecordPreferencePollUnary(t *testing.T) {
   986  	require := require.New(t)
   987  
   988  	params := Parameters{
   989  		K:               3,
   990  		AlphaPreference: 2,
   991  		AlphaConfidence: 3,
   992  		Beta:            2,
   993  	}
   994  	tree := NewTree(SnowballFactory, params, Red)
   995  	require.Equal(Red, tree.Preference())
   996  	require.False(tree.Finalized())
   997  
   998  	twoRed := bag.Of(Red, Red)
   999  	require.True(tree.RecordPoll(twoRed))
  1000  	require.Equal(Red, tree.Preference())
  1001  	require.False(tree.Finalized())
  1002  
  1003  	tree.Add(Blue)
  1004  
  1005  	threeBlue := bag.Of(Blue, Blue, Blue)
  1006  	require.True(tree.RecordPoll(threeBlue))
  1007  	require.Equal(Red, tree.Preference())
  1008  	require.False(tree.Finalized())
  1009  
  1010  	require.True(tree.RecordPoll(threeBlue))
  1011  	require.Equal(Blue, tree.Preference())
  1012  	require.True(tree.Finalized())
  1013  }