Electra attestation changes sean review (#5972)

* instantiate empty bitlist in unreachable code

* clean up error conversion

* fork enabled bool cleanup

* remove a couple todos

* return bools instead of options in `aggregate` and use the result

* delete commented out code

* use map macros in simple transformations

* remove signers_disjoint_from

* get ef tests compiling

* get ef tests compiling

* update intentionally excluded files
This commit is contained in:
realbigsean
2024-06-21 00:20:10 -04:00
committed by GitHub
parent efb8a01e91
commit 27ed90e4dc
13 changed files with 56 additions and 100 deletions

View File

@@ -33,7 +33,8 @@ use tree_hash_derive::TreeHash;
derive(Debug, PartialEq, TreeHash, Serialize,),
serde(untagged, bound = "E: EthSpec"),
tree_hash(enum_behaviour = "transparent")
)
),
map_ref_into(AttestationRef)
)]
#[derive(
arbitrary::Arbitrary, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, TreeHash,
@@ -59,19 +60,17 @@ pub struct AggregateAndProof<E: EthSpec> {
impl<'a, E: EthSpec> AggregateAndProofRef<'a, E> {
/// Returns `true` if `validator_pubkey` signed over `self.aggregate.data.slot`.
pub fn aggregate(self) -> AttestationRef<'a, E> {
match self {
AggregateAndProofRef::Base(a) => AttestationRef::Base(&a.aggregate),
AggregateAndProofRef::Electra(a) => AttestationRef::Electra(&a.aggregate),
}
map_aggregate_and_proof_ref_into_attestation_ref!(&'a _, self, |inner, cons| {
cons(&inner.aggregate)
})
}
}
impl<E: EthSpec> AggregateAndProof<E> {
/// Returns `true` if `validator_pubkey` signed over `self.aggregate.data.slot`.
pub fn aggregate(&self) -> AttestationRef<E> {
match self {
AggregateAndProof::Base(a) => AttestationRef::Base(&a.aggregate),
AggregateAndProof::Electra(a) => AttestationRef::Electra(&a.aggregate),
}
pub fn aggregate<'a>(&'a self) -> AttestationRef<'a, E> {
map_aggregate_and_proof_ref_into_attestation_ref!(&'a _, self.to_ref(), |inner, cons| {
cons(&inner.aggregate)
})
}
}

View File

@@ -1,6 +1,6 @@
use crate::slot_data::SlotData;
use crate::Checkpoint;
use crate::{test_utils::TestRandom, Hash256, Slot};
use crate::{Checkpoint, ForkName};
use derivative::Derivative;
use safe_arith::ArithError;
use serde::{Deserialize, Serialize};
@@ -99,7 +99,7 @@ impl<E: EthSpec> Attestation<E> {
target: Checkpoint,
spec: &ChainSpec,
) -> Result<Self, Error> {
if spec.fork_name_at_slot::<E>(slot) >= ForkName::Electra {
if spec.fork_name_at_slot::<E>(slot).electra_enabled() {
let mut committee_bits: BitVector<E::MaxCommitteesPerSlot> = BitVector::default();
committee_bits
.set(committee_index as usize, true)
@@ -277,16 +277,6 @@ impl<'a, E: EthSpec> AttestationRef<'a, E> {
}
impl<E: EthSpec> AttestationElectra<E> {
/// Are the aggregation bitfields of these attestations disjoint?
// TODO(electra): check whether the definition from CompactIndexedAttestation::should_aggregate
// is useful where this is used, i.e. only consider attestations disjoint when their committees
// match AND their aggregation bits do not intersect.
pub fn signers_disjoint_from(&self, other: &Self) -> bool {
self.aggregation_bits
.intersection(&other.aggregation_bits)
.is_zero()
}
pub fn committee_index(&self) -> Option<u64> {
self.get_committee_indices().first().cloned()
}
@@ -304,7 +294,6 @@ impl<E: EthSpec> AttestationElectra<E> {
/// The aggregation bitfields must be disjoint, and the data must be the same.
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);
}
@@ -358,19 +347,11 @@ impl<E: EthSpec> AttestationElectra<E> {
}
impl<E: EthSpec> AttestationBase<E> {
/// Are the aggregation bitfields of these attestations disjoint?
pub fn signers_disjoint_from(&self, other: &Self) -> bool {
self.aggregation_bits
.intersection(&other.aggregation_bits)
.is_zero()
}
/// Aggregate another Attestation into this one.
///
/// The aggregation bitfields must be disjoint, and the data must be the same.
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);
}

View File

@@ -120,6 +120,10 @@ impl ForkName {
}
}
pub fn deneb_enabled(self) -> bool {
self >= ForkName::Deneb
}
pub fn electra_enabled(self) -> bool {
self >= ForkName::Electra
}

View File

@@ -34,7 +34,9 @@ use tree_hash_derive::TreeHash;
),
serde(bound = "E: EthSpec"),
arbitrary(bound = "E: EthSpec"),
)
),
map_into(Attestation),
map_ref_into(AggregateAndProofRef)
)]
#[derive(
arbitrary::Arbitrary, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, TreeHash,
@@ -102,19 +104,17 @@ impl<E: EthSpec> SignedAggregateAndProof<E> {
}
}
pub fn message(&self) -> AggregateAndProofRef<E> {
match self {
SignedAggregateAndProof::Base(message) => AggregateAndProofRef::Base(&message.message),
SignedAggregateAndProof::Electra(message) => {
AggregateAndProofRef::Electra(&message.message)
}
}
pub fn message<'a>(&'a self) -> AggregateAndProofRef<'a, E> {
map_signed_aggregate_and_proof_ref_into_aggregate_and_proof_ref!(
&'a _,
self.to_ref(),
|inner, cons| { cons(&inner.message) }
)
}
pub fn into_attestation(self) -> Attestation<E> {
match self {
Self::Base(att) => Attestation::Base(att.message.aggregate),
Self::Electra(att) => Attestation::Electra(att.message.aggregate),
}
map_signed_aggregate_and_proof_into_attestation!(self, |inner, cons| {
cons(inner.message.aggregate)
})
}
}

View File

@@ -63,13 +63,6 @@ impl<E: EthSpec> SyncCommitteeContribution<E> {
})
}
/// Are the aggregation bitfields of these sync contribution disjoint?
pub fn signers_disjoint_from(&self, other: &Self) -> bool {
self.aggregation_bits
.intersection(&other.aggregation_bits)
.is_zero()
}
/// Aggregate another `SyncCommitteeContribution` into this one.
///
/// The aggregation bitfields must be disjoint, and the data must be the same.
@@ -77,7 +70,6 @@ impl<E: EthSpec> SyncCommitteeContribution<E> {
debug_assert_eq!(self.slot, other.slot);
debug_assert_eq!(self.beacon_block_root, other.beacon_block_root);
debug_assert_eq!(self.subcommittee_index, other.subcommittee_index);
debug_assert!(self.signers_disjoint_from(other));
self.aggregation_bits = self.aggregation_bits.union(&other.aggregation_bits);
self.signature.add_assign_aggregate(&other.signature);