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 }