Merge branch 'electra_attestation_changes' of https://github.com/sigp/lighthouse into block-processing-electra

This commit is contained in:
realbigsean
2024-05-08 12:48:09 -04:00
33 changed files with 844 additions and 317 deletions

View File

@@ -1,4 +1,4 @@
use super::{Attestation, AttestationBase, AttestationElectra, AttestationRef};
use super::{AttestationBase, AttestationElectra, AttestationRef};
use super::{
ChainSpec, Domain, EthSpec, Fork, Hash256, PublicKey, SecretKey, SelectionProof, Signature,
SignedRoot,
@@ -81,7 +81,7 @@ impl<E: EthSpec> AggregateAndProof<E> {
/// If `selection_proof.is_none()` it will be computed locally.
pub fn from_aggregate(
aggregator_index: u64,
aggregate: Attestation<E>,
aggregate: AttestationRef<'_, E>,
selection_proof: Option<SelectionProof>,
secret_key: &SecretKey,
fork: &Fork,
@@ -101,14 +101,14 @@ impl<E: EthSpec> AggregateAndProof<E> {
.into();
match aggregate {
Attestation::Base(attestation) => Self::Base(AggregateAndProofBase {
AttestationRef::Base(attestation) => Self::Base(AggregateAndProofBase {
aggregator_index,
aggregate: attestation,
aggregate: attestation.clone(),
selection_proof,
}),
Attestation::Electra(attestation) => Self::Electra(AggregateAndProofElectra {
AttestationRef::Electra(attestation) => Self::Electra(AggregateAndProofElectra {
aggregator_index,
aggregate: attestation,
aggregate: attestation.clone(),
selection_proof,
}),
}

View File

@@ -65,7 +65,7 @@ pub struct Attestation<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 data: AttestationData,
pub signature: AggregateSignature,
#[superstruct(only(Electra))]
@@ -236,6 +236,13 @@ impl<'a, E: EthSpec> AttestationRef<'a, E> {
Self::Electra(att) => att.aggregation_bits.num_set_bits(),
}
}
pub fn committee_index(&self) -> u64 {
match self {
AttestationRef::Base(att) => att.data.index,
AttestationRef::Electra(att) => att.committee_index(),
}
}
}
impl<E: EthSpec> AttestationElectra<E> {
@@ -330,7 +337,6 @@ impl<E: EthSpec> AttestationBase<E> {
pub fn aggregate(&mut self, other: &Self) {
debug_assert_eq!(self.data, other.data);
debug_assert!(self.signers_disjoint_from(other));
self.aggregation_bits = self.aggregation_bits.union(&other.aggregation_bits);
self.signature.add_assign_aggregate(&other.signature);
}
@@ -381,6 +387,18 @@ impl<E: EthSpec> AttestationBase<E> {
Ok(())
}
}
pub fn extend_aggregation_bits(
&self,
) -> Result<BitList<E::MaxValidatorsPerSlot>, ssz_types::Error> {
let mut extended_aggregation_bits: BitList<E::MaxValidatorsPerSlot> =
BitList::with_capacity(self.aggregation_bits.len())?;
for (i, bit) in self.aggregation_bits.iter().enumerate() {
extended_aggregation_bits.set(i, bit)?;
}
Ok(extended_aggregation_bits)
}
}
impl<E: EthSpec> SlotData for Attestation<E> {
@@ -419,6 +437,9 @@ mod tests {
assert_eq!(signature, 288 + 16);
let attestation_expected = aggregation_bits + attestation_data + signature;
// TODO(electra) since we've removed attestation aggregation for electra variant
// i've updated the attestation value expected from 488 544
// assert_eq!(attestation_expected, 488);
assert_eq!(attestation_expected, 488);
assert_eq!(
size_of::<Attestation<MainnetEthSpec>>(),

View File

@@ -608,12 +608,8 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockElectra<E, Payload>
let base_block: BeaconBlockBase<_, Payload> = BeaconBlockBase::full(spec);
// TODO(electra): check this
let indexed_attestation: IndexedAttestationElectra<E> = IndexedAttestationElectra {
attesting_indices: VariableList::new(vec![
0_u64;
E::MaxValidatorsPerCommitteePerSlot::to_usize(
)
])
.unwrap(),
attesting_indices: VariableList::new(vec![0_u64; E::MaxValidatorsPerSlot::to_usize()])
.unwrap(),
data: AttestationData::default(),
signature: AggregateSignature::empty(),
};
@@ -626,12 +622,8 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockElectra<E, Payload>
E::max_attester_slashings_electra()
]
.into();
// TODO(electra): check this
let attestation = AttestationElectra {
aggregation_bits: BitList::with_capacity(
E::MaxValidatorsPerCommitteePerSlot::to_usize(),
)
.unwrap(),
aggregation_bits: BitList::with_capacity(E::MaxValidatorsPerSlot::to_usize()).unwrap(),
data: AttestationData::default(),
signature: AggregateSignature::empty(),
// TODO(electra): does this actually allocate the size correctly?

View File

@@ -161,6 +161,7 @@ pub enum Error {
MerkleTreeError(merkle_proof::MerkleTreeError),
PartialWithdrawalCountInvalid(usize),
NonExecutionAddresWithdrawalCredential,
NoCommitteeFound,
}
/// Control whether an epoch-indexed field can be indexed at the next epoch or not.

View File

@@ -63,7 +63,7 @@ pub trait EthSpec:
* Misc
*/
type MaxValidatorsPerCommittee: Unsigned + Clone + Sync + Send + Debug + PartialEq + Eq;
type MaxValidatorsPerCommitteePerSlot: Unsigned + Clone + Sync + Send + Debug + PartialEq + Eq;
type MaxValidatorsPerSlot: Unsigned + Clone + Sync + Send + Debug + PartialEq + Eq;
type MaxCommitteesPerSlot: Unsigned + Clone + Sync + Send + Debug + PartialEq + Eq;
/*
* Time parameters
@@ -352,7 +352,7 @@ impl EthSpec for MainnetEthSpec {
type SubnetBitfieldLength = U64;
type MaxValidatorsPerCommittee = U2048;
type MaxCommitteesPerSlot = U64;
type MaxValidatorsPerCommitteePerSlot = U131072;
type MaxValidatorsPerSlot = U131072;
type GenesisEpoch = U0;
type SlotsPerEpoch = U32;
type EpochsPerEth1VotingPeriod = U64;
@@ -433,7 +433,7 @@ impl EthSpec for MinimalEthSpec {
SyncCommitteeSubnetCount,
MaxValidatorsPerCommittee,
MaxCommitteesPerSlot,
MaxValidatorsPerCommitteePerSlot,
MaxValidatorsPerSlot,
GenesisEpoch,
HistoricalRootsLimit,
ValidatorRegistryLimit,
@@ -475,7 +475,7 @@ impl EthSpec for GnosisEthSpec {
type SubnetBitfieldLength = U64;
type MaxValidatorsPerCommittee = U2048;
type MaxCommitteesPerSlot = U64;
type MaxValidatorsPerCommitteePerSlot = U131072;
type MaxValidatorsPerSlot = U131072;
type GenesisEpoch = U0;
type SlotsPerEpoch = U16;
type EpochsPerEth1VotingPeriod = U64;

View File

@@ -59,7 +59,7 @@ pub struct IndexedAttestation<E: EthSpec> {
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerCommittee>,
#[superstruct(only(Electra), partial_getter(rename = "attesting_indices_electra"))]
#[serde(with = "quoted_variable_list_u64")]
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerCommitteePerSlot>,
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerSlot>,
pub data: AttestationData,
pub signature: AggregateSignature,
}

View File

@@ -2,8 +2,8 @@ use super::{
AggregateAndProof, AggregateAndProofBase, AggregateAndProofElectra, AggregateAndProofRef,
};
use super::{
Attestation, ChainSpec, Domain, EthSpec, Fork, Hash256, SecretKey, SelectionProof, Signature,
SignedRoot,
AttestationRef, ChainSpec, Domain, EthSpec, Fork, Hash256, SecretKey, SelectionProof,
Signature, SignedRoot,
};
use crate::test_utils::TestRandom;
use serde::{Deserialize, Serialize};
@@ -58,7 +58,7 @@ impl<E: EthSpec> SignedAggregateAndProof<E> {
/// If `selection_proof.is_none()` it will be computed locally.
pub fn from_aggregate(
aggregator_index: u64,
aggregate: Attestation<E>,
aggregate: AttestationRef<'_, E>,
selection_proof: Option<SelectionProof>,
secret_key: &SecretKey,
fork: &Fork,