EIP7549 get_attestation_indices (#5657)

* get attesting indices electra impl

* fmt

* get tests to pass

* fmt

* fix some beacon chain tests

* fmt

* fix slasher test

* fmt got me again

* fix more tests

* fix tests
This commit is contained in:
Eitan Seri-Levi
2024-05-08 09:32:44 -07:00
committed by GitHub
parent 2c2e44c4ed
commit 90179d4a88
33 changed files with 844 additions and 319 deletions

View File

@@ -2,7 +2,7 @@ use crate::attestation_storage::{AttestationRef, CompactIndexedAttestation};
use crate::max_cover::MaxCover;
use crate::reward_cache::RewardCache;
use state_processing::common::{
base, get_attestation_participation_flag_indices, get_attesting_indices,
attesting_indices_base::get_attesting_indices, base, get_attestation_participation_flag_indices,
};
use std::collections::HashMap;
use types::{

View File

@@ -28,7 +28,7 @@ pub struct CompactIndexedAttestation<E: EthSpec> {
#[superstruct(only(Base), partial_getter(rename = "aggregation_bits_base"))]
pub aggregation_bits: BitList<E::MaxValidatorsPerCommittee>,
#[superstruct(only(Electra), partial_getter(rename = "aggregation_bits_electra"))]
pub aggregation_bits: BitList<E::MaxValidatorsPerCommitteePerSlot>,
pub aggregation_bits: BitList<E::MaxValidatorsPerSlot>,
pub signature: AggregateSignature,
pub index: u64,
#[superstruct(only(Electra))]
@@ -81,8 +81,15 @@ impl<E: EthSpec> SplitAttestation<E> {
index: data.index,
})
}
// TODO(electra) implement electra variant
Attestation::Electra(_) => todo!(),
Attestation::Electra(attn) => {
CompactIndexedAttestation::Electra(CompactIndexedAttestationElectra {
attesting_indices,
aggregation_bits: attn.aggregation_bits,
signature: attestation.signature().clone(),
index: data.index,
committee_bits: attn.committee_bits,
})
}
};
Self {
@@ -157,9 +164,10 @@ impl<E: EthSpec> CompactIndexedAttestation<E> {
(CompactIndexedAttestation::Base(this), CompactIndexedAttestation::Base(other)) => {
this.signers_disjoint_from(other)
}
(CompactIndexedAttestation::Electra(_), CompactIndexedAttestation::Electra(_)) => {
todo!()
}
(
CompactIndexedAttestation::Electra(this),
CompactIndexedAttestation::Electra(other),
) => this.signers_disjoint_from(other),
// TODO(electra) is a mix of electra and base compact indexed attestations an edge case we need to deal with?
_ => false,
}
@@ -170,9 +178,10 @@ impl<E: EthSpec> CompactIndexedAttestation<E> {
(CompactIndexedAttestation::Base(this), CompactIndexedAttestation::Base(other)) => {
this.aggregate(other)
}
(CompactIndexedAttestation::Electra(_), CompactIndexedAttestation::Electra(_)) => {
todo!()
}
(
CompactIndexedAttestation::Electra(this),
CompactIndexedAttestation::Electra(other),
) => this.aggregate(other),
// TODO(electra) is a mix of electra and base compact indexed attestations an edge case we need to deal with?
_ => (),
}
@@ -198,13 +207,34 @@ impl<E: EthSpec> CompactIndexedAttestationBase<E> {
}
}
impl<E: EthSpec> CompactIndexedAttestationElectra<E> {
// TODO(electra) update to match spec requirements
pub fn signers_disjoint_from(&self, other: &Self) -> bool {
self.aggregation_bits
.intersection(&other.aggregation_bits)
.is_zero()
}
// TODO(electra) update to match spec requirements
pub fn aggregate(&mut self, other: &Self) {
self.attesting_indices = self
.attesting_indices
.drain(..)
.merge(other.attesting_indices.iter().copied())
.dedup()
.collect();
self.aggregation_bits = self.aggregation_bits.union(&other.aggregation_bits);
self.signature.add_assign_aggregate(&other.signature);
}
}
impl<E: EthSpec> AttestationMap<E> {
pub fn insert(&mut self, attestation: Attestation<E>, attesting_indices: Vec<u64>) {
let SplitAttestation {
checkpoint,
data,
indexed,
} = SplitAttestation::new(attestation, attesting_indices);
} = SplitAttestation::new(attestation.clone(), attesting_indices);
let attestation_map = self.checkpoint_map.entry(checkpoint).or_default();
let attestations = attestation_map.attestations.entry(data).or_default();
@@ -213,14 +243,23 @@ impl<E: EthSpec> AttestationMap<E> {
// NOTE: this is sub-optimal and in future we will remove this in favour of max-clique
// aggregation.
let mut aggregated = false;
for existing_attestation in attestations.iter_mut() {
if existing_attestation.signers_disjoint_from(&indexed) {
existing_attestation.aggregate(&indexed);
aggregated = true;
} else if *existing_attestation == indexed {
aggregated = true;
match attestation {
Attestation::Base(_) => {
for existing_attestation in attestations.iter_mut() {
if existing_attestation.signers_disjoint_from(&indexed) {
existing_attestation.aggregate(&indexed);
aggregated = true;
} else if *existing_attestation == indexed {
aggregated = true;
}
}
}
}
// TODO(electra) in order to be devnet ready, we can skip
// aggregating here for now. this will result in "poorly"
// constructed blocks, but that should be fine for devnet
Attestation::Electra(_) => (),
};
if !aggregated {
attestations.push(indexed);