Electra - Filter aggregated attestations by root/committee (#6594)

* Filter aggregated attestations by root/committee

* fixed validator api documentation link

---------

Co-authored-by: Pedro Miranda <pedro.miranda@nimbus.team>
This commit is contained in:
Pedro Miranda 2024-10-04 06:15:48 +01:00 committed by GitHub
parent eb30b741d9
commit ff0cc8e62e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 24 deletions

View File

@ -1045,23 +1045,23 @@ func getElectraAggregatedAttestation*(
attestationDataRoot: Eth2Digest, committeeIndex: CommitteeIndex):
Opt[electra.Attestation] =
let candidateIdx = pool.candidateIdx(slot)
let
candidateIdx = pool.candidateIdx(slot)
if candidateIdx.isNone:
return Opt.none(electra.Attestation)
var res: Opt[electra.Attestation]
for _, entry in pool.electraCandidates[candidateIdx.get].mpairs():
if entry.data.index != committeeIndex.distinctBase:
continue
pool.electraCandidates[candidateIdx.get].withValue(
attestationDataRoot, entry):
entry.updateAggregates()
if entry.data.index == committeeIndex.distinctBase:
entry[].updateAggregates()
let (bestIndex, best) = bestValidation(entry.aggregates)
let (bestIndex, _) = bestValidation(entry[].aggregates)
if res.isNone() or best > res.get().aggregation_bits.countOnes():
res = Opt.some(entry.toElectraAttestation(entry.aggregates[bestIndex]))
# Found the right hash, no need to look further
return Opt.some(entry[].toElectraAttestation(entry[].aggregates[bestIndex]))
res
Opt.none(electra.Attestation)
func getAggregatedAttestation*(
pool: var AttestationPool, slot: Slot, attestation_data_root: Eth2Digest):

View File

@ -804,7 +804,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
res.get()
RestApiResponse.jsonResponse(attestation)
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getPoolAttestationsV2
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Validator/getAggregatedAttestationV2
router.api2(MethodGet, "/eth/v2/validator/aggregate_attestation") do (
attestation_data_root: Option[Eth2Digest],
committee_index: Option[CommitteeIndex],

View File

@ -850,7 +850,7 @@ suite "Attestation pool electra processing" & preset():
# We should now get both attestations for the block, but the aggregate
# should be the one with the most votes
pool[].getElectraAttestationsForBlock(state[], cache).len() == 2
pool[].getElectraAggregatedAttestation(2.Slot, combined[0].data.beacon_block_root,
pool[].getElectraAggregatedAttestation(2.Slot, hash_tree_root(combined[0].data),
0.CommitteeIndex).get().aggregation_bits.countOnes() == 2
pool[].getElectraAggregatedAttestation(2.Slot, hash_tree_root(att2.data), 0.CommitteeIndex).
get().aggregation_bits.countOnes() == 2
@ -858,12 +858,6 @@ suite "Attestation pool electra processing" & preset():
pool[].getElectraAggregatedAttestation(
2.Slot, combined[0].data.beacon_block_root, 1.CommitteeIndex).isNone()
let
# Someone votes for a different root
att4 = makeElectraAttestation(state[], ZERO_HASH, bc1[2], cache)
pool[].addAttestation(
att4, @[bc1[2]], att3.loadSig, att3.data.slot.start_beacon_time)
test "Attestations with disjoint comittee bits and equal data into single on-chain aggregate" & preset():
let
@ -915,7 +909,7 @@ suite "Attestation pool electra processing" & preset():
bc1 = get_beacon_committee(
state[], getStateField(state[], slot), 1.CommitteeIndex, cache)
# atestation from first committee
# attestation from first committee
attestation_1 = makeElectraAttestation(
state[], state[].latest_block_root, bc0[0], cache)
@ -923,8 +917,8 @@ suite "Attestation pool electra processing" & preset():
attestation_2 = makeElectraAttestation(
state[], state[].latest_block_root, bc0[1], cache)
# atestation from different committee with same data as
# attestaton 1
# attestation from different committee with same data as
# attestation 1
attestation_3 = makeElectraAttestation(
state[], state[].latest_block_root, bc1[1], cache)
@ -995,7 +989,7 @@ suite "Attestation pool electra processing" & preset():
pool[].getElectraAttestationsForBlock(state[], cache).len() == 1
# Can get either aggregate here, random!
pool[].getElectraAggregatedAttestation(
1.Slot, att0.data.beacon_block_root, 0.CommitteeIndex).isSome()
1.Slot, hash_tree_root(att0.data), 0.CommitteeIndex).isSome()
# Add in attestation 3 - both aggregates should now have it added
pool[].addAttestation(
@ -1008,7 +1002,7 @@ suite "Attestation pool electra processing" & preset():
attestations[0].aggregation_bits.countOnes() == 6
# Can get either aggregate here, random!
pool[].getElectraAggregatedAttestation(
1.Slot, attestations[0].data.beacon_block_root, 0.CommitteeIndex).isSome()
1.Slot, hash_tree_root(attestations[0].data), 0.CommitteeIndex).isSome()
# Add in attestation 0 as single - attestation 1 is now a superset of the
# aggregates in the pool, so everything else should be removed
@ -1021,4 +1015,15 @@ suite "Attestation pool electra processing" & preset():
attestations.len() == 1
attestations[0].aggregation_bits.countOnes() == 4
pool[].getElectraAggregatedAttestation(
1.Slot, attestations[0].data.beacon_block_root, 0.CommitteeIndex).isSome()
1.Slot, hash_tree_root(attestations[0].data), 0.CommitteeIndex).isSome()
# Someone votes for a different root
let
att4 = makeElectraAttestation(state[], ZERO_HASH, bc0[4], cache)
pool[].addAttestation(
att4, @[bc0[4]], att4.loadSig, att4.data.slot.start_beacon_time)
# Total aggregations size should be one for that root
check:
pool[].getElectraAggregatedAttestation(1.Slot, hash_tree_root(att4.data),
0.CommitteeIndex).get().aggregation_bits.countOnes() == 1