Ensure finalized block is the correct fork variant when constructing light client updates (#7085)

This commit is contained in:
Eitan Seri-Levi
2025-03-16 20:39:35 -06:00
committed by GitHub
parent 50b5a72c58
commit 9db29b023b
2 changed files with 49 additions and 10 deletions

View File

@@ -213,14 +213,18 @@ impl<E: EthSpec> LightClientUpdate<E> {
.map_err(|_| Error::InconsistentFork)? .map_err(|_| Error::InconsistentFork)?
{ {
ForkName::Base => return Err(Error::AltairForkNotActive), ForkName::Base => return Err(Error::AltairForkNotActive),
ForkName::Altair | ForkName::Bellatrix => { fork_name @ ForkName::Altair | fork_name @ ForkName::Bellatrix => {
let attested_header = let attested_header =
LightClientHeaderAltair::block_to_light_client_header(attested_block)?; LightClientHeaderAltair::block_to_light_client_header(attested_block)?;
let finalized_header = if let Some(finalized_block) = finalized_block { let finalized_header = if let Some(finalized_block) = finalized_block {
if finalized_block.fork_name_unchecked() == fork_name {
LightClientHeaderAltair::block_to_light_client_header(finalized_block)? LightClientHeaderAltair::block_to_light_client_header(finalized_block)?
} else { } else {
LightClientHeaderAltair::default() LightClientHeaderAltair::default()
}
} else {
LightClientHeaderAltair::default()
}; };
Self::Altair(LightClientUpdateAltair { Self::Altair(LightClientUpdateAltair {
@@ -233,14 +237,18 @@ impl<E: EthSpec> LightClientUpdate<E> {
signature_slot: block_slot, signature_slot: block_slot,
}) })
} }
ForkName::Capella => { fork_name @ ForkName::Capella => {
let attested_header = let attested_header =
LightClientHeaderCapella::block_to_light_client_header(attested_block)?; LightClientHeaderCapella::block_to_light_client_header(attested_block)?;
let finalized_header = if let Some(finalized_block) = finalized_block { let finalized_header = if let Some(finalized_block) = finalized_block {
if finalized_block.fork_name_unchecked() == fork_name {
LightClientHeaderCapella::block_to_light_client_header(finalized_block)? LightClientHeaderCapella::block_to_light_client_header(finalized_block)?
} else { } else {
LightClientHeaderCapella::default() LightClientHeaderCapella::default()
}
} else {
LightClientHeaderCapella::default()
}; };
Self::Capella(LightClientUpdateCapella { Self::Capella(LightClientUpdateCapella {
@@ -253,14 +261,18 @@ impl<E: EthSpec> LightClientUpdate<E> {
signature_slot: block_slot, signature_slot: block_slot,
}) })
} }
ForkName::Deneb => { fork_name @ ForkName::Deneb => {
let attested_header = let attested_header =
LightClientHeaderDeneb::block_to_light_client_header(attested_block)?; LightClientHeaderDeneb::block_to_light_client_header(attested_block)?;
let finalized_header = if let Some(finalized_block) = finalized_block { let finalized_header = if let Some(finalized_block) = finalized_block {
if finalized_block.fork_name_unchecked() == fork_name {
LightClientHeaderDeneb::block_to_light_client_header(finalized_block)? LightClientHeaderDeneb::block_to_light_client_header(finalized_block)?
} else { } else {
LightClientHeaderDeneb::default() LightClientHeaderDeneb::default()
}
} else {
LightClientHeaderDeneb::default()
}; };
Self::Deneb(LightClientUpdateDeneb { Self::Deneb(LightClientUpdateDeneb {
@@ -273,14 +285,18 @@ impl<E: EthSpec> LightClientUpdate<E> {
signature_slot: block_slot, signature_slot: block_slot,
}) })
} }
ForkName::Electra => { fork_name @ ForkName::Electra => {
let attested_header = let attested_header =
LightClientHeaderElectra::block_to_light_client_header(attested_block)?; LightClientHeaderElectra::block_to_light_client_header(attested_block)?;
let finalized_header = if let Some(finalized_block) = finalized_block { let finalized_header = if let Some(finalized_block) = finalized_block {
if finalized_block.fork_name_unchecked() == fork_name {
LightClientHeaderElectra::block_to_light_client_header(finalized_block)? LightClientHeaderElectra::block_to_light_client_header(finalized_block)?
} else { } else {
LightClientHeaderElectra::default() LightClientHeaderElectra::default()
}
} else {
LightClientHeaderElectra::default()
}; };
Self::Electra(LightClientUpdateElectra { Self::Electra(LightClientUpdateElectra {
@@ -293,14 +309,18 @@ impl<E: EthSpec> LightClientUpdate<E> {
signature_slot: block_slot, signature_slot: block_slot,
}) })
} }
ForkName::Fulu => { fork_name @ ForkName::Fulu => {
let attested_header = let attested_header =
LightClientHeaderFulu::block_to_light_client_header(attested_block)?; LightClientHeaderFulu::block_to_light_client_header(attested_block)?;
let finalized_header = if let Some(finalized_block) = finalized_block { let finalized_header = if let Some(finalized_block) = finalized_block {
if finalized_block.fork_name_unchecked() == fork_name {
LightClientHeaderFulu::block_to_light_client_header(finalized_block)? LightClientHeaderFulu::block_to_light_client_header(finalized_block)?
} else { } else {
LightClientHeaderFulu::default() LightClientHeaderFulu::default()
}
} else {
LightClientHeaderFulu::default()
}; };
Self::Fulu(LightClientUpdateFulu { Self::Fulu(LightClientUpdateFulu {

View File

@@ -264,6 +264,11 @@ pub(crate) async fn verify_light_client_updates<E: EthSpec>(
let slot = Slot::new(slot); let slot = Slot::new(slot);
let previous_slot = slot - 1; let previous_slot = slot - 1;
let sync_committee_period = slot
.epoch(E::slots_per_epoch())
.sync_committee_period(&E::default_spec())
.unwrap();
let previous_slot_block = client let previous_slot_block = client
.get_beacon_blocks::<E>(BlockId::Slot(previous_slot)) .get_beacon_blocks::<E>(BlockId::Slot(previous_slot))
.await .await
@@ -329,6 +334,20 @@ pub(crate) async fn verify_light_client_updates<E: EthSpec>(
"Existing finality update too old: signature slot {signature_slot}, current slot {slot:?}" "Existing finality update too old: signature slot {signature_slot}, current slot {slot:?}"
)); ));
} }
let light_client_updates = client
.get_beacon_light_client_updates::<E>(sync_committee_period, 1)
.await
.map_err(|e| format!("Error while getting light client update: {:?}", e))?
.ok_or(format!("Light client update not found {slot:?}"))?;
// Ensure we're only storing a single light client update for the given sync committee period
if light_client_updates.len() != 1 {
return Err(format!(
"{} light client updates was returned when only one was expected.",
light_client_updates.len()
));
}
} }
Ok(()) Ok(())