github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_sync_aggregate_test.go (about)

     1  package validator
     2  
     3  import (
     4  	"bytes"
     5  	"sort"
     6  	"testing"
     7  
     8  	"github.com/prysmaticlabs/go-bitfield"
     9  	v2 "github.com/prysmaticlabs/prysm/proto/prysm/v2"
    10  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    11  )
    12  
    13  func TestProposerSyncContributions_FilterByBlockRoot(t *testing.T) {
    14  	rootA := [32]byte{'a'}
    15  	rootB := [32]byte{'b'}
    16  	tests := []struct {
    17  		name string
    18  		cs   proposerSyncContributions
    19  		want proposerSyncContributions
    20  	}{
    21  		{
    22  			name: "empty list",
    23  			cs:   proposerSyncContributions{},
    24  			want: proposerSyncContributions{},
    25  		},
    26  		{
    27  			name: "single item, not found",
    28  			cs: proposerSyncContributions{
    29  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.NewBitvector128()},
    30  			},
    31  			want: proposerSyncContributions{},
    32  		},
    33  		{
    34  			name: "single item with filter, found",
    35  			cs: proposerSyncContributions{
    36  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], Slot: 0},
    37  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], Slot: 1},
    38  			},
    39  			want: proposerSyncContributions{
    40  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:]},
    41  			},
    42  		},
    43  		{
    44  			name: "multiple items with filter, found",
    45  			cs: proposerSyncContributions{
    46  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], Slot: 0},
    47  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], Slot: 1},
    48  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], Slot: 2},
    49  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], Slot: 3},
    50  			},
    51  			want: proposerSyncContributions{
    52  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], Slot: 0},
    53  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], Slot: 2},
    54  			},
    55  		},
    56  	}
    57  	for _, tt := range tests {
    58  		t.Run(tt.name, func(t *testing.T) {
    59  			cs := tt.cs.filterByBlockRoot(rootA)
    60  			assert.DeepEqual(t, tt.want, cs)
    61  		})
    62  	}
    63  }
    64  
    65  func TestProposerSyncContributions_FilterBySubcommitteeID(t *testing.T) {
    66  	rootA := [32]byte{'a'}
    67  	rootB := [32]byte{'b'}
    68  	tests := []struct {
    69  		name string
    70  		cs   proposerSyncContributions
    71  		want proposerSyncContributions
    72  	}{
    73  		{
    74  			name: "empty list",
    75  			cs:   proposerSyncContributions{},
    76  			want: proposerSyncContributions{},
    77  		},
    78  		{
    79  			name: "single item, not found",
    80  			cs: proposerSyncContributions{
    81  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.NewBitvector128(), SubcommitteeIndex: 1},
    82  			},
    83  			want: proposerSyncContributions{},
    84  		},
    85  		{
    86  			name: "single item with filter",
    87  			cs: proposerSyncContributions{
    88  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], SubcommitteeIndex: 0},
    89  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], SubcommitteeIndex: 1},
    90  			},
    91  			want: proposerSyncContributions{
    92  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:]},
    93  			},
    94  		},
    95  		{
    96  			name: "multiple items with filter",
    97  			cs: proposerSyncContributions{
    98  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], SubcommitteeIndex: 0},
    99  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], SubcommitteeIndex: 1},
   100  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], SubcommitteeIndex: 0},
   101  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], SubcommitteeIndex: 2},
   102  			},
   103  			want: proposerSyncContributions{
   104  				&v2.SyncCommitteeContribution{BlockRoot: rootA[:], SubcommitteeIndex: 0},
   105  				&v2.SyncCommitteeContribution{BlockRoot: rootB[:], SubcommitteeIndex: 0},
   106  			},
   107  		},
   108  	}
   109  	for _, tt := range tests {
   110  		t.Run(tt.name, func(t *testing.T) {
   111  			cs := tt.cs.filterBySubIndex(0)
   112  			assert.DeepEqual(t, tt.want, cs)
   113  		})
   114  	}
   115  }
   116  
   117  func TestProposerSyncContributions_Dedup(t *testing.T) {
   118  	tests := []struct {
   119  		name string
   120  		cs   proposerSyncContributions
   121  		want proposerSyncContributions
   122  	}{
   123  		{
   124  			name: "nil list",
   125  			cs:   nil,
   126  			want: proposerSyncContributions(nil),
   127  		},
   128  		{
   129  			name: "empty list",
   130  			cs:   proposerSyncContributions{},
   131  			want: proposerSyncContributions{},
   132  		},
   133  		{
   134  			name: "single item",
   135  			cs: proposerSyncContributions{
   136  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.NewBitvector128()},
   137  			},
   138  			want: proposerSyncContributions{
   139  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.NewBitvector128()},
   140  			},
   141  		},
   142  		{
   143  			name: "two items no duplicates",
   144  			cs: proposerSyncContributions{
   145  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10111110, 0x01}},
   146  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01111111, 0x01}},
   147  			},
   148  			want: proposerSyncContributions{
   149  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01111111, 0x01}},
   150  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10111110, 0x01}},
   151  			},
   152  		},
   153  		{
   154  			name: "two items with duplicates",
   155  			cs: proposerSyncContributions{
   156  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0xba, 0x01}},
   157  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0xba, 0x01}},
   158  			},
   159  			want: proposerSyncContributions{
   160  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0xba, 0x01}},
   161  			},
   162  		},
   163  		{
   164  			name: "sorted no duplicates",
   165  			cs: proposerSyncContributions{
   166  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   167  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   168  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00101011, 0b1}},
   169  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100000, 0b1}},
   170  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00010000, 0b1}},
   171  			},
   172  			want: proposerSyncContributions{
   173  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   174  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   175  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00101011, 0b1}},
   176  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100000, 0b1}},
   177  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00010000, 0b1}},
   178  			},
   179  		},
   180  		{
   181  			name: "sorted with duplicates",
   182  			cs: proposerSyncContributions{
   183  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   184  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   185  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   186  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   187  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   188  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   189  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   190  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   191  			},
   192  			want: proposerSyncContributions{
   193  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   194  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   195  			},
   196  		},
   197  		{
   198  			name: "all equal",
   199  			cs: proposerSyncContributions{
   200  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   201  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   202  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   203  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   204  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   205  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   206  			},
   207  			want: proposerSyncContributions{
   208  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   209  			},
   210  		},
   211  		{
   212  			name: "unsorted no duplicates",
   213  			cs: proposerSyncContributions{
   214  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   215  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00100010, 0b1}},
   216  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100101, 0b1}},
   217  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00010000, 0b1}},
   218  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   219  			},
   220  			want: proposerSyncContributions{
   221  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   222  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   223  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100101, 0b1}},
   224  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00100010, 0b1}},
   225  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00010000, 0b1}},
   226  			},
   227  		},
   228  		{
   229  			name: "unsorted with duplicates",
   230  			cs: proposerSyncContributions{
   231  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   232  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   233  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100101, 0b1}},
   234  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100101, 0b1}},
   235  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   236  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   237  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   238  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   239  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   240  			},
   241  			want: proposerSyncContributions{
   242  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   243  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   244  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10100101, 0b1}},
   245  			},
   246  		},
   247  		{
   248  			name: "no proper subset (same root)",
   249  			cs: proposerSyncContributions{
   250  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000101, 0b1}},
   251  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   252  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10000001, 0b1}},
   253  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00011001, 0b1}},
   254  			},
   255  			want: proposerSyncContributions{
   256  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00011001, 0b1}},
   257  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   258  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000101, 0b1}},
   259  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10000001, 0b1}},
   260  			},
   261  		},
   262  		{
   263  			name: "proper subset (same root)",
   264  			cs: proposerSyncContributions{
   265  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   266  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   267  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   268  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   269  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   270  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   271  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   272  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   273  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   274  			},
   275  			want: proposerSyncContributions{
   276  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   277  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   278  			},
   279  		},
   280  		{
   281  			name: "no proper subset (different index)",
   282  			cs: proposerSyncContributions{
   283  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000101, 0b1}},
   284  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   285  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b10000001, 0b1}},
   286  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00011001, 0b1}},
   287  			},
   288  			want: proposerSyncContributions{
   289  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00011001, 0b1}},
   290  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b10000001, 0b1}},
   291  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   292  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000101, 0b1}},
   293  			},
   294  		},
   295  		{
   296  			name: "proper subset (different index 1)",
   297  			cs: proposerSyncContributions{
   298  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   299  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   300  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   301  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   302  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   303  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00000011, 0b1}},
   304  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   305  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00000001, 0b1}},
   306  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   307  			},
   308  			want: proposerSyncContributions{
   309  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   310  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01101101, 0b1}},
   311  			},
   312  		},
   313  		{
   314  			name: "proper subset (different index 2)",
   315  			cs: proposerSyncContributions{
   316  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   317  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   318  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b00001111, 0b1}},
   319  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   320  			},
   321  			want: proposerSyncContributions{
   322  				&v2.SyncCommitteeContribution{SubcommitteeIndex: 1, AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   323  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b11001111, 0b1}},
   324  			},
   325  		},
   326  	}
   327  	for _, tt := range tests {
   328  		t.Run(tt.name, func(t *testing.T) {
   329  			cs, err := tt.cs.dedup()
   330  			if err != nil {
   331  				t.Error(err)
   332  			}
   333  			sort.Slice(cs, func(i, j int) bool {
   334  				if cs[i].AggregationBits.Count() == cs[j].AggregationBits.Count() {
   335  					if cs[i].SubcommitteeIndex == cs[j].SubcommitteeIndex {
   336  						return bytes.Compare(cs[i].AggregationBits, cs[j].AggregationBits) <= 0
   337  					}
   338  					return cs[i].SubcommitteeIndex > cs[j].SubcommitteeIndex
   339  				}
   340  				return cs[i].AggregationBits.Count() > cs[j].AggregationBits.Count()
   341  			})
   342  			assert.DeepEqual(t, tt.want, cs)
   343  		})
   344  	}
   345  }
   346  
   347  func TestProposerSyncContributions_MostProfitable(t *testing.T) {
   348  	tests := []struct {
   349  		name string
   350  		cs   proposerSyncContributions
   351  		want *v2.SyncCommitteeContribution
   352  	}{
   353  		{
   354  			name: "Same item",
   355  			cs: proposerSyncContributions{
   356  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01}},
   357  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01}},
   358  			},
   359  			want: &v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01}},
   360  		},
   361  		{
   362  			name: "Same item again",
   363  			cs: proposerSyncContributions{
   364  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01}},
   365  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b10}},
   366  			},
   367  			want: &v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b01}},
   368  		},
   369  		{
   370  			name: "most profitable at the start",
   371  			cs: proposerSyncContributions{
   372  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b0101}},
   373  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b0100}},
   374  			},
   375  			want: &v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b0101}},
   376  		},
   377  		{
   378  			name: "most profitable at the end",
   379  			cs: proposerSyncContributions{
   380  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b0101}},
   381  				&v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b0111}},
   382  			},
   383  			want: &v2.SyncCommitteeContribution{AggregationBits: bitfield.Bitvector128{0b0111}},
   384  		},
   385  	}
   386  	for _, tt := range tests {
   387  		t.Run(tt.name, func(t *testing.T) {
   388  			cs := tt.cs.mostProfitable()
   389  			assert.DeepEqual(t, tt.want, cs)
   390  		})
   391  	}
   392  }