Skip to content

Commit

Permalink
convert op pool messages to electra in electra
Browse files Browse the repository at this point in the history
  • Loading branch information
realbigsean committed Jul 11, 2024
1 parent c4cb8ad commit 386aacd
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 21 deletions.
73 changes: 53 additions & 20 deletions beacon_node/http_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1834,18 +1834,35 @@ pub fn serve<T: BeaconChainTypes>(
.filter(|&att| query_filter(att.data()))
.cloned(),
);
let slot = query
.slot
.or_else(|| {
attestations
.first()
.map(|att| att.data().slot)
.or_else(|| chain.slot_clock.now())
})
.ok_or(warp_utils::reject::custom_server_error(
"unable to read slot clock".to_string(),
))?;
let fork_name = chain.spec.fork_name_at_slot::<T::EthSpec>(slot);
// Use the current slot to find the fork version, and convert all messages to the
// current fork's format. This is to ensure consistent message types matching
// `Eth-Consensus-Version`.
let current_slot =
chain
.slot_clock
.now()
.ok_or(warp_utils::reject::custom_server_error(
"unable to read slot clock".to_string(),
))?;
let fork_name = chain.spec.fork_name_at_slot::<T::EthSpec>(current_slot);

let attestations = if fork_name.electra_enabled() {
attestations
.into_iter()
.map(|att| match att {
Attestation::Base(a) => Ok(Attestation::Electra(a.try_into()?)),
Attestation::Electra(a) => Ok(Attestation::Electra(a)),
})
.collect::<Result<Vec<_>, types::attestation::Error>>()
.map_err(|e| {
warp_utils::reject::custom_server_error(format!(
"could not convert base attestations to electra {e:?}"
))
})?
} else {
attestations
};

let res = fork_versioned_response(endpoint_version, fork_name, &attestations)?;
Ok(add_consensus_version_header(
warp::reply::json(&res).into_response(),
Expand Down Expand Up @@ -1914,14 +1931,30 @@ pub fn serve<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>| {
task_spawner.blocking_response_task(Priority::P1, move || {
let slashings = chain.op_pool.get_all_attester_slashings();
let slot = slashings
.first()
.map(|slashing| slashing.attestation_1().data().slot)
.or_else(|| chain.slot_clock.now())
.ok_or(warp_utils::reject::custom_server_error(
"unable to read slot clock".to_string(),
))?;
let fork_name = chain.spec.fork_name_at_slot::<T::EthSpec>(slot);

// Use the current slot to find the fork version, and convert all messages to the
// current fork's format. This is to ensure consistent message types matching
// `Eth-Consensus-Version`.
let current_slot =
chain
.slot_clock
.now()
.ok_or(warp_utils::reject::custom_server_error(
"unable to read slot clock".to_string(),
))?;
let fork_name = chain.spec.fork_name_at_slot::<T::EthSpec>(current_slot);

let slashings = if fork_name.electra_enabled() {
slashings
.into_iter()
.map(|att| match att {
AttesterSlashing::Base(a) => AttesterSlashing::Electra(a.into()),
AttesterSlashing::Electra(a) => AttesterSlashing::Electra(a),
})
.collect::<Vec<_>>()
} else {
slashings
};
let res = fork_versioned_response(endpoint_version, fork_name, &slashings)?;
Ok(add_consensus_version_header(
warp::reply::json(&res).into_response(),
Expand Down
35 changes: 35 additions & 0 deletions consensus/types/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ pub enum Error {
InvalidCommitteeIndex,
}

impl From<ssz_types::Error> for Error {
fn from(e: ssz_types::Error) -> Self {
Error::SszTypesError(e)
}
}

#[superstruct(
variants(Base, Electra),
variant_attributes(
Expand Down Expand Up @@ -416,6 +422,35 @@ impl<E: EthSpec> AttestationBase<E> {
}
}

impl<E: EthSpec> TryFrom<AttestationBase<E>> for AttestationElectra<E> {
type Error = Error;
fn try_from(att: AttestationBase<E>) -> Result<Self, Self::Error> {
// Extend the aggregation bits list.
let aggregation_bits = att.extend_aggregation_bits()?;
let AttestationBase {
aggregation_bits: _,
mut data,
signature,
} = att;

// Set the committee index based on the index field.
let mut committee_bits: BitVector<E::MaxCommitteesPerSlot> = BitVector::default();
committee_bits
.set(data.index as usize, true)
.map_err(|_| Error::InvalidCommitteeIndex)?;

// Set the attestation data's index to zero.
data.index = 0;

Ok(Self {
aggregation_bits,
data,
committee_bits,
signature,
})
}
}

impl<E: EthSpec> SlotData for Attestation<E> {
fn get_slot(&self) -> Slot {
self.data().slot
Expand Down
15 changes: 14 additions & 1 deletion consensus/types/src/attester_slashing.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::indexed_attestation::{
IndexedAttestationBase, IndexedAttestationElectra, IndexedAttestationRef,
IndexedAttestation, IndexedAttestationBase, IndexedAttestationElectra, IndexedAttestationRef,
};
use crate::{test_utils::TestRandom, EthSpec};
use derivative::Derivative;
Expand Down Expand Up @@ -161,6 +161,19 @@ impl<E: EthSpec> AttesterSlashing<E> {
}
}

impl<E: EthSpec> From<AttesterSlashingBase<E>> for AttesterSlashingElectra<E> {
fn from(attester_slashing: AttesterSlashingBase<E>) -> Self {
let AttesterSlashingBase {
attestation_1,
attestation_2,
} = attester_slashing;
AttesterSlashingElectra {
attestation_1: IndexedAttestation::Base(attestation_1).to_electra(),
attestation_2: IndexedAttestation::Base(attestation_2).to_electra(),
}
}
}

impl<E: EthSpec> TestRandom for AttesterSlashing<E> {
fn random_for_test(rng: &mut impl RngCore) -> Self {
if rng.gen_bool(0.5) {
Expand Down

0 comments on commit 386aacd

Please sign in to comment.