Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Committee-aware attestation packing #14245

Merged
merged 8 commits into from
Aug 2, 2024
Merged

Committee-aware attestation packing #14245

merged 8 commits into from
Aug 2, 2024

Conversation

rkapka
Copy link
Contributor

@rkapka rkapka commented Jul 19, 2024

Max-Cover is executed on all attestations for a slot bundled together, without considering committees. This is very bad because an attestation for committee C0 with bits 11111110 and an attestation for committee C1 with the same bits will be treated as equal, meaning that Max-Cover will treat the attestation for C1 as not improving coverage, even though it's an entirely distinct set of votes. As a result it will most likely place this attestation after an attestation with bits 00000001 (for whatever committee).

If the number of attestations in the block is less then MAX_ATTESTATIONS, then this a non-issue because all attestations will get into the block anyway. But for blocks that hit the maximum number of attestations, which is 128, the packing can be made more optimal.

The new algorithm:

// sort attestations as follows:
//
// - all attestations selected by max-cover are ordered before leftover attestations
// - within selected/leftover, attestations are ordered by slot, with higher slot coming first
// - within a slot, all top attestations (one per committee) are ordered before any second-best attestations, second-best before third-best etc.
// - within top/second-best/etc. attestations (one per committee), attestations are ordered by bit count, with higher bit count coming first

The new algorithm is hidden behind a feature flag called EnableCommitteeAwarePacking (although it does more than dividing attestations into committees)

@rkapka rkapka changed the title initial algorithm Committee-aware attestation packing Jul 19, 2024
@rkapka rkapka marked this pull request as ready for review July 22, 2024 15:55
@rkapka rkapka requested a review from a team as a code owner July 22, 2024 15:55
@rkapka rkapka added the Ready For Review A pull request ready for code review label Jul 23, 2024
if err != nil {
return nil, err
var sorted proposerAtts
if features.Get().EnableCommitteeAwarePacking {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move this logic withing the sort() method?

sa.selected = make(map[primitives.CommitteeIndex]proposerAtts)
sa.leftover = make(map[primitives.CommitteeIndex]proposerAtts)
for ci, committeeAtts := range sa.candidates {
sa.selected[ci], sa.leftover[ci], err = committeeAtts.sortByProfitabilityUsingMaxCover_committeeAwarePacking()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test where we check for leftovers? I think that with the parameters passed to MaxCover the leftover map will always be empty unless there are contained aggregation bits, in which case anyway we would drop them. I suspect that with these parameters you can simply ignore the leftovers from MaxCover and just consider the selected ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atts := getAtts([]testData{
			{4, bitfield.Bitlist{0b00000001, 0b1}},
			{4, bitfield.Bitlist{0b11100001, 0b1}},
			{1, bitfield.Bitlist{0b11000000, 0b1}},
			{2, bitfield.Bitlist{0b11100000, 0b1}},
			{4, bitfield.Bitlist{0b10000011, 0b1}},
			{4, bitfield.Bitlist{0b11111000, 0b1}},
			{1, bitfield.Bitlist{0b11100000, 0b1}},
			{3, bitfield.Bitlist{0b11000000, 0b1}},
		})
		want := getAtts([]testData{
			{4, bitfield.Bitlist{0b11111000, 0b1}},
			{4, bitfield.Bitlist{0b10000011, 0b1}},
			{3, bitfield.Bitlist{0b11000000, 0b1}},
			{2, bitfield.Bitlist{0b11100000, 0b1}},
			{1, bitfield.Bitlist{0b11100000, 0b1}},
			{4, bitfield.Bitlist{0b11100001, 0b1}},
			{4, bitfield.Bitlist{0b00000001, 0b1}},
			{1, bitfield.Bitlist{0b11000000, 0b1}},
		})

This is an example of a test where we check that left over aggregates are sorted last. I agree that in all such tests each leftover atts has bits that are already covered.

potuz
potuz previously approved these changes Aug 1, 2024
Copy link
Contributor

@potuz potuz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rkapka rkapka added this pull request to the merge queue Aug 2, 2024
Merged via the queue into develop with commit 13e09c5 Aug 2, 2024
16 of 17 checks passed
@rkapka rkapka deleted the att-packing-committee branch August 2, 2024 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Ready For Review A pull request ready for code review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants