Ensure duplicated attestations are only counted as 1 in block proposal.

This commit is contained in:
Jim McDonald 2020-10-04 12:28:44 +01:00
parent e19fae7b4e
commit eb5c919344
No known key found for this signature in database
GPG Key ID: 89CEB61B2AD2A5E7
3 changed files with 60 additions and 5 deletions

View File

@ -1,4 +1,5 @@
Development
- ensure duplicated attestations are only counted as 1 in block proposal score
- ensure genesis attesters are scheduled appropriately
- do not continue if attempt to acquire a semaphore fails
- fetch validators without balances, for (much) faster response from Prysm

View File

@ -33,12 +33,35 @@ func scoreBeaconBlockProposal(ctx context.Context, name string, blockProposal *s
immediateAttestationScore := float64(0)
attestationScore := float64(0)
// Add attestation scores.
// We need to avoid duplicates in attestations.
// Map is slot -> committee index -> validator committee index -> attested.
attested := make(map[uint64]map[uint64]map[uint64]bool)
for _, attestation := range blockProposal.Body.Attestations {
inclusionDistance := float64(blockProposal.Slot - attestation.Data.Slot)
attestationScore += float64(attestation.AggregationBits.Count()) * (float64(0.75) + float64(0.25)/inclusionDistance)
if inclusionDistance == 1 {
immediateAttestationScore += float64(attestation.AggregationBits.Count()) * (float64(0.75) + float64(0.25)/inclusionDistance)
slotAttested, exists := attested[attestation.Data.Slot]
if !exists {
slotAttested = make(map[uint64]map[uint64]bool)
attested[attestation.Data.Slot] = slotAttested
}
committeeAttested, exists := slotAttested[attestation.Data.Index]
if !exists {
committeeAttested = make(map[uint64]bool)
slotAttested[attestation.Data.Index] = committeeAttested
}
for i := uint64(0); i < attestation.AggregationBits.Len(); i++ {
if attestation.AggregationBits.BitAt(i) {
committeeAttested[i] = true
}
}
}
// Calculate inclusion score.
for slot, slotAttested := range attested {
inclusionDistance := float64(blockProposal.Slot - slot)
for _, committeeAttested := range slotAttested {
attestationScore += float64(len(committeeAttested)) * (float64(0.75) + float64(0.25)/inclusionDistance)
if inclusionDistance == 1 {
immediateAttestationScore += float64(len(committeeAttested)) * (float64(0.75) + float64(0.25)/inclusionDistance)
}
}
}

View File

@ -30,6 +30,14 @@ func aggregationBits(set uint64, total uint64) bitfield.Bitlist {
return bits
}
func specificAggregationBits(set []uint64, total uint64) bitfield.Bitlist {
bits := bitfield.NewBitlist(total)
for _, pos := range set {
bits.SetBitAt(pos, true)
}
return bits
}
func TestScore(t *testing.T) {
tests := []struct {
name string
@ -130,6 +138,29 @@ func TestScore(t *testing.T) {
},
score: 1450,
},
{
name: "DuplicateAttestations",
block: &spec.BeaconBlock{
Slot: 12345,
Body: &spec.BeaconBlockBody{
Attestations: []*spec.Attestation{
{
AggregationBits: specificAggregationBits([]uint64{1, 2, 3}, 128),
Data: &spec.AttestationData{
Slot: 12344,
},
},
{
AggregationBits: specificAggregationBits([]uint64{2, 3, 4}, 128),
Data: &spec.AttestationData{
Slot: 12344,
},
},
},
},
},
score: 4,
},
}
for _, test := range tests {