Heze fork

This commit is contained in:
Eitan Seri-Levi
2026-04-30 09:23:00 +02:00
parent a2dcd2d6de
commit c57a49b3af
24 changed files with 64 additions and 266 deletions

View File

@@ -27,18 +27,13 @@ use tree_hash::TreeHash;
use types::consts::gloas::BUILDER_INDEX_SELF_BUILD;
use types::{
Address, Attestation, AttestationElectra, AttesterSlashing, AttesterSlashingElectra,
<<<<<<< HEAD
BeaconBlock, BeaconBlockBodyGloas, BeaconBlockBodyHeze, BeaconBlockGloas, BeaconBlockHeze,
BeaconState, BeaconStateError,
BuilderIndex, Deposit, Eth1Data, EthSpec, ExecutionBlockHash, ExecutionPayloadBid,
=======
BeaconBlock, BeaconBlockBodyGloas, BeaconBlockGloas, BeaconState, BeaconStateError,
BuilderIndex, ChainSpec, Deposit, Eth1Data, EthSpec, ExecutionBlockHash, ExecutionPayloadBid,
>>>>>>> f406e9c3fbf6f4abdd65a7d1501e2e892c96d2c9
ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequests, FullPayload, Graffiti,
Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, SignedBeaconBlock,
SignedBlsToExecutionChange, SignedExecutionPayloadBid, SignedExecutionPayloadEnvelope,
SignedVoluntaryExit, Slot, SyncAggregate, Withdrawal, Withdrawals,
BeaconState, BeaconStateError, BuilderIndex, ChainSpec, Deposit, Eth1Data, EthSpec,
ExecutionBlockHash, ExecutionPayloadBid, ExecutionPayloadEnvelope, ExecutionPayloadGloas,
ExecutionRequests, FullPayload, Graffiti, Hash256, PayloadAttestation, ProposerSlashing,
RelativeEpoch, SignedBeaconBlock, SignedBlsToExecutionChange, SignedExecutionPayloadBid,
SignedExecutionPayloadEnvelope, SignedVoluntaryExit, Slot, SyncAggregate, Withdrawal,
Withdrawals,
};
use crate::pending_payload_envelopes::PendingEnvelopeData;

View File

@@ -8,10 +8,7 @@ use crate::custody_context::NodeCustodyType;
use crate::data_availability_checker::DataAvailabilityChecker;
use crate::fork_choice_signal::ForkChoiceSignalTx;
use crate::graffiti_calculator::{GraffitiCalculator, GraffitiOrigin};
use crate::kzg_utils::{
build_data_column_sidecars_fulu, build_data_column_sidecars_gloas,
build_data_column_sidecars_heze,
};
use crate::kzg_utils::{build_data_column_sidecars_fulu, build_data_column_sidecars_gloas};
use crate::light_client_server_cache::LightClientServerCache;
use crate::migrate::{BackgroundMigrator, MigratorConfig};
use crate::observed_data_sidecars::ObservedDataSidecars;
@@ -1239,15 +1236,7 @@ fn build_data_columns_from_blobs<E: EthSpec>(
.cloned()
.map_err(|e| format!("Unexpected pre Deneb block: {e:?}"))?;
if block.fork_name_unchecked().heze_enabled() {
build_data_column_sidecars_heze(
block.message().tree_hash_root(),
block.slot(),
blob_cells_and_proofs_vec,
spec,
)
.map_err(|e| format!("Failed to compute weak subjectivity data_columns: {e:?}"))?
} else if block.fork_name_unchecked().gloas_enabled() {
if block.fork_name_unchecked().gloas_enabled() {
build_data_column_sidecars_gloas(
block.message().tree_hash_root(),
block.slot(),

View File

@@ -320,9 +320,7 @@ impl<T: BeaconChainTypes, O: ObservationStrategy> GossipVerifiedDataColumn<T, O>
})
}
// TODO(gloas) support gloas data column variant
DataColumnSidecar::Gloas(_) | DataColumnSidecar::Heze(_) => {
Err(GossipDataColumnError::InvalidVariant)
}
DataColumnSidecar::Gloas(_) => Err(GossipDataColumnError::InvalidVariant),
}
}
@@ -1131,9 +1129,7 @@ fn verify_data_column_sidecar<E: EthSpec>(
// TODO(gloas): implement Gloas verification that takes kzg_commitments from block as parameter
let commitments_len = match data_column {
DataColumnSidecar::Fulu(dc) => dc.kzg_commitments.len(),
DataColumnSidecar::Gloas(_) | DataColumnSidecar::Heze(_) => {
return Err(GossipDataColumnError::InvalidVariant)
}
DataColumnSidecar::Gloas(_) => return Err(GossipDataColumnError::InvalidVariant),
};
if commitments_len == 0 {

View File

@@ -13,8 +13,7 @@ use types::data::{
use types::kzg_ext::KzgCommitments;
use types::{
Blob, BlobSidecar, BlobSidecarList, ChainSpec, DataColumnSidecar, DataColumnSidecarFulu,
DataColumnSidecarGloas, DataColumnSidecarHeze, DataColumnSidecarList, EthSpec, Hash256,
KzgCommitment, KzgProof,
DataColumnSidecarGloas, DataColumnSidecarList, EthSpec, Hash256, KzgCommitment, KzgProof,
SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlindedBeaconBlock, Slot,
};
@@ -81,11 +80,11 @@ pub fn validate_full_data_columns<'a, E: EthSpec>(
// This function requires Fulu sidecars with embedded commitments.
let kzg_commitments = match data_column.as_ref() {
DataColumnSidecar::Fulu(dc) => &dc.kzg_commitments,
DataColumnSidecar::Gloas(_) | DataColumnSidecar::Heze(_) => {
DataColumnSidecar::Gloas(_) => {
return Err((
Some(col_index),
KzgError::InconsistentArrayLength(
"Gloas/Heze data columns require commitments from block".to_string(),
"Gloas data columns require commitments from block".to_string(),
),
));
}
@@ -275,15 +274,7 @@ pub fn blobs_to_data_column_sidecars<E: EthSpec>(
})
.collect::<Result<Vec<_>, KzgError>>()?;
if block.fork_name_unchecked().heze_enabled() {
build_data_column_sidecars_heze(
signed_block_header.message.tree_hash_root(),
block.slot(),
blob_cells_and_proofs_vec,
spec,
)
.map_err(DataColumnSidecarError::BuildSidecarFailed)
} else if block.fork_name_unchecked().gloas_enabled() {
if block.fork_name_unchecked().gloas_enabled() {
build_data_column_sidecars_gloas(
signed_block_header.message.tree_hash_root(),
block.slot(),
@@ -403,7 +394,7 @@ pub(crate) fn build_data_column_sidecars_fulu<E: EthSpec>(
.fork_name_at_slot::<E>(signed_block_header.message.slot)
.gloas_enabled()
{
return Err("Attempting to construct Fulu data columns post-Gloas/Heze".to_owned());
return Err("Attempting to construct Fulu data columns post-Gloas".to_owned());
}
let number_of_columns = E::number_of_columns();
@@ -528,68 +519,6 @@ pub(crate) fn build_data_column_sidecars_gloas<E: EthSpec>(
sidecars
}
pub(crate) fn build_data_column_sidecars_heze<E: EthSpec>(
beacon_block_root: Hash256,
slot: Slot,
blob_cells_and_proofs_vec: Vec<CellsAndKzgProofs>,
spec: &ChainSpec,
) -> Result<DataColumnSidecarList<E>, String> {
if !spec.fork_name_at_slot::<E>(slot).heze_enabled() {
return Err("Attempting to construct Heze data columns pre-Heze".to_owned());
}
let number_of_columns = E::number_of_columns();
let max_blobs_per_block = spec.max_blobs_per_block(slot.epoch(E::slots_per_epoch())) as usize;
let mut columns = vec![Vec::with_capacity(max_blobs_per_block); number_of_columns];
let mut column_kzg_proofs = vec![Vec::with_capacity(max_blobs_per_block); number_of_columns];
for (blob_cells, blob_cell_proofs) in blob_cells_and_proofs_vec {
for col in 0..number_of_columns {
let cell = blob_cells
.get(col)
.ok_or(format!("Missing blob cell at index {col}"))?;
let cell: Vec<u8> = cell.to_vec();
let cell =
Cell::<E>::try_from(cell).map_err(|e| format!("BytesPerCell exceeded: {e:?}"))?;
let proof = blob_cell_proofs
.get(col)
.ok_or(format!("Missing blob cell KZG proof at index {col}"))?;
let column = columns
.get_mut(col)
.ok_or(format!("Missing data column at index {col}"))?;
let column_proofs = column_kzg_proofs
.get_mut(col)
.ok_or(format!("Missing data column proofs at index {col}"))?;
column.push(cell);
column_proofs.push(*proof);
}
}
let sidecars: Result<Vec<Arc<DataColumnSidecar<E>>>, String> = columns
.into_iter()
.zip(column_kzg_proofs)
.enumerate()
.map(
|(index, (col, proofs))| -> Result<Arc<DataColumnSidecar<E>>, String> {
Ok(Arc::new(DataColumnSidecar::Heze(DataColumnSidecarHeze {
index: index as u64,
column: DataColumn::<E>::try_from(col)
.map_err(|e| format!("MaxBlobCommitmentsPerBlock exceeded: {e:?}"))?,
kzg_proofs: VariableList::try_from(proofs)
.map_err(|e| format!("MaxBlobCommitmentsPerBlock exceeded: {e:?}"))?,
beacon_block_root,
slot,
})))
},
)
.collect();
sidecars
}
pub(crate) fn build_partial_data_columns<E: EthSpec>(
header: &PartialDataColumnHeader<E>,
blob_cells_and_proofs_vec: Vec<Option<CellsAndKzgProofs>>,
@@ -700,7 +629,7 @@ pub fn reconstruct_blobs<E: EthSpec>(
// https://github.com/sigp/lighthouse/issues/7413
let num_of_blobs = first_data_column
.kzg_commitments()
.map_err(|_| "Gloas/Heze blob reconstruction not yet supported".to_string())?
.map_err(|_| "Gloas blob reconstruction not yet supported".to_string())?
.len();
(0..num_of_blobs).collect()
}
@@ -780,7 +709,7 @@ pub fn reconstruct_data_columns<E: EthSpec>(
.kzg_commitments()
.map_err(|_| {
KzgError::InconsistentArrayLength(
"Gloas/Heze data column reconstruction not yet supported".to_string(),
"Gloas data column reconstruction not yet supported".to_string(),
)
})?
.len();
@@ -822,13 +751,6 @@ pub fn reconstruct_data_columns<E: EthSpec>(
spec,
)
.map_err(KzgError::ReconstructFailed),
DataColumnSidecar::Heze(first_column) => build_data_column_sidecars_heze(
first_column.beacon_block_root,
first_column.slot,
blob_cells_and_proofs_vec,
spec,
)
.map_err(KzgError::ReconstructFailed),
}
}

View File

@@ -265,8 +265,7 @@ mod tests {
use bls::{FixedBytesExtended, Signature};
use std::sync::Arc;
use types::{
BeaconBlockHeader, DataColumnSidecarFulu, DataColumnSidecarGloas, DataColumnSidecarHeze,
ForkName, MainnetEthSpec,
BeaconBlockHeader, DataColumnSidecarFulu, DataColumnSidecarGloas, ForkName, MainnetEthSpec,
SignedBeaconBlockHeader,
};
@@ -321,31 +320,13 @@ mod tests {
}))
}
/// Creates a Heze DataColumnSidecar for testing.
/// Keyed by (beacon_block_root, slot) in the observation cache.
fn get_data_column_sidecar_heze(
slot: u64,
beacon_block_root: Hash256,
index: u64,
) -> Arc<DataColumnSidecar<E>> {
Arc::new(DataColumnSidecar::Heze(DataColumnSidecarHeze {
index,
column: vec![].try_into().unwrap(),
kzg_proofs: vec![].try_into().unwrap(),
slot: slot.into(),
beacon_block_root,
}))
}
fn get_sidecar(
slot: u64,
key: u64,
index: u64,
fork_name: ForkName,
) -> Arc<DataColumnSidecar<E>> {
if fork_name.heze_enabled() {
get_data_column_sidecar_heze(slot, Hash256::from_low_u64_be(key), index)
} else if fork_name.gloas_enabled() {
if fork_name.gloas_enabled() {
get_data_column_sidecar_gloas(slot, Hash256::from_low_u64_be(key), index)
} else {
get_data_column_sidecar_fulu(slot, key, index)

View File

@@ -3,10 +3,7 @@ use crate::block_verification_types::{AsBlock, AvailableBlockData, LookupBlock,
use crate::custody_context::NodeCustodyType;
use crate::data_availability_checker::DataAvailabilityChecker;
use crate::graffiti_calculator::GraffitiSettings;
use crate::kzg_utils::{
build_data_column_sidecars_fulu, build_data_column_sidecars_gloas,
build_data_column_sidecars_heze,
};
use crate::kzg_utils::{build_data_column_sidecars_fulu, build_data_column_sidecars_gloas};
use crate::observed_operations::ObservationOutcome;
pub use crate::persisted_beacon_chain::PersistedBeaconChain;
use crate::{BeaconBlockResponseWrapper, CustodyContext, get_block_root};
@@ -3802,41 +3799,6 @@ pub fn generate_data_column_sidecars_from_block<E: EthSpec>(
) -> DataColumnSidecarList<E> {
// Load the precomputed column sidecar to avoid computing them for every block in the tests.
// Then repeat the cells and proofs for every blob
<<<<<<< HEAD
if block.fork_name_unchecked().heze_enabled() {
let template_data_columns =
RuntimeVariableList::<DataColumnSidecarHeze<E>>::from_ssz_bytes(
TEST_DATA_COLUMN_SIDECARS_SSZ,
E::number_of_columns(),
)
.unwrap();
let (cells, proofs) = template_data_columns
.into_iter()
.map(|sidecar| {
let DataColumnSidecarHeze {
column, kzg_proofs, ..
} = sidecar;
// There's only one cell per column for a single blob
let cell_bytes: Vec<u8> = column.into_iter().next().unwrap().into();
let kzg_cell = cell_bytes.try_into().unwrap();
let kzg_proof = kzg_proofs.into_iter().next().unwrap();
(kzg_cell, kzg_proof)
})
.collect::<(Vec<_>, Vec<_>)>();
let blob_cells_and_proofs_vec =
vec![(cells.try_into().unwrap(), proofs.try_into().unwrap()); kzg_commitments.len()];
build_data_column_sidecars_heze(
signed_block_header.message.tree_hash_root(),
signed_block_header.message.slot,
blob_cells_and_proofs_vec,
spec,
)
.unwrap()
} else if block.fork_name_unchecked().gloas_enabled() {
=======
if block.fork_name_unchecked().gloas_enabled() {
let kzg_commitments = &block
.message()
@@ -3850,7 +3812,6 @@ pub fn generate_data_column_sidecars_from_block<E: EthSpec>(
}
let num_blobs = kzg_commitments.len();
let signed_block_header = block.signed_block_header();
>>>>>>> f406e9c3fbf6f4abdd65a7d1501e2e892c96d2c9
let template_data_columns =
RuntimeVariableList::<DataColumnSidecarGloas<E>>::from_ssz_bytes(
TEST_DATA_COLUMN_SIDECARS_GLOAS_SSZ,