diff --git a/beacon_node/beacon_chain/src/beacon_block_streamer.rs b/beacon_node/beacon_chain/src/beacon_block_streamer.rs index 33fc9be4a0..13e6aaaa7d 100644 --- a/beacon_node/beacon_chain/src/beacon_block_streamer.rs +++ b/beacon_node/beacon_chain/src/beacon_block_streamer.rs @@ -15,8 +15,8 @@ use types::{ SignedBlindedBeaconBlock, Slot, }; use types::{ - ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadEip7805, - ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeader, + ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadElectra, + ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeader, ExecutionPayloadHeze, }; #[derive(PartialEq)] @@ -100,9 +100,10 @@ fn reconstruct_default_header_block( ForkName::Capella => ExecutionPayloadCapella::default().into(), ForkName::Deneb => ExecutionPayloadDeneb::default().into(), ForkName::Electra => ExecutionPayloadElectra::default().into(), - ForkName::Eip7805 => ExecutionPayloadEip7805::default().into(), + ForkName::Heze => ExecutionPayloadHeze::default().into(), ForkName::Fulu => ExecutionPayloadFulu::default().into(), ForkName::Gloas => ExecutionPayloadGloas::default().into(), + ForkName::Heze => ExecutionPayloadHeze::default().into(), ForkName::Base | ForkName::Altair => { return Err(Error::PayloadReconstruction(format!( "Block with fork variant {} has execution payload", @@ -724,7 +725,7 @@ mod tests { let capella_fork_epoch = 4usize; let deneb_fork_epoch = 6usize; let electra_fork_epoch = 8usize; - let eip7805_fork_epoch = 10usize; + let heze_fork_epoch = 10usize; let fulu_fork_epoch = 12usize; let num_blocks_produced = num_epochs * slots_per_epoch; @@ -734,9 +735,10 @@ mod tests { spec.capella_fork_epoch = Some(Epoch::new(capella_fork_epoch as u64)); spec.deneb_fork_epoch = Some(Epoch::new(deneb_fork_epoch as u64)); spec.electra_fork_epoch = Some(Epoch::new(electra_fork_epoch as u64)); - spec.eip7805_fork_epoch = Some(Epoch::new(eip7805_fork_epoch as u64)); + spec.heze_fork_epoch = Some(Epoch::new(heze_fork_epoch as u64)); spec.fulu_fork_epoch = Some(Epoch::new(fulu_fork_epoch as u64)); spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; let spec = Arc::new(spec); let harness = get_harness(VALIDATOR_COUNT, spec.clone()); diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 3bde5abf8e..f0864790cf 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2647,7 +2647,7 @@ impl BeaconChain { metrics::inc_counter(&metrics::INCLUSION_LIST_PROCESSING_SUCCESSES); if let Some(event_handler) = self.event_handler.as_ref() { event_handler.register(EventKind::InclusionList(SseInclusionList { - version: ForkName::Eip7805, + version: ForkName::Heze, data: v.signed_il.clone(), })); } @@ -6145,61 +6145,6 @@ impl BeaconChain { execution_payload_value, ) } - BeaconState::Eip7805(_) => { - tracing::error!("BeaconState::Eip7805"); - let ( - payload, - kzg_commitments, - maybe_blobs_and_proofs, - maybe_requests, - execution_payload_value, - ) = block_contents - .ok_or(BlockProductionError::MissingExecutionPayload)? - .deconstruct(); - - ( - BeaconBlock::Eip7805(BeaconBlockEip7805 { - slot, - proposer_index, - parent_root, - state_root: Hash256::zero(), - body: BeaconBlockBodyEip7805 { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings: proposer_slashings - .try_into() - .map_err(BlockProductionError::SszTypesError)?, - attester_slashings: attester_slashings_electra - .try_into() - .map_err(BlockProductionError::SszTypesError)?, - attestations: attestations_electra - .try_into() - .map_err(BlockProductionError::SszTypesError)?, - deposits: deposits - .try_into() - .map_err(BlockProductionError::SszTypesError)?, - voluntary_exits: voluntary_exits - .try_into() - .map_err(BlockProductionError::SszTypesError)?, - sync_aggregate: sync_aggregate - .ok_or(BlockProductionError::MissingSyncAggregate)?, - execution_payload: payload - .try_into() - .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - bls_to_execution_changes: bls_to_execution_changes - .try_into() - .map_err(BlockProductionError::SszTypesError)?, - blob_kzg_commitments: kzg_commitments - .ok_or(BlockProductionError::InvalidPayloadFork)?, - execution_requests: maybe_requests - .ok_or(BlockProductionError::MissingExecutionRequests)?, - }, - }), - maybe_blobs_and_proofs, - execution_payload_value, - ) - } BeaconState::Fulu(_) => { let ( payload, @@ -6259,6 +6204,11 @@ impl BeaconChain { "Attempting to produce gloas beacon block via non gloas code path".to_owned(), )); } + BeaconState::Heze(_) => { + return Err(BlockProductionError::HezeNotImplemented( + "Attempting to produce heze beacon block via non heze code path".to_owned(), + )); + } }; let block = SignedBeaconBlock::from_block( diff --git a/beacon_node/beacon_chain/src/block_production/gloas.rs b/beacon_node/beacon_chain/src/block_production/gloas.rs index d82c4a4873..74a9ddf419 100644 --- a/beacon_node/beacon_chain/src/block_production/gloas.rs +++ b/beacon_node/beacon_chain/src/block_production/gloas.rs @@ -27,12 +27,13 @@ use tree_hash::TreeHash; use types::consts::gloas::BUILDER_INDEX_SELF_BUILD; use types::{ Address, Attestation, AttestationElectra, AttesterSlashing, AttesterSlashingElectra, - BeaconBlock, BeaconBlockBodyGloas, BeaconBlockGloas, 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, + BeaconBlock, BeaconBlockBodyGloas, BeaconBlockBodyHeze, BeaconBlockGloas, BeaconBlockHeze, + 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; @@ -542,7 +543,7 @@ impl BeaconChain { | BeaconState::Deneb(_) | BeaconState::Electra(_) | BeaconState::Fulu(_) - | BeaconState::Eip7805(_) => { + | BeaconState::Heze(_) => { return Err(BlockProductionError::InvalidBlockVariant( "Cannot construct a block pre-Gloas".to_owned(), )); @@ -583,6 +584,42 @@ impl BeaconChain { _phantom: PhantomData::>, }, }), + BeaconState::Heze(_) => BeaconBlock::Heze(BeaconBlockHeze { + slot, + proposer_index, + parent_root, + state_root: Hash256::ZERO, + body: BeaconBlockBodyHeze { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings: proposer_slashings + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + attester_slashings: attester_slashings + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + attestations: attestations + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + deposits: deposits + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + voluntary_exits: voluntary_exits + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + sync_aggregate, + bls_to_execution_changes: bls_to_execution_changes + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + parent_execution_requests, + signed_execution_payload_bid, + payload_attestations: payload_attestations + .try_into() + .map_err(BlockProductionError::SszTypesError)?, + _phantom: PhantomData::>, + }, + }), }; let signed_beacon_block = SignedBeaconBlock::from_block( diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index 01dcaa74a9..de557e7e2c 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -8,7 +8,10 @@ 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}; +use crate::kzg_utils::{ + build_data_column_sidecars_fulu, build_data_column_sidecars_gloas, + build_data_column_sidecars_heze, +}; use crate::light_client_server_cache::LightClientServerCache; use crate::migrate::{BackgroundMigrator, MigratorConfig}; use crate::observed_data_sidecars::ObservedDataSidecars; @@ -1237,7 +1240,15 @@ fn build_data_columns_from_blobs( .cloned() .map_err(|e| format!("Unexpected pre Deneb block: {e:?}"))?; - if block.fork_name_unchecked().gloas_enabled() { + 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() { build_data_column_sidecars_gloas( block.message().tree_hash_root(), block.slot(), diff --git a/beacon_node/beacon_chain/src/data_column_verification.rs b/beacon_node/beacon_chain/src/data_column_verification.rs index 8ea3c792f4..967025d336 100644 --- a/beacon_node/beacon_chain/src/data_column_verification.rs +++ b/beacon_node/beacon_chain/src/data_column_verification.rs @@ -320,7 +320,9 @@ impl GossipVerifiedDataColumn }) } // TODO(gloas) support gloas data column variant - DataColumnSidecar::Gloas(_) => Err(GossipDataColumnError::InvalidVariant), + DataColumnSidecar::Gloas(_) | DataColumnSidecar::Heze(_) => { + Err(GossipDataColumnError::InvalidVariant) + } } } @@ -1129,7 +1131,9 @@ fn verify_data_column_sidecar( // 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(_) => return Err(GossipDataColumnError::InvalidVariant), + DataColumnSidecar::Gloas(_) | DataColumnSidecar::Heze(_) => { + return Err(GossipDataColumnError::InvalidVariant); + } }; if commitments_len == 0 { @@ -1564,8 +1568,8 @@ mod test { if !spec.is_fulu_scheduled() { return; } - // Gloas is not supported yet. - if spec.is_gloas_scheduled() { + // Gloas and Heze are not supported yet. + if spec.is_gloas_scheduled() || spec.is_heze_scheduled() { return; } diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index b8b88da476..df54249dc0 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -328,6 +328,8 @@ pub enum BlockProductionError { MissingExecutionPayloadEnvelope(Hash256), // TODO(gloas): Remove this once Gloas is implemented GloasNotImplemented(String), + // TODO(heze): Remove this once Heze is implemented + HezeNotImplemented(String), } easy_from_to!(BlockProcessingError, BlockProductionError); diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 04f25c35b3..37ab5b3a42 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -122,7 +122,7 @@ impl PayloadNotifier { ); inclusion_list_transactions } else { - // TODO(eip7805) what should be done here in terms of error handling + // TODO(heze) what should be done here in terms of error handling VariableList::new(vec![]) .map_err(|_| BlockError::InternalError("Cant create empty IL".to_string()))? }; diff --git a/beacon_node/beacon_chain/src/eip7805_readiness.rs b/beacon_node/beacon_chain/src/heze_readiness.rs similarity index 66% rename from beacon_node/beacon_chain/src/eip7805_readiness.rs rename to beacon_node/beacon_chain/src/heze_readiness.rs index 2250ab3281..23ae4db632 100644 --- a/beacon_node/beacon_chain/src/eip7805_readiness.rs +++ b/beacon_node/beacon_chain/src/heze_readiness.rs @@ -10,16 +10,16 @@ use std::fmt; use std::time::Duration; use types::*; -/// The time before the eip7805 fork when we will start issuing warnings about preparation. +/// The time before the heze fork when we will start issuing warnings about preparation. use super::bellatrix_readiness::SECONDS_IN_A_WEEK; -pub const EIP7805_READINESS_PREPARATION_SECONDS: u64 = SECONDS_IN_A_WEEK * 2; +pub const HEZE_READINESS_PREPARATION_SECONDS: u64 = SECONDS_IN_A_WEEK * 2; pub const ENGINE_CAPABILITIES_REFRESH_INTERVAL: u64 = 300; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] #[serde(tag = "type")] -pub enum Eip7805Readiness { - /// The execution engine is eip7805-enabled (as far as we can tell) +pub enum HezeReadiness { + /// The execution engine is heze-enabled (as far as we can tell) Ready, /// We are connected to an execution engine which doesn't support the V4 engine api methods V4MethodsNotSupported { error: String }, @@ -30,26 +30,26 @@ pub enum Eip7805Readiness { NoExecutionEndpoint, } -impl fmt::Display for Eip7805Readiness { +impl fmt::Display for HezeReadiness { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Eip7805Readiness::Ready => { - write!(f, "This node appears ready for Eip7805.") + HezeReadiness::Ready => { + write!(f, "This node appears ready for Heze.") } - Eip7805Readiness::ExchangeCapabilitiesFailed { error } => write!( + HezeReadiness::ExchangeCapabilitiesFailed { error } => write!( f, "Could not exchange capabilities with the \ execution endpoint: {}", error ), - Eip7805Readiness::NoExecutionEndpoint => write!( + HezeReadiness::NoExecutionEndpoint => write!( f, "The --execution-endpoint flag is not specified, this is a \ requirement post-merge" ), - Eip7805Readiness::V4MethodsNotSupported { error } => write!( + HezeReadiness::V4MethodsNotSupported { error } => write!( f, - "Execution endpoint does not support eip7805 methods: {}", + "Execution endpoint does not support heze methods: {}", error ), } @@ -57,23 +57,23 @@ impl fmt::Display for Eip7805Readiness { } impl BeaconChain { - /// Returns `true` if eip7805 epoch is set and Eip7805 fork has occurred or will - /// occur within `EIP7805_READINESS_PREPARATION_SECONDS` - pub fn is_time_to_prepare_for_eip7805(&self, current_slot: Slot) -> bool { - if let Some(eip7805_epoch) = self.spec.eip7805_fork_epoch { - let eip7805_slot = eip7805_epoch.start_slot(T::EthSpec::slots_per_epoch()); - let eip7805_readiness_preparation_slots = - EIP7805_READINESS_PREPARATION_SECONDS / self.spec.seconds_per_slot; - // Return `true` if eip7805 has happened or is within the preparation time. - current_slot + eip7805_readiness_preparation_slots > eip7805_slot + /// Returns `true` if heze epoch is set and Heze fork has occurred or will + /// occur within `HEZE_READINESS_PREPARATION_SECONDS` + pub fn is_time_to_prepare_for_heze(&self, current_slot: Slot) -> bool { + if let Some(heze_epoch) = self.spec.heze_fork_epoch { + let heze_slot = heze_epoch.start_slot(T::EthSpec::slots_per_epoch()); + let heze_readiness_preparation_slots = + HEZE_READINESS_PREPARATION_SECONDS / self.spec.seconds_per_slot; + // Return `true` if heze has happened or is within the preparation time. + current_slot + heze_readiness_preparation_slots > heze_slot } else { // The Electra fork epoch has not been defined yet, no need to prepare. false } } - /// Attempts to connect to the EL and confirm that it is ready for eip7805. - pub async fn check_eip7805_readiness(&self) -> Eip7805Readiness { + /// Attempts to connect to the EL and confirm that it is ready for heze. + pub async fn check_heze_readiness(&self) -> HezeReadiness { if let Some(el) = self.execution_layer.as_ref() { match el .get_engine_capabilities(Some(Duration::from_secs( @@ -83,7 +83,7 @@ impl BeaconChain { { Err(e) => { // The EL was either unreachable or responded with an error - Eip7805Readiness::ExchangeCapabilitiesFailed { + HezeReadiness::ExchangeCapabilitiesFailed { error: format!("{:?}", e), } } @@ -107,16 +107,16 @@ impl BeaconChain { } if all_good { - Eip7805Readiness::Ready + HezeReadiness::Ready } else { - Eip7805Readiness::V4MethodsNotSupported { + HezeReadiness::V4MethodsNotSupported { error: missing_methods, } } } } } else { - Eip7805Readiness::NoExecutionEndpoint + HezeReadiness::NoExecutionEndpoint } } } diff --git a/beacon_node/beacon_chain/src/kzg_utils.rs b/beacon_node/beacon_chain/src/kzg_utils.rs index b05a896777..9a8fe0feae 100644 --- a/beacon_node/beacon_chain/src/kzg_utils.rs +++ b/beacon_node/beacon_chain/src/kzg_utils.rs @@ -13,8 +13,9 @@ use types::data::{ use types::kzg_ext::KzgCommitments; use types::{ Blob, BlobSidecar, BlobSidecarList, ChainSpec, DataColumnSidecar, DataColumnSidecarFulu, - DataColumnSidecarGloas, DataColumnSidecarList, EthSpec, Hash256, KzgCommitment, KzgProof, - SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlindedBeaconBlock, Slot, + DataColumnSidecarGloas, DataColumnSidecarHeze, DataColumnSidecarList, EthSpec, Hash256, + KzgCommitment, KzgProof, SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlindedBeaconBlock, + Slot, }; /// Converts a blob ssz FixedVector to a reference to a fixed-size array @@ -80,11 +81,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::Gloas(_) | DataColumnSidecar::Heze(_) => { return Err(( Some(col_index), KzgError::InconsistentArrayLength( - "Gloas data columns require commitments from block".to_string(), + "Gloas/Heze data columns require commitments from block".to_string(), ), )); } @@ -274,7 +275,15 @@ pub fn blobs_to_data_column_sidecars( }) .collect::, KzgError>>()?; - if block.fork_name_unchecked().gloas_enabled() { + 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() { build_data_column_sidecars_gloas( signed_block_header.message.tree_hash_root(), block.slot(), @@ -394,7 +403,7 @@ pub(crate) fn build_data_column_sidecars_fulu( .fork_name_at_slot::(signed_block_header.message.slot) .gloas_enabled() { - return Err("Attempting to construct Fulu data columns post-Gloas".to_owned()); + return Err("Attempting to construct Fulu data columns post-Gloas/Heze".to_owned()); } let number_of_columns = E::number_of_columns(); @@ -519,6 +528,68 @@ pub(crate) fn build_data_column_sidecars_gloas( sidecars } +pub(crate) fn build_data_column_sidecars_heze( + beacon_block_root: Hash256, + slot: Slot, + blob_cells_and_proofs_vec: Vec, + spec: &ChainSpec, +) -> Result, String> { + if !spec.fork_name_at_slot::(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 = cell.to_vec(); + let cell = + Cell::::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>>, String> = columns + .into_iter() + .zip(column_kzg_proofs) + .enumerate() + .map( + |(index, (col, proofs))| -> Result>, String> { + Ok(Arc::new(DataColumnSidecar::Heze(DataColumnSidecarHeze { + index: index as u64, + column: DataColumn::::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( header: &PartialDataColumnHeader, blob_cells_and_proofs_vec: Vec>, @@ -629,7 +700,7 @@ pub fn reconstruct_blobs( // https://github.com/sigp/lighthouse/issues/7413 let num_of_blobs = first_data_column .kzg_commitments() - .map_err(|_| "Gloas blob reconstruction not yet supported".to_string())? + .map_err(|_| "Gloas/Heze blob reconstruction not yet supported".to_string())? .len(); (0..num_of_blobs).collect() } @@ -709,7 +780,7 @@ pub fn reconstruct_data_columns( .kzg_commitments() .map_err(|_| { KzgError::InconsistentArrayLength( - "Gloas data column reconstruction not yet supported".to_string(), + "Gloas/Heze data column reconstruction not yet supported".to_string(), ) })? .len(); @@ -751,6 +822,13 @@ pub fn reconstruct_data_columns( 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), } } diff --git a/beacon_node/beacon_chain/src/observed_data_sidecars.rs b/beacon_node/beacon_chain/src/observed_data_sidecars.rs index 2461c8115d..05cab4bbfb 100644 --- a/beacon_node/beacon_chain/src/observed_data_sidecars.rs +++ b/beacon_node/beacon_chain/src/observed_data_sidecars.rs @@ -265,8 +265,8 @@ mod tests { use bls::{FixedBytesExtended, Signature}; use std::sync::Arc; use types::{ - BeaconBlockHeader, DataColumnSidecarFulu, DataColumnSidecarGloas, ForkName, MainnetEthSpec, - SignedBeaconBlockHeader, + BeaconBlockHeader, DataColumnSidecarFulu, DataColumnSidecarGloas, DataColumnSidecarHeze, + ForkName, MainnetEthSpec, SignedBeaconBlockHeader, }; type E = MainnetEthSpec; @@ -320,13 +320,31 @@ 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> { + 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> { - if fork_name.gloas_enabled() { + if fork_name.heze_enabled() { + get_data_column_sidecar_heze(slot, Hash256::from_low_u64_be(key), index) + } else 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) diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index ffd27895cf..19a9496bd5 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -3,7 +3,10 @@ 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}; +use crate::kzg_utils::{ + build_data_column_sidecars_fulu, build_data_column_sidecars_gloas, + build_data_column_sidecars_heze, +}; use crate::observed_operations::ObservationOutcome; pub use crate::persisted_beacon_chain::PersistedBeaconChain; use crate::{BeaconBlockResponseWrapper, CustodyContext, get_block_root}; @@ -557,8 +560,8 @@ where genesis_time + spec.get_slot_duration().as_secs() * E::slots_per_epoch() * epoch.as_u64() }); - mock.server.execution_block_generator().eip7805_time = - spec.eip7805_fork_epoch.map(|epoch| { + mock.server.execution_block_generator().heze_time = + spec.heze_fork_epoch.map(|epoch| { genesis_time + spec.get_slot_duration().as_secs() * E::slots_per_epoch() * epoch.as_u64() }); mock.server.execution_block_generator().osaka_time = spec.fulu_fork_epoch.map(|epoch| { @@ -695,7 +698,7 @@ pub fn mock_execution_layer_from_parts( HARNESS_GENESIS_TIME + (spec.get_slot_duration().as_secs()) * E::slots_per_epoch() * epoch.as_u64() }); - let eip7805_time = spec.eip7805_fork_epoch.map(|epoch| { + let heze_time = spec.heze_fork_epoch.map(|epoch| { HARNESS_GENESIS_TIME + spec.get_slot_duration().as_secs() * E::slots_per_epoch() * epoch.as_u64() }); let osaka_time = spec.fulu_fork_epoch.map(|epoch| { @@ -706,6 +709,10 @@ pub fn mock_execution_layer_from_parts( HARNESS_GENESIS_TIME + (spec.get_slot_duration().as_secs()) * E::slots_per_epoch() * epoch.as_u64() }); + let heze_time = spec.heze_fork_epoch.map(|epoch| { + HARNESS_GENESIS_TIME + + (spec.get_slot_duration().as_secs()) * E::slots_per_epoch() * epoch.as_u64() + }); let kzg = get_kzg(&spec); @@ -714,9 +721,9 @@ pub fn mock_execution_layer_from_parts( shanghai_time, cancun_time, prague_time, - eip7805_time, osaka_time, amsterdam_time, + heze_time, Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()), spec, Some(kzg), @@ -3823,10 +3830,7 @@ pub fn generate_rand_block_and_blobs( SignedBeaconBlock::Fulu(SignedBeaconBlockFulu { ref mut message, .. }) => add_blob_transactions!(message, FullPayloadFulu, num_blobs, rng, fork_name), - SignedBeaconBlock::Eip7805(SignedBeaconBlockEip7805 { - ref mut message, .. - }) => add_blob_transactions!(message, FullPayloadEip7805, num_blobs, rng, fork_name), - // TODO(EIP-7732) Add `SignedBeaconBlock::Gloas` variant + // TODO(EIP-7732) Add `SignedBeaconBlock::Gloas` and `SignedBeaconBlock::Heze` variants _ => return (block, blob_sidecars), }; @@ -3876,7 +3880,51 @@ pub fn generate_data_column_sidecars_from_block( ) -> DataColumnSidecarList { // Load the precomputed column sidecar to avoid computing them for every block in the tests. // Then repeat the cells and proofs for every blob - if block.fork_name_unchecked().gloas_enabled() { + if block.fork_name_unchecked().heze_enabled() { + let kzg_commitments = &block + .message() + .body() + .signed_execution_payload_bid() + .expect("Heze block should have a payload bid") + .message + .blob_kzg_commitments; + if kzg_commitments.is_empty() { + return vec![]; + } + let num_blobs = kzg_commitments.len(); + let signed_block_header = block.signed_block_header(); + let template_data_columns = + RuntimeVariableList::>::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 = 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()); num_blobs]; + + 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() { let kzg_commitments = &block .message() .body() diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index 1b117c0ecb..f0761734b9 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -923,7 +923,7 @@ async fn invalid_signature_attester_slashing() { .push(attester_slashing.as_electra().unwrap().clone()) .expect("should update attester slashing"); } - BeaconBlockBodyRefMut::Eip7805(blk) => { + BeaconBlockBodyRefMut::Heze(blk) => { blk.attester_slashings .push(attester_slashing.as_electra().unwrap().clone()) .expect("should update attester slashing"); @@ -933,6 +933,11 @@ async fn invalid_signature_attester_slashing() { .push(attester_slashing.as_electra().unwrap().clone()) .expect("should update attester slashing"); } + BeaconBlockBodyRefMut::Heze(blk) => { + blk.attester_slashings + .push(attester_slashing.as_electra().unwrap().clone()) + .expect("should update attester slashing"); + } } snapshots[block_index].beacon_block = Arc::new(SignedBeaconBlock::from_block(block, signature)); @@ -992,7 +997,7 @@ async fn invalid_signature_attestation() { .attestations .get_mut(0) .map(|att| att.signature = junk_aggregate_signature()), - BeaconBlockBodyRefMut::Eip7805(blk) => blk + BeaconBlockBodyRefMut::Heze(blk) => blk .attestations .get_mut(0) .map(|att| att.signature = junk_aggregate_signature()), @@ -1000,6 +1005,10 @@ async fn invalid_signature_attestation() { .attestations .get_mut(0) .map(|att| att.signature = junk_aggregate_signature()), + BeaconBlockBodyRefMut::Heze(blk) => blk + .attestations + .get_mut(0) + .map(|att| att.signature = junk_aggregate_signature()), }; if block.body().attestations_len() > 0 { diff --git a/beacon_node/beacon_chain/tests/inclusion_list_verification.rs b/beacon_node/beacon_chain/tests/inclusion_list_verification.rs index 9084f031e7..e3fcb790af 100644 --- a/beacon_node/beacon_chain/tests/inclusion_list_verification.rs +++ b/beacon_node/beacon_chain/tests/inclusion_list_verification.rs @@ -19,15 +19,15 @@ static KEYPAIRS: LazyLock> = pub type E = MainnetEthSpec; -/// Returns a beacon chain harness for the eip7805 fork -fn get_harness_eip7805(validator_count: usize) -> BeaconChainHarness> { +/// Returns a beacon chain harness for the heze fork +fn get_harness_heze(validator_count: usize) -> BeaconChainHarness> { let mut spec = E::default_spec(); spec.altair_fork_epoch = Some(Epoch::new(0)); spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(0)); spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.electra_fork_epoch = Some(Epoch::new(0)); - spec.eip7805_fork_epoch = Some(Epoch::new(0)); + spec.heze_fork_epoch = Some(Epoch::new(0)); let spec = Arc::new(spec); let harness = BeaconChainHarness::builder(MainnetEthSpec) @@ -140,7 +140,7 @@ struct InclusionListGossipTester { impl InclusionListGossipTester { pub async fn new() -> Self { - let harness = get_harness_eip7805(VALIDATOR_COUNT); + let harness = get_harness_heze(VALIDATOR_COUNT); // Extend the chain out a few epochs so we have some chain depth to play with. harness diff --git a/beacon_node/client/src/notifier.rs b/beacon_node/client/src/notifier.rs index 8b00b591c5..9c9e0d05ec 100644 --- a/beacon_node/client/src/notifier.rs +++ b/beacon_node/client/src/notifier.rs @@ -554,16 +554,7 @@ fn methods_required_for_fork( missing_methods.push(ENGINE_NEW_PAYLOAD_V4); } } - // TODO(EIP7805) check capabilities - ForkName::Eip7805 => { - if !capabilities.get_payload_v5 { - missing_methods.push(ENGINE_GET_PAYLOAD_V5); - } - if !capabilities.new_payload_v4 { - missing_methods.push(ENGINE_NEW_PAYLOAD_V4); - } - } - ForkName::Gloas => { + ForkName::Gloas | ForkName::Heze => { if !capabilities.get_payload_v6 { missing_methods.push(ENGINE_GET_PAYLOAD_V6); } diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 02ecb92a81..0fb2ef42e8 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -26,7 +26,7 @@ pub use types::{ }; use types::{ ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb, - ExecutionPayloadEip7805, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, + ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeze, ExecutionRequests, KzgProofs, }; use types::{GRAFFITI_BYTES_LEN, Graffiti}; @@ -38,8 +38,8 @@ mod new_payload_request; pub use new_payload_request::{ NewPayloadRequest, NewPayloadRequestBellatrix, NewPayloadRequestCapella, - NewPayloadRequestDeneb, NewPayloadRequestEip7805, NewPayloadRequestElectra, - NewPayloadRequestFulu, NewPayloadRequestGloas, + NewPayloadRequestDeneb, NewPayloadRequestElectra, NewPayloadRequestFulu, + NewPayloadRequestGloas, NewPayloadRequestHeze, }; pub const LATEST_TAG: &str = "latest"; @@ -300,7 +300,7 @@ pub struct ProposeBlindedBlockResponse { } #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes(derive(Clone, Debug, PartialEq),), map_into(ExecutionPayload), map_ref_into(ExecutionPayloadRef), @@ -320,18 +320,18 @@ pub struct GetPayloadResponse { pub execution_payload: ExecutionPayloadDeneb, #[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))] pub execution_payload: ExecutionPayloadElectra, - #[superstruct(only(Eip7805), partial_getter(rename = "execution_payload_eip7805"))] - pub execution_payload: ExecutionPayloadEip7805, #[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))] pub execution_payload: ExecutionPayloadFulu, #[superstruct(only(Gloas), partial_getter(rename = "execution_payload_gloas"))] pub execution_payload: ExecutionPayloadGloas, + #[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))] + pub execution_payload: ExecutionPayloadHeze, pub block_value: Uint256, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] pub blobs_bundle: BlobsBundle, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze), partial_getter(copy))] pub should_override_builder: bool, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] pub requests: ExecutionRequests, } @@ -399,12 +399,6 @@ impl From> Some(inner.blobs_bundle), Some(inner.requests), ), - GetPayloadResponse::Eip7805(inner) => ( - ExecutionPayload::Eip7805(inner.execution_payload), - inner.block_value, - Some(inner.blobs_bundle), - Some(inner.requests), - ), GetPayloadResponse::Fulu(inner) => ( ExecutionPayload::Fulu(inner.execution_payload), inner.block_value, @@ -417,6 +411,12 @@ impl From> Some(inner.blobs_bundle), Some(inner.requests), ), + GetPayloadResponse::Heze(inner) => ( + ExecutionPayload::Heze(inner.execution_payload), + inner.block_value, + Some(inner.blobs_bundle), + Some(inner.requests), + ), } } } @@ -550,9 +550,9 @@ impl ExecutionPayloadBodyV1 { )) } } - ExecutionPayloadHeader::Eip7805(header) => { + ExecutionPayloadHeader::Heze(header) => { if let Some(withdrawals) = self.withdrawals { - Ok(ExecutionPayload::Eip7805(ExecutionPayloadEip7805 { + Ok(ExecutionPayload::Heze(ExecutionPayloadHeze { parent_hash: header.parent_hash, fee_recipient: header.fee_recipient, state_root: header.state_root, @@ -570,6 +570,9 @@ impl ExecutionPayloadBodyV1 { withdrawals, blob_gas_used: header.blob_gas_used, excess_blob_gas: header.excess_blob_gas, + // TODO(heze): block_access_list and slot_number are not available in ExecutionPayloadBodyV1 + block_access_list: Default::default(), + slot_number: Default::default(), })) } else { Err(format!( diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 3c7f2618c3..0a6262fd15 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -924,12 +924,12 @@ impl HttpJsonRpc { Ok(response.into()) } - // TODO(EIP7805) fix new payload if needed - pub async fn new_payload_v4_eip7805( + // TODO(HEZE) fix new payload if needed + pub async fn new_payload_v4_heze( &self, - new_payload_request_eip7805: NewPayloadRequestEip7805<'_, E>, + new_payload_request_heze: NewPayloadRequestHeze<'_, E>, ) -> Result { - let il_transactions: Vec = new_payload_request_eip7805 + let il_transactions: Vec = new_payload_request_heze .il_transactions .into_iter() .map(|tx| { @@ -939,21 +939,21 @@ impl HttpJsonRpc { .collect(); let params = json!([ - JsonExecutionPayload::Eip7805( - new_payload_request_eip7805 + JsonExecutionPayload::Heze( + new_payload_request_heze .execution_payload .clone() .try_into()? ), - new_payload_request_eip7805.versioned_hashes, - new_payload_request_eip7805.parent_beacon_block_root, - new_payload_request_eip7805 + new_payload_request_heze.versioned_hashes, + new_payload_request_heze.parent_beacon_block_root, + new_payload_request_heze .execution_requests .get_execution_requests_list(), il_transactions ]); - // TODO(eip7805) should be v5 i think + // TODO(heze) should be v5 i think let response: JsonPayloadStatusV1 = self .rpc_request( ENGINE_NEW_PAYLOAD_V4, @@ -994,6 +994,35 @@ impl HttpJsonRpc { Ok(response.into()) } + pub async fn new_payload_v5_heze( + &self, + new_payload_request_heze: NewPayloadRequestHeze<'_, E>, + ) -> Result { + let params = json!([ + JsonExecutionPayload::Heze( + new_payload_request_heze + .execution_payload + .clone() + .try_into()? + ), + new_payload_request_heze.versioned_hashes, + new_payload_request_heze.parent_beacon_block_root, + new_payload_request_heze + .execution_requests + .get_execution_requests_list(), + ]); + + let response: JsonPayloadStatusV1 = self + .rpc_request( + ENGINE_NEW_PAYLOAD_V5, + params, + ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + + Ok(response.into()) + } + pub async fn get_payload_v1( &self, payload_id: PayloadId, @@ -1103,8 +1132,8 @@ impl HttpJsonRpc { .try_into() .map_err(Error::BadResponse) } - ForkName::Eip7805 => { - let response: JsonGetPayloadResponseEip7805 = self + ForkName::Heze => { + let response: JsonGetPayloadResponseHeze = self .rpc_request( ENGINE_GET_PAYLOAD_V4, params, @@ -1112,7 +1141,7 @@ impl HttpJsonRpc { ) .await?; - JsonGetPayloadResponse::Eip7805(response) + JsonGetPayloadResponse::Heze(response) .try_into() .map_err(Error::BadResponse) } @@ -1143,15 +1172,15 @@ impl HttpJsonRpc { .try_into() .map_err(Error::BadResponse) } - ForkName::Eip7805 => { - let response: JsonGetPayloadResponseEip7805 = self + ForkName::Heze => { + let response: JsonGetPayloadResponseHeze = self .rpc_request( ENGINE_GET_PAYLOAD_V5, params, ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, ) .await?; - JsonGetPayloadResponse::Eip7805(response) + JsonGetPayloadResponse::Heze(response) .try_into() .map_err(Error::BadResponse) } @@ -1182,6 +1211,18 @@ impl HttpJsonRpc { .try_into() .map_err(Error::BadResponse) } + ForkName::Heze => { + let response: JsonGetPayloadResponseHeze = self + .rpc_request( + ENGINE_GET_PAYLOAD_V6, + params, + ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier, + ) + .await?; + JsonGetPayloadResponse::Heze(response) + .try_into() + .map_err(Error::BadResponse) + } _ => Err(Error::UnsupportedForkVariant(format!( "called get_payload_v6 with {}", fork_name @@ -1500,10 +1541,10 @@ impl HttpJsonRpc { Err(Error::RequiredMethodUnsupported("engine_newPayloadV4")) } } - // TODO(EIP7805) engine capabilties should be v5? - NewPayloadRequest::Eip7805(new_payload_request_eip7805) => { + // TODO(HEZE) engine capabilties should be v5? + NewPayloadRequest::Heze(new_payload_request_heze) => { if engine_capabilities.new_payload_v4 { - self.new_payload_v4_eip7805(new_payload_request_eip7805) + self.new_payload_v4_heze(new_payload_request_heze) .await } else { Err(Error::RequiredMethodUnsupported("engine_newPayloadV4")) @@ -1516,6 +1557,13 @@ impl HttpJsonRpc { Err(Error::RequiredMethodUnsupported("engine_newPayloadV5")) } } + NewPayloadRequest::Heze(new_payload_request_heze) => { + if engine_capabilities.new_payload_v5 { + self.new_payload_v5_heze(new_payload_request_heze).await + } else { + Err(Error::RequiredMethodUnsupported("engine_newPayloadV5")) + } + } } } @@ -1551,7 +1599,7 @@ impl HttpJsonRpc { Err(Error::RequiredMethodUnsupported("engine_getPayloadv4")) } } - ForkName::Eip7805 => { + ForkName::Heze => { if engine_capabilities.get_payload_v4 { self.get_payload_v4(fork_name, payload_id).await } else { @@ -1572,6 +1620,13 @@ impl HttpJsonRpc { Err(Error::RequiredMethodUnsupported("engine_getPayloadV6")) } } + ForkName::Heze => { + if engine_capabilities.get_payload_v6 { + self.get_payload_v6(fork_name, payload_id).await + } else { + Err(Error::RequiredMethodUnsupported("engine_getPayloadV6")) + } + } ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!( "called get_payload with {}", fork_name diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 9ab0c40e53..c0bf4cf829 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -64,7 +64,7 @@ pub struct JsonPayloadIdResponse { } #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive(Debug, PartialEq, Default, Serialize, Deserialize,), serde(bound = "E: EthSpec", rename_all = "camelCase"), @@ -99,18 +99,18 @@ pub struct JsonExecutionPayload { pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: Transactions, - #[superstruct(only(Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas, Heze))] pub withdrawals: VariableList, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] #[serde(with = "serde_utils::u64_hex_be")] pub blob_gas_used: u64, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] #[serde(with = "serde_utils::u64_hex_be")] pub excess_blob_gas: u64, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[serde(with = "ssz_types::serde_utils::hex_var_list")] pub block_access_list: VariableList, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[serde(with = "serde_utils::u64_hex_be")] pub slot_number: u64, } @@ -236,11 +236,11 @@ impl TryFrom> for JsonExecutionPayloadFulu TryFrom> for JsonExecutionPayloadEip7805 { +impl TryFrom> for JsonExecutionPayloadGloas { type Error = ssz_types::Error; - fn try_from(payload: ExecutionPayloadEip7805) -> Result { - Ok(JsonExecutionPayloadEip7805 { + fn try_from(payload: ExecutionPayloadGloas) -> Result { + Ok(JsonExecutionPayloadGloas { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, state_root: payload.state_root, @@ -258,15 +258,17 @@ impl TryFrom> for JsonExecutionPayloadEip withdrawals: withdrawals_to_json(payload.withdrawals)?, blob_gas_used: payload.blob_gas_used, excess_blob_gas: payload.excess_blob_gas, + block_access_list: payload.block_access_list, + slot_number: payload.slot_number.into(), }) } } -impl TryFrom> for JsonExecutionPayloadGloas { +impl TryFrom> for JsonExecutionPayloadHeze { type Error = ssz_types::Error; - fn try_from(payload: ExecutionPayloadGloas) -> Result { - Ok(JsonExecutionPayloadGloas { + fn try_from(payload: ExecutionPayloadHeze) -> Result { + Ok(JsonExecutionPayloadHeze { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, state_root: payload.state_root, @@ -308,12 +310,12 @@ impl TryFrom> for JsonExecutionPayload { Ok(JsonExecutionPayload::Electra(payload.try_into()?)) } ExecutionPayload::Fulu(payload) => Ok(JsonExecutionPayload::Fulu(payload.try_into()?)), - ExecutionPayload::Eip7805(payload) => { - Ok(JsonExecutionPayload::Eip7805(payload.try_into()?)) - } ExecutionPayload::Gloas(payload) => { Ok(JsonExecutionPayload::Gloas(payload.try_into()?)) } + ExecutionPayload::Heze(payload) => { + Ok(JsonExecutionPayload::Heze(payload.try_into()?)) + } } } } @@ -440,11 +442,11 @@ impl TryFrom> for ExecutionPayloadFulu TryFrom> for ExecutionPayloadEip7805 { +impl TryFrom> for ExecutionPayloadGloas { type Error = ssz_types::Error; - fn try_from(payload: JsonExecutionPayloadEip7805) -> Result { - Ok(ExecutionPayloadEip7805 { + fn try_from(payload: JsonExecutionPayloadGloas) -> Result { + Ok(ExecutionPayloadGloas { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, state_root: payload.state_root, @@ -462,15 +464,17 @@ impl TryFrom> for ExecutionPayloadEip withdrawals: withdrawals_from_json(payload.withdrawals)?, blob_gas_used: payload.blob_gas_used, excess_blob_gas: payload.excess_blob_gas, + block_access_list: payload.block_access_list, + slot_number: payload.slot_number.into(), }) } } -impl TryFrom> for ExecutionPayloadGloas { +impl TryFrom> for ExecutionPayloadHeze { type Error = ssz_types::Error; - fn try_from(payload: JsonExecutionPayloadGloas) -> Result { - Ok(ExecutionPayloadGloas { + fn try_from(payload: JsonExecutionPayloadHeze) -> Result { + Ok(ExecutionPayloadHeze { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, state_root: payload.state_root, @@ -512,12 +516,12 @@ impl TryFrom> for ExecutionPayload { Ok(ExecutionPayload::Electra(payload.try_into()?)) } JsonExecutionPayload::Fulu(payload) => Ok(ExecutionPayload::Fulu(payload.try_into()?)), - JsonExecutionPayload::Eip7805(payload) => { - Ok(ExecutionPayload::Eip7805(payload.try_into()?)) - } JsonExecutionPayload::Gloas(payload) => { Ok(ExecutionPayload::Gloas(payload.try_into()?)) } + JsonExecutionPayload::Heze(payload) => { + Ok(ExecutionPayload::Heze(payload.try_into()?)) + } } } } @@ -631,7 +635,7 @@ impl TryFrom for ExecutionRequests { } #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive(Debug, PartialEq, Serialize, Deserialize), serde(bound = "E: EthSpec", rename_all = "camelCase") @@ -655,17 +659,17 @@ pub struct JsonGetPayloadResponse { pub execution_payload: JsonExecutionPayloadElectra, #[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))] pub execution_payload: JsonExecutionPayloadFulu, - #[superstruct(only(Eip7805), partial_getter(rename = "execution_payload_eip7805"))] - pub execution_payload: JsonExecutionPayloadEip7805, #[superstruct(only(Gloas), partial_getter(rename = "execution_payload_gloas"))] pub execution_payload: JsonExecutionPayloadGloas, + #[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))] + pub execution_payload: JsonExecutionPayloadHeze, #[serde(with = "serde_utils::u256_hex_be")] pub block_value: Uint256, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] pub blobs_bundle: JsonBlobsBundleV1, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] pub should_override_builder: bool, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] pub execution_requests: JsonExecutionRequests, } @@ -723,8 +727,8 @@ impl TryFrom> for GetPayloadResponse { })?, })) } - JsonGetPayloadResponse::Eip7805(response) => { - Ok(GetPayloadResponse::Eip7805(GetPayloadResponseEip7805 { + JsonGetPayloadResponse::Gloas(response) => { + Ok(GetPayloadResponse::Gloas(GetPayloadResponseGloas { execution_payload: response.execution_payload.try_into().map_err(|e| { format!("Failed to convert json to execution payload: {:?}", e) })?, @@ -736,8 +740,8 @@ impl TryFrom> for GetPayloadResponse { })?, })) } - JsonGetPayloadResponse::Gloas(response) => { - Ok(GetPayloadResponse::Gloas(GetPayloadResponseGloas { + JsonGetPayloadResponse::Heze(response) => { + Ok(GetPayloadResponse::Heze(GetPayloadResponseHeze { execution_payload: response.execution_payload.try_into().map_err(|e| { format!("Failed to convert json to execution payload: {:?}", e) })?, diff --git a/beacon_node/execution_layer/src/engine_api/new_payload_request.rs b/beacon_node/execution_layer/src/engine_api/new_payload_request.rs index b025bf7a69..6130f9511e 100644 --- a/beacon_node/execution_layer/src/engine_api/new_payload_request.rs +++ b/beacon_node/execution_layer/src/engine_api/new_payload_request.rs @@ -9,12 +9,12 @@ use types::{ }; use types::{ ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb, - ExecutionPayloadEip7805, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, + ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeze, ExecutionRequests, Transactions, }; #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes(derive(Clone, Debug, PartialEq),), map_into(ExecutionPayload), map_ref_into(ExecutionPayloadRef), @@ -42,17 +42,17 @@ pub struct NewPayloadRequest<'block, E: EthSpec> { pub execution_payload: &'block ExecutionPayloadElectra, #[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))] pub execution_payload: &'block ExecutionPayloadFulu, - #[superstruct(only(Eip7805), partial_getter(rename = "execution_payload_eip7805"))] - pub execution_payload: &'block ExecutionPayloadEip7805, #[superstruct(only(Gloas), partial_getter(rename = "execution_payload_gloas"))] pub execution_payload: &'block ExecutionPayloadGloas, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))] + pub execution_payload: &'block ExecutionPayloadHeze, + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] pub versioned_hashes: Vec, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze))] pub parent_beacon_block_root: Hash256, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] pub execution_requests: &'block ExecutionRequests, - #[superstruct(only(Eip7805, Gloas))] + #[superstruct(only(Heze, Gloas))] pub il_transactions: Transactions, } @@ -63,9 +63,9 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> { Self::Capella(payload) => payload.execution_payload.parent_hash, Self::Deneb(payload) => payload.execution_payload.parent_hash, Self::Electra(payload) => payload.execution_payload.parent_hash, - Self::Eip7805(payload) => payload.execution_payload.parent_hash, Self::Fulu(payload) => payload.execution_payload.parent_hash, Self::Gloas(payload) => payload.execution_payload.parent_hash, + Self::Heze(payload) => payload.execution_payload.parent_hash, } } @@ -75,9 +75,9 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> { Self::Capella(payload) => payload.execution_payload.block_hash, Self::Deneb(payload) => payload.execution_payload.block_hash, Self::Electra(payload) => payload.execution_payload.block_hash, - Self::Eip7805(payload) => payload.execution_payload.block_hash, Self::Fulu(payload) => payload.execution_payload.block_hash, Self::Gloas(payload) => payload.execution_payload.block_hash, + Self::Heze(payload) => payload.execution_payload.block_hash, } } @@ -87,9 +87,9 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> { Self::Capella(payload) => payload.execution_payload.block_number, Self::Deneb(payload) => payload.execution_payload.block_number, Self::Electra(payload) => payload.execution_payload.block_number, - Self::Eip7805(payload) => payload.execution_payload.block_number, Self::Fulu(payload) => payload.execution_payload.block_number, Self::Gloas(payload) => payload.execution_payload.block_number, + Self::Heze(payload) => payload.execution_payload.block_number, } } @@ -99,9 +99,9 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> { Self::Capella(request) => ExecutionPayloadRef::Capella(request.execution_payload), Self::Deneb(request) => ExecutionPayloadRef::Deneb(request.execution_payload), Self::Electra(request) => ExecutionPayloadRef::Electra(request.execution_payload), - Self::Eip7805(request) => ExecutionPayloadRef::Eip7805(request.execution_payload), Self::Fulu(request) => ExecutionPayloadRef::Fulu(request.execution_payload), Self::Gloas(request) => ExecutionPayloadRef::Gloas(request.execution_payload), + Self::Heze(request) => ExecutionPayloadRef::Heze(request.execution_payload), } } @@ -113,9 +113,9 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> { Self::Capella(request) => ExecutionPayload::Capella(request.execution_payload.clone()), Self::Deneb(request) => ExecutionPayload::Deneb(request.execution_payload.clone()), Self::Electra(request) => ExecutionPayload::Electra(request.execution_payload.clone()), - Self::Eip7805(request) => ExecutionPayload::Eip7805(request.execution_payload.clone()), Self::Fulu(request) => ExecutionPayload::Fulu(request.execution_payload.clone()), Self::Gloas(request) => ExecutionPayload::Gloas(request.execution_payload.clone()), + Self::Heze(request) => ExecutionPayload::Heze(request.execution_payload.clone()), } } @@ -232,18 +232,6 @@ impl<'a, E: EthSpec> NewPayloadRequest<'a, E> { parent_beacon_block_root: block_ref.parent_root, execution_requests: &block_ref.body.execution_requests, })), - BeaconBlockRef::Eip7805(block_ref) => Ok(Self::Eip7805(NewPayloadRequestEip7805 { - execution_payload: &block_ref.body.execution_payload.execution_payload, - versioned_hashes: block_ref - .body - .blob_kzg_commitments - .iter() - .map(kzg_commitment_to_versioned_hash) - .collect(), - parent_beacon_block_root: block_ref.parent_root, - execution_requests: &block_ref.body.execution_requests, - il_transactions, - })), _ => Err(BeaconStateError::IncorrectStateVariant), } } @@ -298,19 +286,9 @@ impl<'a, E: EthSpec> TryFrom> for NewPayloadRequest<'a, E> parent_beacon_block_root: block_ref.parent_root, execution_requests: &block_ref.body.execution_requests, })), - BeaconBlockRef::Eip7805(block_ref) => Ok(Self::Eip7805(NewPayloadRequestEip7805 { - execution_payload: &block_ref.body.execution_payload.execution_payload, - versioned_hashes: block_ref - .body - .blob_kzg_commitments - .iter() - .map(kzg_commitment_to_versioned_hash) - .collect(), - parent_beacon_block_root: block_ref.parent_root, - execution_requests: &block_ref.body.execution_requests, - il_transactions: vec![].try_into()?, - })), - BeaconBlockRef::Gloas(_) => Err(Self::Error::IncorrectStateVariant), + BeaconBlockRef::Gloas(_) | BeaconBlockRef::Heze(_) => { + Err(Self::Error::IncorrectStateVariant) + } } } } @@ -330,7 +308,7 @@ impl<'a, E: EthSpec> TryFrom> for NewPayloadRequest<' })), ExecutionPayloadRef::Deneb(_) => Err(Self::Error::IncorrectStateVariant), ExecutionPayloadRef::Electra(_) => Err(Self::Error::IncorrectStateVariant), - ExecutionPayloadRef::Eip7805(_) => Err(Self::Error::IncorrectStateVariant), + ExecutionPayloadRef::Heze(_) => Err(Self::Error::IncorrectStateVariant), ExecutionPayloadRef::Fulu(_) => Err(Self::Error::IncorrectStateVariant), //TODO(EIP7732): Probably time to just get rid of this ExecutionPayloadRef::Gloas(_) => Err(Self::Error::IncorrectStateVariant), diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index a46ea4b7bb..4c6e286b31 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -45,6 +45,7 @@ use tokio_stream::wrappers::WatchStream; use tracing::{Instrument, debug, debug_span, error, info, instrument, warn}; use tree_hash::TreeHash; use types::ExecutionPayloadGloas; +use types::ExecutionPayloadHeze; use types::builder::BuilderBid; use types::execution::BlockProductionVersion; use types::kzg_ext::KzgCommitments; @@ -54,7 +55,7 @@ use types::{ }; use types::{ BeaconStateError, BlindedPayload, ChainSpec, Epoch, ExecPayload, ExecutionPayloadBellatrix, - ExecutionPayloadCapella, ExecutionPayloadEip7805, ExecutionPayloadElectra, + ExecutionPayloadCapella, ExecutionPayloadElectra, ExecutionPayloadFulu, FullPayload, ProposerPreparationData, Slot, }; @@ -119,8 +120,8 @@ impl TryFrom> for ProvenancedPayload BlockProposalContents::PayloadAndBlobs { - payload: ExecutionPayloadHeader::Eip7805(builder_bid.header).into(), + BuilderBid::Heze(builder_bid) => BlockProposalContents::PayloadAndBlobs { + payload: ExecutionPayloadHeader::Heze(builder_bid.header).into(), block_value: builder_bid.value, kzg_commitments: builder_bid.blob_kzg_commitments, blobs_and_proofs: None, @@ -237,6 +238,26 @@ impl From> for BlockProposalContentsGloas } } +pub struct BlockProposalContentsHeze { + pub payload: ExecutionPayloadHeze, + pub payload_value: Uint256, + pub blob_kzg_commitments: KzgCommitments, + pub blobs_and_proofs: (BlobsList, KzgProofs), + pub execution_requests: ExecutionRequests, +} + +impl From> for BlockProposalContentsHeze { + fn from(response: GetPayloadResponseHeze) -> Self { + Self { + payload: response.execution_payload, + payload_value: response.block_value, + blob_kzg_commitments: response.blobs_bundle.commitments, + blobs_and_proofs: (response.blobs_bundle.blobs, response.blobs_bundle.proofs), + execution_requests: response.requests, + } + } +} + pub enum BlockProposalContents> { Payload { payload: Payload, @@ -948,6 +969,44 @@ impl ExecutionLayer { Ok(payload_response.into()) } + /// Maps to the `engine_getPayload` JSON-RPC call for post-Heze payload construction. + /// + /// However, it will attempt to call `self.prepare_payload` if it cannot find an existing + /// payload id for the given parameters. + /// + /// ## Fallback Behavior + /// + /// The result will be returned from the first node that returns successfully. No more nodes + /// will be contacted. + #[instrument(level = "debug", skip_all)] + pub async fn get_payload_heze( + &self, + payload_parameters: PayloadParameters<'_>, + ) -> Result, Error> { + let payload_response_type = self.get_full_payload_caching(payload_parameters).await?; + let GetPayloadResponseType::Full(payload_response) = payload_response_type else { + return Err(Error::Unexpected( + "get_payload_heze should never return a blinded payload".to_owned(), + )); + }; + let GetPayloadResponse::Heze(payload_response) = payload_response else { + return Err(Error::Unexpected( + "get_payload_heze should always return a heze `GetPayloadResponse` variant" + .to_owned(), + )); + }; + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, + &[metrics::SUCCESS], + ); + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, + &[metrics::LOCAL], + ); + + Ok(payload_response.into()) + } + /// Maps to the `engine_getPayload` JSON-RPC call. /// /// However, it will attempt to call `self.prepare_payload` if it cannot find an existing @@ -1702,7 +1761,7 @@ impl ExecutionLayer { ForkName::Capella => ExecutionPayloadCapella::default().into(), ForkName::Deneb => ExecutionPayloadDeneb::default().into(), ForkName::Electra => ExecutionPayloadElectra::default().into(), - ForkName::Eip7805 => ExecutionPayloadEip7805::default().into(), + ForkName::Heze => ExecutionPayloadHeze::default().into(), ForkName::Fulu => ExecutionPayloadFulu::default().into(), ForkName::Base | ForkName::Altair => { return Err(Error::InvalidForkForPayload); @@ -1710,6 +1769,9 @@ impl ExecutionLayer { ForkName::Gloas => { return Err(Error::InvalidForkForPayload); } + ForkName::Heze => { + return Err(Error::InvalidForkForPayload); + } }; return Ok(Some(payload)); } diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index 2e9da55439..449cfb07c6 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -25,9 +25,9 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use types::{ Blob, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadBellatrix, - ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadEip7805, - ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeader, - ExecutionRequests, ForkName, Hash256, KzgProofs, Transaction, Transactions, Uint256, + ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu, + ExecutionPayloadGloas, ExecutionPayloadHeader, ExecutionPayloadHeze, ExecutionRequests, + ForkName, Hash256, KzgProofs, Transaction, Transactions, Uint256, }; const TEST_BLOB_BUNDLE: &[u8] = include_bytes!("fixtures/mainnet/test_blobs_bundle.ssz"); @@ -154,8 +154,8 @@ pub struct ExecutionBlockGenerator { pub cancun_time: Option, // deneb pub prague_time: Option, // electra pub osaka_time: Option, // fulu - pub eip7805_time: Option, // eip7805 pub amsterdam_time: Option, // gloas + pub heze_time: Option, // heze /* * deneb stuff */ @@ -184,9 +184,9 @@ impl ExecutionBlockGenerator { shanghai_time: Option, cancun_time: Option, prague_time: Option, - eip7805_time: Option, osaka_time: Option, amsterdam_time: Option, + heze_time: Option, kzg: Option>, ) -> Self { let mut generator = Self { @@ -204,9 +204,9 @@ impl ExecutionBlockGenerator { shanghai_time, cancun_time, prague_time, - eip7805_time, osaka_time, amsterdam_time, + heze_time, blobs_bundles: <_>::default(), kzg, rng: make_rng(), @@ -258,8 +258,9 @@ impl ExecutionBlockGenerator { pub fn get_fork_at_timestamp(&self, timestamp: u64) -> ForkName { let forks = [ + (self.heze_time, ForkName::Heze), (self.amsterdam_time, ForkName::Gloas), - (self.eip7805_time, ForkName::Eip7805), + (self.heze_time, ForkName::Heze), (self.osaka_time, ForkName::Fulu), (self.prague_time, ForkName::Electra), (self.cancun_time, ForkName::Deneb), @@ -758,7 +759,10 @@ impl ExecutionBlockGenerator { blob_gas_used: 0, excess_blob_gas: 0, }), - ForkName::Eip7805 => ExecutionPayload::Eip7805(ExecutionPayloadEip7805 { + _ => unreachable!(), + }, + PayloadAttributes::V4(pa) => match self.get_fork_at_timestamp(pa.timestamp) { + ForkName::Gloas => ExecutionPayload::Gloas(ExecutionPayloadGloas { parent_hash: head_block_hash, fee_recipient: pa.suggested_fee_recipient, receipts_root: Hash256::repeat_byte(42), @@ -769,18 +773,17 @@ impl ExecutionBlockGenerator { gas_limit: DEFAULT_GAS_LIMIT, gas_used: GAS_USED, timestamp: pa.timestamp, - extra_data: mock_el_extra_data::(), + extra_data: "block gen was here".as_bytes().to_vec().try_into().unwrap(), base_fee_per_gas: Uint256::from(1u64), block_hash: ExecutionBlockHash::zero(), transactions: vec![].try_into().unwrap(), withdrawals: pa.withdrawals.clone().try_into().unwrap(), blob_gas_used: 0, excess_blob_gas: 0, + block_access_list: VariableList::empty(), + slot_number: pa.slot_number.into(), }), - _ => unreachable!(), - }, - PayloadAttributes::V4(pa) => match self.get_fork_at_timestamp(pa.timestamp) { - ForkName::Gloas => ExecutionPayload::Gloas(ExecutionPayloadGloas { + ForkName::Heze => ExecutionPayload::Heze(ExecutionPayloadHeze { parent_hash: head_block_hash, fee_recipient: pa.suggested_fee_recipient, receipts_root: Hash256::repeat_byte(42), @@ -978,8 +981,8 @@ pub fn generate_genesis_header(spec: &ChainSpec) -> Option { - let mut header = ExecutionPayloadHeader::Eip7805(<_>::default()); + ForkName::Heze => { + let mut header = ExecutionPayloadHeader::Heze(<_>::default()); *header.block_hash_mut() = genesis_block_hash.unwrap_or_default(); *header.transactions_root_mut() = empty_transactions_root; Some(header) @@ -998,6 +1001,14 @@ pub fn generate_genesis_header(spec: &ChainSpec) -> Option { + // TODO(heze): we are using a Fulu header for now, but this gets fixed up by the + // genesis builder anyway which translates it to bid/latest_block_hash. + let mut header = ExecutionPayloadHeader::Fulu(<_>::default()); + *header.block_hash_mut() = genesis_block_hash.unwrap_or_default(); + *header.transactions_root_mut() = empty_transactions_root; + Some(header) + } } } diff --git a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs index 816cec9760..1cba1d1726 100644 --- a/beacon_node/execution_layer/src/test_utils/handle_rpc.rs +++ b/beacon_node/execution_layer/src/test_utils/handle_rpc.rs @@ -127,9 +127,16 @@ pub async fn handle_rpc( .map(|jep| JsonExecutionPayload::Electra(jep)) }) .map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?, - ENGINE_NEW_PAYLOAD_V5 => get_param::>(params, 0) - .map(|jep| JsonExecutionPayload::Gloas(jep)) - .map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?, + ENGINE_NEW_PAYLOAD_V5 => { + // Try Heze first, fall back to Gloas + get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::Heze(jep)) + .or_else(|_| { + get_param::>(params, 0) + .map(|jep| JsonExecutionPayload::Gloas(jep)) + }) + .map_err(|s| (s, BAD_PARAMS_ERROR_CODE))? + } _ => unreachable!(), }; @@ -193,7 +200,7 @@ pub async fn handle_rpc( )); } } - ForkName::Electra | ForkName::Fulu | ForkName::Eip7805 | ForkName::Gloas => { + ForkName::Electra | ForkName::Fulu | ForkName::Heze | ForkName::Gloas => { if method == ENGINE_NEW_PAYLOAD_V1 || method == ENGINE_NEW_PAYLOAD_V2 || method == ENGINE_NEW_PAYLOAD_V3 @@ -239,6 +246,14 @@ pub async fn handle_rpc( )); } } + ForkName::Heze => { + if method != ENGINE_NEW_PAYLOAD_V5 { + return Err(( + format!("{} called after Heze fork!", method), + GENERIC_ERROR_CODE, + )); + } + } _ => unreachable!(), }; @@ -377,6 +392,24 @@ pub async fn handle_rpc( )); } + // validate method called correctly according to heze fork time + if ctx + .execution_block_generator + .read() + .get_fork_at_timestamp(response.timestamp()) + == ForkName::Heze + && (method == ENGINE_GET_PAYLOAD_V1 + || method == ENGINE_GET_PAYLOAD_V2 + || method == ENGINE_GET_PAYLOAD_V3 + || method == ENGINE_GET_PAYLOAD_V4 + || method == ENGINE_GET_PAYLOAD_V5) + { + return Err(( + format!("{} called after Heze fork!", method), + FORK_REQUEST_MISMATCH_ERROR_CODE, + )); + } + match method { ENGINE_GET_PAYLOAD_V1 => Ok(serde_json::to_value( JsonExecutionPayload::try_from(response).unwrap(), @@ -466,8 +499,8 @@ pub async fn handle_rpc( }) .unwrap() } - JsonExecutionPayload::Eip7805(execution_payload) => { - serde_json::to_value(JsonGetPayloadResponseEip7805 { + JsonExecutionPayload::Heze(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseHeze { execution_payload, block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI), blobs_bundle: maybe_blobs @@ -503,6 +536,23 @@ pub async fn handle_rpc( }) .unwrap() } + JsonExecutionPayload::Heze(execution_payload) => { + serde_json::to_value(JsonGetPayloadResponseHeze { + execution_payload, + block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI), + blobs_bundle: maybe_blobs + .ok_or(( + "No blobs returned despite V6 Payload".to_string(), + GENERIC_ERROR_CODE, + ))? + .into(), + should_override_builder: false, + execution_requests: maybe_execution_requests + .unwrap_or_default() + .into(), + }) + .unwrap() + } _ => unreachable!(), }) } @@ -649,7 +699,7 @@ pub async fn handle_rpc( ForkName::Deneb | ForkName::Electra | ForkName::Fulu - | ForkName::Eip7805 + | ForkName::Heze | ForkName::Gloas => { if method == ENGINE_FORKCHOICE_UPDATED_V1 { return Err(( @@ -672,6 +722,14 @@ pub async fn handle_rpc( )); } } + ForkName::Heze => { + if method != ENGINE_FORKCHOICE_UPDATED_V4 { + return Err(( + format!("{} called after Heze fork! Use V4.", method), + FORK_REQUEST_MISMATCH_ERROR_CODE, + )); + } + } _ => unreachable!(), }; } diff --git a/beacon_node/execution_layer/src/test_utils/mock_builder.rs b/beacon_node/execution_layer/src/test_utils/mock_builder.rs index 72b26d68ea..984f81ed92 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_builder.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_builder.rs @@ -30,7 +30,7 @@ use tracing::{debug, error, info, warn}; use tree_hash::TreeHash; use types::ExecutionBlockHash; use types::builder::{ - BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidEip7805, + BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidHeze, BuilderBidElectra, BuilderBidFulu, SignedBuilderBid, }; use types::{ @@ -114,7 +114,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.fee_recipient = fee_recipient; } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.fee_recipient = fee_recipient; } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -137,7 +137,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.gas_limit = gas_limit; } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.gas_limit = gas_limit; } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -164,7 +164,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.parent_hash = ExecutionBlockHash::from_root(parent_hash); } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.parent_hash = ExecutionBlockHash::from_root(parent_hash); } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -187,7 +187,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.prev_randao = prev_randao; } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.prev_randao = prev_randao; } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -210,7 +210,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.block_number = block_number; } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.block_number = block_number; } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -233,7 +233,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.timestamp = timestamp; } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.timestamp = timestamp; } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -256,7 +256,7 @@ impl BidStuff for BuilderBid { ExecutionPayloadHeaderRefMut::Electra(header) => { header.withdrawals_root = withdrawals_root; } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.withdrawals_root = withdrawals_root; } ExecutionPayloadHeaderRefMut::Fulu(header) => { @@ -291,7 +291,7 @@ impl BidStuff for BuilderBid { header.extra_data = extra_data; header.block_hash = ExecutionBlockHash::from_root(header.tree_hash_root()); } - ExecutionPayloadHeaderRefMut::Eip7805(header) => { + ExecutionPayloadHeaderRefMut::Heze(header) => { header.extra_data = extra_data; header.block_hash = ExecutionBlockHash::from_root(header.tree_hash_root()); } @@ -493,9 +493,6 @@ impl MockBuilder { SignedBlindedBeaconBlock::Electra(block) => { block.message.body.execution_payload.tree_hash_root() } - SignedBlindedBeaconBlock::Eip7805(block) => { - block.message.body.execution_payload.tree_hash_root() - } SignedBlindedBeaconBlock::Fulu(block) => { block.message.body.execution_payload.tree_hash_root() } @@ -503,6 +500,10 @@ impl MockBuilder { // TODO(EIP7732) Check if this is how we want to do error handling for gloas return Err("invalid fork".to_string()); } + SignedBlindedBeaconBlock::Heze(_) => { + // TODO(EIP7732) Check if this is how we want to do error handling for heze + return Err("invalid fork".to_string()); + } }; let block_hash = block .message() @@ -621,6 +622,10 @@ impl MockBuilder { // TODO(EIP7732) Check if this is how we want to do error handling for gloas return Err("invalid fork".to_string()); } + ForkName::Heze => { + // TODO(EIP7732) Check if this is how we want to do error handling for heze + return Err("invalid fork".to_string()); + } ForkName::Fulu => BuilderBid::Fulu(BuilderBidFulu { header: payload .as_fulu() @@ -633,9 +638,9 @@ impl MockBuilder { pubkey: self.builder_sk.public_key().compress(), execution_requests: maybe_requests.unwrap_or_default(), }), - ForkName::Eip7805 => BuilderBid::Eip7805(BuilderBidEip7805 { + ForkName::Heze => BuilderBid::Heze(BuilderBidHeze { header: payload - .as_eip7805() + .as_heze() .map_err(|_| "incorrect payload variant".to_string())? .into(), blob_kzg_commitments: maybe_blobs_bundle @@ -944,17 +949,15 @@ impl MockBuilder { None, None, ), - ForkName::Deneb | ForkName::Electra | ForkName::Fulu | ForkName::Eip7805 => { - PayloadAttributes::new( - timestamp, - *prev_randao, - fee_recipient, - expected_withdrawals, - Some(head_block_root), - None, - ) - } - ForkName::Gloas => PayloadAttributes::new( + ForkName::Deneb | ForkName::Electra | ForkName::Fulu => PayloadAttributes::new( + timestamp, + *prev_randao, + fee_recipient, + expected_withdrawals, + Some(head_block_root), + None, + ), + ForkName::Gloas | ForkName::Heze => PayloadAttributes::new( timestamp, *prev_randao, fee_recipient, diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index 0007900f8c..e0cc1ef5f2 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -37,9 +37,9 @@ impl MockExecutionLayer { shanghai_time: Option, cancun_time: Option, prague_time: Option, - eip7805_time: Option, osaka_time: Option, amsterdam_time: Option, + heze_time: Option, jwt_key: Option, spec: Arc, kzg: Option>, @@ -53,9 +53,9 @@ impl MockExecutionLayer { shanghai_time, cancun_time, prague_time, - eip7805_time, osaka_time, amsterdam_time, + heze_time, kzg, ); diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index 5c2efb4689..4689e0a07d 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -85,9 +85,9 @@ pub struct MockExecutionConfig { pub shanghai_time: Option, pub cancun_time: Option, pub prague_time: Option, - pub eip7805_time: Option, pub osaka_time: Option, pub amsterdam_time: Option, + pub heze_time: Option, } impl Default for MockExecutionConfig { @@ -98,9 +98,9 @@ impl Default for MockExecutionConfig { shanghai_time: None, cancun_time: None, prague_time: None, - eip7805_time: None, osaka_time: None, amsterdam_time: None, + heze_time: None, } } } @@ -120,9 +120,9 @@ impl MockServer { None, // FIXME(capella): should this be the default? None, // FIXME(deneb): should this be the default? None, // FIXME(electra): should this be the default? - None, None, // FIXME(fulu): should this be the default? None, // FIXME(gloas): should this be the default? + None, // FIXME(heze): should this be the default? None, ) } @@ -139,9 +139,9 @@ impl MockServer { shanghai_time, cancun_time, prague_time, - eip7805_time, osaka_time, amsterdam_time, + heze_time, } = config; let last_echo_request = Arc::new(RwLock::new(None)); let preloaded_responses = Arc::new(Mutex::new(vec![])); @@ -149,9 +149,9 @@ impl MockServer { shanghai_time, cancun_time, prague_time, - eip7805_time, osaka_time, amsterdam_time, + heze_time, kzg, ); @@ -211,9 +211,9 @@ impl MockServer { shanghai_time: Option, cancun_time: Option, prague_time: Option, - eip7805_time: Option, osaka_time: Option, amsterdam_time: Option, + heze_time: Option, kzg: Option>, ) -> Self { Self::new_with_config( @@ -224,9 +224,9 @@ impl MockServer { shanghai_time, cancun_time, prague_time, - eip7805_time, osaka_time, amsterdam_time, + heze_time, }, kzg, ) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 53311cbd22..65283f2c82 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -2621,7 +2621,7 @@ pub fn serve( task_spawner_filter.clone(), ); - // TODO(eip7805) update endpoint def + // TODO(heze) update endpoint def // POST validator/duties/inclusion_list/{epoch} let post_validator_duties_inclusion_list = eth_v1 .clone() @@ -2659,7 +2659,7 @@ pub fn serve( task_spawner_filter.clone(), ); - // TODO(EIP7805) update endpoint definition format + // TODO(HEZE) update endpoint definition format // GET validator/inclusion_list?slot let get_validator_inclusion_list = eth_v1 .clone() diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index 15f61537a0..d82f291a1c 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -385,6 +385,7 @@ pub async fn proposer_boost_re_org_weight_misprediction() { /// - `num_empty_votes`: percentage of comm of attestations for the parent block /// - `num_head_votes`: number of attestations for the head block /// - `should_re_org`: whether the proposer should build on the parent rather than the head +#[allow(clippy::large_stack_frames)] pub async fn proposer_boost_re_org_test( ReOrgTest { head_slot, diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 3f933f4a5b..571c33fbcd 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -8994,7 +8994,7 @@ async fn create_signed_inclusion_lists() { config.spec.deneb_fork_epoch = Some(Epoch::new(0)); config.spec.electra_fork_epoch = Some(Epoch::new(0)); config.spec.fulu_fork_epoch = Some(Epoch::new(0)); - config.spec.eip7805_fork_epoch = Some(Epoch::new(0)); + config.spec.heze_fork_epoch = Some(Epoch::new(0)); ApiTester::new_from_config(config) .await .test_create_inclusion_lists() @@ -9010,7 +9010,7 @@ async fn test_post_validator_duties_inclusion_list() { config.spec.deneb_fork_epoch = Some(Epoch::new(0)); config.spec.electra_fork_epoch = Some(Epoch::new(0)); config.spec.fulu_fork_epoch = Some(Epoch::new(0)); - config.spec.eip7805_fork_epoch = Some(Epoch::new(0)); + config.spec.heze_fork_epoch = Some(Epoch::new(0)); ApiTester::new_from_config(config) .await .test_post_validator_duties_inclusion_list() diff --git a/beacon_node/lighthouse_network/src/rpc/codec.rs b/beacon_node/lighthouse_network/src/rpc/codec.rs index 5035135d43..173eb26899 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec.rs @@ -21,8 +21,8 @@ use types::{ ForkName, Hash256, LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate, LightClientUpdate, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella, - SignedBeaconBlockDeneb, SignedBeaconBlockEip7805, SignedBeaconBlockElectra, - SignedBeaconBlockFulu, SignedBeaconBlockGloas, + SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBeaconBlockFulu, + SignedBeaconBlockGloas, SignedBeaconBlockHeze, }; use unsigned_varint::codec::Uvi; @@ -890,8 +890,8 @@ fn handle_rpc_response( decoded_buffer, )?), )))), - Some(ForkName::Eip7805) => Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new( - SignedBeaconBlock::Eip7805(SignedBeaconBlockEip7805::from_ssz_bytes( + Some(ForkName::Heze) => Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new( + SignedBeaconBlock::Heze(SignedBeaconBlockHeze::from_ssz_bytes( decoded_buffer, )?), )))), @@ -901,6 +901,9 @@ fn handle_rpc_response( Some(ForkName::Gloas) => Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new( SignedBeaconBlock::Gloas(SignedBeaconBlockGloas::from_ssz_bytes(decoded_buffer)?), )))), + Some(ForkName::Heze) => Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new( + SignedBeaconBlock::Heze(SignedBeaconBlockHeze::from_ssz_bytes(decoded_buffer)?), + )))), None => Err(RPCError::ErrorResponse( RpcErrorResponse::InvalidRequest, format!( @@ -934,8 +937,8 @@ fn handle_rpc_response( decoded_buffer, )?), )))), - Some(ForkName::Eip7805) => Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new( - SignedBeaconBlock::Eip7805(SignedBeaconBlockEip7805::from_ssz_bytes( + Some(ForkName::Heze) => Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new( + SignedBeaconBlock::Heze(SignedBeaconBlockHeze::from_ssz_bytes( decoded_buffer, )?), )))), @@ -945,6 +948,9 @@ fn handle_rpc_response( Some(ForkName::Gloas) => Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new( SignedBeaconBlock::Gloas(SignedBeaconBlockGloas::from_ssz_bytes(decoded_buffer)?), )))), + Some(ForkName::Heze) => Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new( + SignedBeaconBlock::Heze(SignedBeaconBlockHeze::from_ssz_bytes(decoded_buffer)?), + )))), None => Err(RPCError::ErrorResponse( RpcErrorResponse::InvalidRequest, format!( @@ -1001,8 +1007,8 @@ mod tests { chain_spec.deneb_fork_epoch = Some(Epoch::new(4)); chain_spec.electra_fork_epoch = Some(Epoch::new(5)); chain_spec.fulu_fork_epoch = Some(Epoch::new(6)); - chain_spec.eip7805_fork_epoch = Some(Epoch::new(7)); - chain_spec.gloas_fork_epoch = Some(Epoch::new(8)); + chain_spec.gloas_fork_epoch = Some(Epoch::new(7)); + chain_spec.heze_fork_epoch = Some(Epoch::new(8)); // check that we have all forks covered assert!(chain_spec.fork_epoch(ForkName::latest()).is_some()); @@ -1018,8 +1024,9 @@ mod tests { ForkName::Deneb => spec.deneb_fork_epoch, ForkName::Electra => spec.electra_fork_epoch, ForkName::Fulu => spec.fulu_fork_epoch, - ForkName::Eip7805 => spec.eip7805_fork_epoch, + ForkName::Heze => spec.heze_fork_epoch, ForkName::Gloas => spec.gloas_fork_epoch, + ForkName::Heze => spec.heze_fork_epoch, }; let current_slot = current_epoch.unwrap().start_slot(Spec::slots_per_epoch()); ForkContext::new::(current_slot, Hash256::zero(), spec) @@ -1617,7 +1624,7 @@ mod tests { RpcResponse::Success(RpcSuccessResponse::DataColumnsByRange( empty_data_column_sidecar(&chain_spec) )), - ForkName::Eip7805, + ForkName::Heze, &chain_spec ), Ok(Some(RpcSuccessResponse::DataColumnsByRange( @@ -1673,7 +1680,7 @@ mod tests { RpcResponse::Success(RpcSuccessResponse::DataColumnsByRoot( empty_data_column_sidecar(&chain_spec) )), - ForkName::Eip7805, + ForkName::Heze, &chain_spec ), Ok(Some(RpcSuccessResponse::DataColumnsByRoot( diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 3e906fbdbc..9b451d0877 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -155,8 +155,8 @@ pub fn rpc_block_limits_by_fork(current_fork: ForkName) -> RpcLimits { | ForkName::Deneb | ForkName::Electra | ForkName::Fulu - | ForkName::Eip7805 - | ForkName::Gloas => RpcLimits::new( + | ForkName::Gloas + | ForkName::Heze => RpcLimits::new( *SIGNED_BEACON_BLOCK_BASE_MIN, *SIGNED_BEACON_BLOCK_BELLATRIX_MAX, ), @@ -185,7 +185,7 @@ fn rpc_light_client_updates_by_range_limits_by_fork(current_fork: ForkName) -> R ForkName::Deneb => { RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_UPDATES_BY_RANGE_DENEB_MAX) } - ForkName::Electra | ForkName::Fulu | ForkName::Eip7805 | ForkName::Gloas => { + ForkName::Electra | ForkName::Fulu | ForkName::Gloas | ForkName::Heze => { RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_UPDATES_BY_RANGE_ELECTRA_MAX) } } @@ -205,7 +205,7 @@ fn rpc_light_client_finality_update_limits_by_fork(current_fork: ForkName) -> Rp ForkName::Deneb => { RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_FINALITY_UPDATE_DENEB_MAX) } - ForkName::Electra | ForkName::Fulu | ForkName::Eip7805 | ForkName::Gloas => { + ForkName::Electra | ForkName::Fulu | ForkName::Gloas | ForkName::Heze => { RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_FINALITY_UPDATE_ELECTRA_MAX) } } @@ -226,7 +226,7 @@ fn rpc_light_client_optimistic_update_limits_by_fork(current_fork: ForkName) -> ForkName::Deneb => { RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_OPTIMISTIC_UPDATE_DENEB_MAX) } - ForkName::Electra | ForkName::Fulu | ForkName::Eip7805 | ForkName::Gloas => RpcLimits::new( + ForkName::Electra | ForkName::Fulu | ForkName::Gloas | ForkName::Heze => RpcLimits::new( altair_fixed_len, *LIGHT_CLIENT_OPTIMISTIC_UPDATE_ELECTRA_MAX, ), @@ -243,7 +243,7 @@ fn rpc_light_client_bootstrap_limits_by_fork(current_fork: ForkName) -> RpcLimit } ForkName::Capella => RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_BOOTSTRAP_CAPELLA_MAX), ForkName::Deneb => RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_BOOTSTRAP_DENEB_MAX), - ForkName::Electra | ForkName::Fulu | ForkName::Eip7805 | ForkName::Gloas => { + ForkName::Electra | ForkName::Fulu | ForkName::Gloas | ForkName::Heze => { RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_BOOTSTRAP_ELECTRA_MAX) } } diff --git a/beacon_node/lighthouse_network/src/types/pubsub.rs b/beacon_node/lighthouse_network/src/types/pubsub.rs index b6c7f8361c..0ec7932109 100644 --- a/beacon_node/lighthouse_network/src/types/pubsub.rs +++ b/beacon_node/lighthouse_network/src/types/pubsub.rs @@ -13,8 +13,8 @@ use types::{ PartialDataColumnSidecar, PayloadAttestationMessage, ProposerSlashing, SignedAggregateAndProof, SignedAggregateAndProofBase, SignedAggregateAndProofElectra, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix, - SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockEip7805, - SignedBeaconBlockElectra, SignedBeaconBlockFulu, SignedBeaconBlockGloas, + SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra, + SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBeaconBlockHeze, SignedBlsToExecutionChange, SignedContributionAndProof, SignedExecutionPayloadBid, SignedExecutionPayloadEnvelope, SignedInclusionList, SignedProposerPreferences, SignedVoluntaryExit, SingleAttestation, SubnetId, SyncCommitteeMessage, SyncSubnetId, @@ -256,14 +256,18 @@ impl PubsubMessage { SignedBeaconBlockFulu::from_ssz_bytes(data) .map_err(|e| format!("{:?}", e))?, ), - Some(ForkName::Eip7805) => SignedBeaconBlock::::Eip7805( - SignedBeaconBlockEip7805::from_ssz_bytes(data) + Some(ForkName::Heze) => SignedBeaconBlock::::Heze( + SignedBeaconBlockHeze::from_ssz_bytes(data) .map_err(|e| format!("{:?}", e))?, ), Some(ForkName::Gloas) => SignedBeaconBlock::::Gloas( SignedBeaconBlockGloas::from_ssz_bytes(data) .map_err(|e| format!("{:?}", e))?, ), + Some(ForkName::Heze) => SignedBeaconBlock::::Heze( + SignedBeaconBlockHeze::from_ssz_bytes(data) + .map_err(|e| format!("{:?}", e))?, + ), None => { return Err(format!( "Unknown gossipsub fork digest: {:?}", diff --git a/beacon_node/lighthouse_network/src/types/topics.rs b/beacon_node/lighthouse_network/src/types/topics.rs index 4c508cc1f0..f9b8050d42 100644 --- a/beacon_node/lighthouse_network/src/types/topics.rs +++ b/beacon_node/lighthouse_network/src/types/topics.rs @@ -90,7 +90,7 @@ pub fn core_topics_to_subscribe( } } - if fork_name.eip7805_enabled() { + if fork_name.heze_enabled() { topics.push(GossipKind::InclusionList); } diff --git a/beacon_node/lighthouse_network/tests/common.rs b/beacon_node/lighthouse_network/tests/common.rs index 2835c11398..dd9d3ec0d0 100644 --- a/beacon_node/lighthouse_network/tests/common.rs +++ b/beacon_node/lighthouse_network/tests/common.rs @@ -27,8 +27,8 @@ pub fn spec_with_all_forks_enabled() -> ChainSpec { chain_spec.deneb_fork_epoch = Some(Epoch::new(4)); chain_spec.electra_fork_epoch = Some(Epoch::new(5)); chain_spec.fulu_fork_epoch = Some(Epoch::new(6)); - chain_spec.eip7805_fork_epoch = Some(Epoch::new(7)); - chain_spec.gloas_fork_epoch = Some(Epoch::new(8)); + chain_spec.gloas_fork_epoch = Some(Epoch::new(7)); + chain_spec.heze_fork_epoch = Some(Epoch::new(8)); // check that we have all forks covered assert!(chain_spec.fork_epoch(ForkName::latest()).is_some()); @@ -45,8 +45,9 @@ pub fn fork_context(fork_name: ForkName, spec: &ChainSpec) -> ForkContext { ForkName::Deneb => spec.deneb_fork_epoch, ForkName::Electra => spec.electra_fork_epoch, ForkName::Fulu => spec.fulu_fork_epoch, - ForkName::Eip7805 => spec.eip7805_fork_epoch, + ForkName::Heze => spec.heze_fork_epoch, ForkName::Gloas => spec.gloas_fork_epoch, + ForkName::Heze => spec.heze_fork_epoch, }; let current_slot = current_epoch .unwrap_or_else(|| panic!("expect fork {fork_name} to be scheduled")) diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 734295ac1d..5930fd1c07 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -906,8 +906,8 @@ impl SyncManager { ); } // TODO(gloas) support gloas data column variant - DataColumnSidecar::Gloas(_) => { - error!("Gloas variant not yet supported") + DataColumnSidecar::Gloas(_) | DataColumnSidecar::Heze(_) => { + error!("Gloas/Heze variant not yet supported") } } } diff --git a/beacon_node/src/lib.rs b/beacon_node/src/lib.rs index 0306dbc494..dc6775c66f 100644 --- a/beacon_node/src/lib.rs +++ b/beacon_node/src/lib.rs @@ -205,7 +205,7 @@ mod test { spec.bellatrix_fork_epoch = Some(Epoch::new(256)); spec.deneb_fork_epoch = Some(Epoch::new(257)); spec.electra_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.heze_fork_epoch = None; spec.fulu_fork_epoch = None; spec.gloas_fork_epoch = None; let result = validator_fork_epochs(&spec); diff --git a/beacon_node/store/src/impls/execution_payload.rs b/beacon_node/store/src/impls/execution_payload.rs index 22b3d4b51d..27e043b148 100644 --- a/beacon_node/store/src/impls/execution_payload.rs +++ b/beacon_node/store/src/impls/execution_payload.rs @@ -2,7 +2,7 @@ use crate::{DBColumn, Error, StoreItem}; use ssz::{Decode, Encode}; use types::{ EthSpec, ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, - ExecutionPayloadDeneb, ExecutionPayloadEip7805, ExecutionPayloadElectra, ExecutionPayloadFulu, + ExecutionPayloadDeneb, ExecutionPayloadHeze, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, }; @@ -28,7 +28,7 @@ impl_store_item!(ExecutionPayloadCapella); impl_store_item!(ExecutionPayloadDeneb); impl_store_item!(ExecutionPayloadElectra); impl_store_item!(ExecutionPayloadFulu); -impl_store_item!(ExecutionPayloadEip7805); +impl_store_item!(ExecutionPayloadHeze); impl_store_item!(ExecutionPayloadGloas); /// This fork-agnostic implementation should be only used for writing. @@ -49,8 +49,8 @@ impl StoreItem for ExecutionPayload { return Ok(Self::Gloas(payload)); } - if let Ok(payload) = ExecutionPayloadEip7805::from_ssz_bytes(bytes) { - return Ok(Self::Eip7805(payload)); + if let Ok(payload) = ExecutionPayloadHeze::from_ssz_bytes(bytes) { + return Ok(Self::Heze(payload)); } if let Ok(payload) = ExecutionPayloadFulu::from_ssz_bytes(bytes) { diff --git a/beacon_node/store/src/partial_beacon_state.rs b/beacon_node/store/src/partial_beacon_state.rs index 2e8082517f..6d702300e5 100644 --- a/beacon_node/store/src/partial_beacon_state.rs +++ b/beacon_node/store/src/partial_beacon_state.rs @@ -16,7 +16,7 @@ use types::*; /// /// This can be deleted once schema versions prior to V22 are no longer supported. #[superstruct( - variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu), + variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Heze, Fulu), variant_attributes(derive(Debug, PartialEq, Clone, Encode, Decode)) )] #[derive(Debug, PartialEq, Clone, Encode)] @@ -68,9 +68,9 @@ where pub current_epoch_attestations: List, E::MaxPendingAttestations>, // Participation (Altair and later) - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Heze, Fulu))] pub previous_epoch_participation: List, - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Heze, Fulu))] pub current_epoch_participation: List, // Finality @@ -80,13 +80,13 @@ where pub finalized_checkpoint: Checkpoint, // Inactivity - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Heze, Fulu))] pub inactivity_scores: List, // Light-client sync committees - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Heze, Fulu))] pub current_sync_committee: Arc>, - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Heze, Fulu))] pub next_sync_committee: Arc>, // Execution @@ -111,10 +111,10 @@ where )] pub latest_execution_payload_header: ExecutionPayloadHeaderElectra, #[superstruct( - only(Eip7805), - partial_getter(rename = "latest_execution_payload_header_eip7805") + only(Heze), + partial_getter(rename = "latest_execution_payload_header_heze") )] - pub latest_execution_payload_header: ExecutionPayloadHeaderEip7805, + pub latest_execution_payload_header: ExecutionPayloadHeaderHeze, #[superstruct( only(Fulu), partial_getter(rename = "latest_execution_payload_header_fulu") @@ -122,35 +122,35 @@ where pub latest_execution_payload_header: ExecutionPayloadHeaderFulu, // Capella - #[superstruct(only(Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Capella, Deneb, Electra, Heze, Fulu))] pub next_withdrawal_index: u64, - #[superstruct(only(Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Capella, Deneb, Electra, Heze, Fulu))] pub next_withdrawal_validator_index: u64, #[ssz(skip_serializing, skip_deserializing)] - #[superstruct(only(Capella, Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Capella, Deneb, Electra, Heze, Fulu))] pub historical_summaries: Option>, // Electra - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub deposit_requests_start_index: u64, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub deposit_balance_to_consume: u64, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub exit_balance_to_consume: u64, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub earliest_exit_epoch: Epoch, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub consolidation_balance_to_consume: u64, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub earliest_consolidation_epoch: Epoch, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub pending_deposits: List, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub pending_partial_withdrawals: List, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub pending_consolidations: List, } @@ -428,10 +428,10 @@ impl TryInto> for PartialBeaconState { ], [historical_summaries] ), - PartialBeaconState::Eip7805(inner) => impl_try_into_beacon_state!( + PartialBeaconState::Heze(inner) => impl_try_into_beacon_state!( inner, - Eip7805, - BeaconStateEip7805, + Heze, + BeaconStateHeze, [ previous_epoch_participation, current_epoch_participation, diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 0a9d80ad89..d084679b76 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -146,7 +146,7 @@ impl Timeouts { sync_committee_contribution: base_timeout / HTTP_SYNC_COMMITTEE_CONTRIBUTION_TIMEOUT_QUOTIENT, sync_duties: base_timeout / HTTP_SYNC_DUTIES_TIMEOUT_QUOTIENT, - // TODO(EIP7805) check timeouts + // TODO(HEZE) check timeouts inclusion_list_duties: base_timeout, inclusion_list: base_timeout, sync_aggregators: base_timeout / HTTP_SYNC_AGGREGATOR_TIMEOUT_QUOTIENT, diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index 546776f944..f8ad5eed19 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -1044,6 +1044,7 @@ impl SseDataColumnSidecar { let kzg_commitments: Vec = match data_column_sidecar { DataColumnSidecar::Fulu(dc) => dc.kzg_commitments.to_vec(), DataColumnSidecar::Gloas(_) => vec![], + DataColumnSidecar::Heze(_) => vec![], }; let versioned_hashes = kzg_commitments .iter() @@ -1209,8 +1210,8 @@ impl<'de> ContextDeserialize<'de, ForkName> for SsePayloadAttributes { ForkName::Deneb | ForkName::Electra | ForkName::Fulu - | ForkName::Eip7805 - | ForkName::Gloas => { + | ForkName::Gloas + | ForkName::Heze => { Self::V3(Deserialize::deserialize(deserializer).map_err(convert_err)?) } }) @@ -2587,13 +2588,14 @@ mod test { ExecutionPayload::Electra(ExecutionPayloadElectra::::random_for_test( rng, )), - ExecutionPayload::Eip7805(ExecutionPayloadEip7805::::random_for_test( + ExecutionPayload::Heze(ExecutionPayloadHeze::::random_for_test( rng, )), ExecutionPayload::Fulu(ExecutionPayloadFulu::::random_for_test(rng)), ExecutionPayload::Gloas(ExecutionPayloadGloas::::random_for_test( rng, )), + ExecutionPayload::Heze(ExecutionPayloadHeze::::random_for_test(rng)), ]; let merged_forks = &ForkName::list_all()[2..]; assert_eq!( @@ -2639,8 +2641,8 @@ mod test { }, { let execution_payload = - ExecutionPayload::Eip7805( - ExecutionPayloadEip7805::::random_for_test(rng), + ExecutionPayload::Heze( + ExecutionPayloadHeze::::random_for_test(rng), ); let blobs_bundle = BlobsBundle::random_for_test(rng); ExecutionPayloadAndBlobs { @@ -2670,6 +2672,17 @@ mod test { blobs_bundle, } }, + { + let execution_payload = + ExecutionPayload::Heze( + ExecutionPayloadHeze::::random_for_test(rng), + ); + let blobs_bundle = BlobsBundle::random_for_test(rng); + ExecutionPayloadAndBlobs { + execution_payload, + blobs_bundle, + } + }, ]; let blob_forks = &ForkName::list_all()[4..]; diff --git a/consensus/proto_array/src/fork_choice_test_definition.rs b/consensus/proto_array/src/fork_choice_test_definition.rs index 41d6b5c4cc..f541124dec 100644 --- a/consensus/proto_array/src/fork_choice_test_definition.rs +++ b/consensus/proto_array/src/fork_choice_test_definition.rs @@ -1,6 +1,7 @@ mod execution_status; mod ffg_updates; mod gloas_payload; +mod heze_payload; mod no_votes; mod votes; @@ -20,6 +21,7 @@ use types::{ pub use execution_status::*; pub use ffg_updates::*; pub use gloas_payload::*; +pub use heze_payload::*; pub use no_votes::*; pub use votes::*; diff --git a/consensus/proto_array/src/fork_choice_test_definition/heze_payload.rs b/consensus/proto_array/src/fork_choice_test_definition/heze_payload.rs new file mode 100644 index 0000000000..ac1662a1c2 --- /dev/null +++ b/consensus/proto_array/src/fork_choice_test_definition/heze_payload.rs @@ -0,0 +1,1239 @@ +use super::*; + +fn heze_spec() -> ChainSpec { + let mut spec = MainnetEthSpec::default_spec(); + spec.proposer_score_boost = Some(50); + spec.gloas_fork_epoch = Some(Epoch::new(0)); + spec.heze_fork_epoch = Some(Epoch::new(0)); + spec +} + +pub fn get_heze_chain_following_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Build two branches off genesis where one child extends parent's payload chain (Full) + // and the other does not (Empty). + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(2), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(99)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // Extend both branches to verify that head selection follows the selected chain. + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(3), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(3)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(4), + parent_root: get_root(2), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(100)), + execution_payload_block_hash: Some(get_hash(4)), + }); + + // Mark root_1 as having received its execution payload so that + // its FULL virtual node exists in the Heze fork choice tree. + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(1), + expected_status: PayloadStatus::Full, + }); + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(2), + expected_status: PayloadStatus::Empty, + }); + + // With equal full/empty parent weights, tiebreak decides which chain to follow. + ops.push(Operation::SetPayloadTiebreak { + block_root: get_root(0), + is_timely: true, + is_data_available: true, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(3), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + // Cross-slot attestation with payload_present=true to Full branch (root 3, slot 2). + // vote_slot=3 differs from block_slot=2 and payload_present=true, so it counts as Full weight. + ops.push(Operation::ProcessGloasAttestation { + validator_index: 0, + block_root: get_root(3), + attestation_slot: Slot::new(3), + payload_present: true, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(3), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + // Full weight propagated up: root 0 and root 1 should show Full. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(0), + expected_status: PayloadStatus::Full, + current_slot: None, + proposer_boost_root: None, + }); + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(1), + expected_status: PayloadStatus::Full, + current_slot: None, + proposer_boost_root: None, + }); + // Root 2 has no payload received, so it's always Empty. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(2), + expected_status: PayloadStatus::Empty, + current_slot: None, + proposer_boost_root: None, + }); + + // Cross-slot attestations with payload_present=false to Empty branch (root 4, slot 2). + // Two validators so Empty branch outweighs Full branch. + ops.push(Operation::ProcessGloasAttestation { + validator_index: 1, + block_root: get_root(4), + attestation_slot: Slot::new(3), + payload_present: false, + }); + ops.push(Operation::ProcessGloasAttestation { + validator_index: 2, + block_root: get_root(4), + attestation_slot: Slot::new(3), + payload_present: false, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1, 1], + expected_head: get_root(4), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + // Empty weight now dominates, so root 0 flips to Empty. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(0), + expected_status: PayloadStatus::Empty, + current_slot: None, + proposer_boost_root: None, + }); + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(2), + expected_status: PayloadStatus::Empty, + current_slot: None, + proposer_boost_root: None, + }); + // Root 1 (Full branch) still has 1 Full vote and 0 Empty, so it stays Full. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(1), + expected_status: PayloadStatus::Full, + current_slot: None, + proposer_boost_root: None, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(get_hash(42)), + execution_payload_block_hash: Some(get_hash(0)), + spec: Some(heze_spec()), + } +} + +pub fn get_heze_payload_probe_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Block 1 at slot 1: child of genesis. Genesis has execution_payload_block_hash=zero + // (no execution payload at genesis), so all children have parent_payload_status=Empty. + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + + // One Full and one Empty vote for the same head block: tie probes via runtime tiebreak, + // which defaults to Empty unless timely+data-available evidence is set. + ops.push(Operation::ProcessPayloadAttestation { + validator_index: 0, + block_root: get_root(1), + attestation_slot: Slot::new(2), + payload_present: true, + blob_data_available: false, + }); + ops.push(Operation::ProcessPayloadAttestation { + validator_index: 1, + block_root: get_root(1), + attestation_slot: Slot::new(2), + payload_present: false, + blob_data_available: false, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(1), + current_slot: Slot::new(0), + // With MainnetEthSpec PTC_SIZE=512 and a 256-bit threshold, 1 bit set is not timely, so Empty. + expected_payload_status: Some(PayloadStatus::Empty), + }); + // PTC votes write to bitfields only, not to full/empty weight. + // Weight is 0 because no CL attestations target this block. + ops.push(Operation::AssertPayloadWeights { + block_root: get_root(1), + expected_full_weight: 0, + expected_empty_weight: 0, + }); + + // Flip validator 0 to Empty; both bits now clear. + ops.push(Operation::ProcessPayloadAttestation { + validator_index: 0, + block_root: get_root(1), + attestation_slot: Slot::new(3), + payload_present: false, + blob_data_available: false, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(1), + current_slot: Slot::new(0), + expected_payload_status: Some(PayloadStatus::Empty), + }); + ops.push(Operation::AssertPayloadWeights { + block_root: get_root(1), + expected_full_weight: 0, + expected_empty_weight: 0, + }); + + // Same-slot attestation to a new head candidate should be Pending (no payload bucket change). + // Root 5 is an Empty child of root_1 (parent_hash doesn't match root_1's block_hash), + // so it's reachable through root_1's Empty direction (root_1 has no payload_received). + ops.push(Operation::ProcessBlock { + slot: Slot::new(3), + root: get_root(5), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(101)), + execution_payload_block_hash: Some(get_hash(5)), + }); + ops.push(Operation::ProcessPayloadAttestation { + validator_index: 2, + block_root: get_root(5), + attestation_slot: Slot::new(3), + payload_present: true, + blob_data_available: false, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1, 1], + expected_head: get_root(5), + current_slot: Slot::new(0), + expected_payload_status: Some(PayloadStatus::Empty), + }); + ops.push(Operation::AssertPayloadWeights { + block_root: get_root(5), + expected_full_weight: 0, + expected_empty_weight: 0, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + // Genesis has zero execution block hash (no payload at genesis), which + // ensures all children get parent_payload_status=Empty. + execution_payload_parent_hash: Some(ExecutionBlockHash::zero()), + execution_payload_block_hash: Some(ExecutionBlockHash::zero()), + spec: Some(heze_spec()), + } +} + +/// Test that CL attestation weight can flip the head between Full/Empty branches, +/// overriding the tiebreaker. +pub fn get_heze_find_head_vote_transition_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Competing branches with distinct payload ancestry (Full vs Empty from genesis). + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(2), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(99)), + execution_payload_block_hash: Some(get_hash(2)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(3), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(3)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(4), + parent_root: get_root(2), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(100)), + execution_payload_block_hash: Some(get_hash(4)), + }); + + // Mark root_1 as having received its execution payload so that + // its FULL virtual node exists in the Heze fork choice tree. + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + // Equal branch weights: tiebreak FULL picks branch rooted at 3. + ops.push(Operation::SetPayloadTiebreak { + block_root: get_root(0), + is_timely: true, + is_data_available: true, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(3), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + // CL attestation to Empty branch (root 4) from validator 0 flips the head to 4. + ops.push(Operation::ProcessAttestation { + validator_index: 0, + block_root: get_root(4), + attestation_slot: Slot::new(3), + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(4), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + // CL attestation back to Full branch (root 3) returns the head to 3. + ops.push(Operation::ProcessAttestation { + validator_index: 0, + block_root: get_root(3), + attestation_slot: Slot::new(4), + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(3), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(get_hash(42)), + execution_payload_block_hash: Some(get_hash(0)), + spec: Some(heze_spec()), + } +} + +/// CL attestation weight overrides payload preference tiebreaker. +pub fn get_heze_weight_priority_over_payload_preference_test_definition() -> ForkChoiceTestDefinition +{ + let mut ops = vec![]; + + // Build two branches where one child extends payload (Full) and the other doesn't (Empty). + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(2), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(99)), + execution_payload_block_hash: Some(get_hash(2)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(3), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(3)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(4), + parent_root: get_root(2), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(100)), + execution_payload_block_hash: Some(get_hash(4)), + }); + + // Mark root_1 as having received its execution payload so that + // its FULL virtual node exists in the Heze fork choice tree. + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + // Parent prefers Full on equal branch weights (tiebreaker). + ops.push(Operation::SetPayloadTiebreak { + block_root: get_root(0), + is_timely: true, + is_data_available: true, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(3), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + // Two CL attestations to the Empty branch make it strictly heavier, + // overriding the Full tiebreaker. + ops.push(Operation::ProcessAttestation { + validator_index: 0, + block_root: get_root(4), + attestation_slot: Slot::new(3), + }); + ops.push(Operation::ProcessAttestation { + validator_index: 1, + block_root: get_root(4), + attestation_slot: Slot::new(3), + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(4), + current_slot: Slot::new(0), + expected_payload_status: None, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(get_hash(42)), + execution_payload_block_hash: Some(get_hash(0)), + spec: Some(heze_spec()), + } +} + +pub fn get_heze_parent_empty_when_child_points_to_grandparent_test_definition() +-> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Build a three-block chain A -> B -> C (CL parent links). + // A: EL parent = genesis hash(0), EL hash = hash(1). + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + + // B: EL parent = hash(1), EL hash = hash(2). + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(2), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // C: CL parent is B, but EL parent points to A (hash 1), not B (hash 2). + // This models B's payload not arriving in time, so C records parent status as Empty. + ops.push(Operation::ProcessBlock { + slot: Slot::new(3), + root: get_root(3), + parent_root: get_root(2), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(3)), + }); + + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(3), + expected_status: PayloadStatus::Empty, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(get_hash(42)), + execution_payload_block_hash: Some(get_hash(0)), + spec: Some(heze_spec()), + } +} + +/// Test interleaving of blocks, regular attestations, and tiebreaker. +/// +/// genesis → block 1 (Full) → block 3 +/// → block 2 (Empty) → block 4 +/// +/// With equal CL weight, tiebreaker determines which branch wins. +/// An extra CL attestation can override the tiebreaker. +pub fn get_heze_interleaved_attestations_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Step 1: Two competing blocks at slot 1. + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(2), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(99)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // Step 2: Regular attestations arrive, one per branch (equal CL weight). + ops.push(Operation::ProcessAttestation { + validator_index: 0, + block_root: get_root(1), + attestation_slot: Slot::new(1), + }); + ops.push(Operation::ProcessAttestation { + validator_index: 1, + block_root: get_root(2), + attestation_slot: Slot::new(1), + }); + + // Step 3: Child blocks at slot 2. + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(3), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(3)), + }); + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(4), + parent_root: get_root(2), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(100)), + execution_payload_block_hash: Some(get_hash(4)), + }); + + // Mark root_1 as having received its execution payload so that + // its FULL virtual node exists in the Heze fork choice tree. + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + // Step 4: Set tiebreaker to Empty on genesis so the Empty branch wins. + ops.push(Operation::SetPayloadTiebreak { + block_root: get_root(0), + is_timely: false, + is_data_available: false, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(4), + current_slot: Slot::new(1), + expected_payload_status: None, + }); + // Weights are tied (1 vote each branch), tiebreaker is Empty. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(0), + expected_status: PayloadStatus::Empty, + current_slot: None, + proposer_boost_root: None, + }); + + // Step 5: Flip tiebreaker to Full so the Full branch wins. + ops.push(Operation::SetPayloadTiebreak { + block_root: get_root(0), + is_timely: true, + is_data_available: true, + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(3), + current_slot: Slot::new(100), + expected_payload_status: None, + }); + // Weights still tied, tiebreaker flipped to Full. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(0), + expected_status: PayloadStatus::Full, + current_slot: None, + proposer_boost_root: None, + }); + + // Step 6: Add extra CL weight to the Empty branch; this overrides the Full tiebreaker. + ops.push(Operation::ProcessAttestation { + validator_index: 2, + block_root: get_root(4), + attestation_slot: Slot::new(3), + }); + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1, 1], + expected_head: get_root(4), + current_slot: Slot::new(100), + expected_payload_status: None, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(get_hash(42)), + execution_payload_block_hash: Some(get_hash(0)), + spec: Some(heze_spec()), + } +} + +/// Test interleaving of blocks, payload validation, and attestations. +/// +/// Scenario (branching at block 1 since genesis has no payload): +/// - Genesis block (slot 0) with zero execution block hash +/// - Block 1 (slot 1) child of genesis (Empty parent status since genesis hash=zero) +/// - Block 2 (slot 2) extends block 1 Full chain (parent_hash matches block 1's block_hash) +/// - Block 3 (slot 2) extends block 1 Empty chain (parent_hash doesn't match) +/// - Before payload arrives: payload_received is false for block 1, only Empty reachable +/// - Process execution payload for block 1 → payload_received becomes true +/// - Both Full and Empty directions from block 1 become available +/// - With equal weight, tiebreaker prefers Full → Block 2 wins +pub fn get_heze_payload_received_interleaving_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Block 1 at slot 1: child of genesis. Genesis has zero block hash, so + // parent_payload_status = Empty regardless of block 1's execution_payload_parent_hash. + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + + // Block 2 at slot 2: Full child of block 1 (parent_hash matches block 1's block_hash). + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(2), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // Block 3 at slot 2: Empty child of block 1 (parent_hash doesn't match block 1's block_hash). + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(3), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(99)), + execution_payload_block_hash: Some(get_hash(3)), + }); + + // Verify parent_payload_status is set correctly. + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(1), + expected_status: PayloadStatus::Empty, + }); + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(2), + expected_status: PayloadStatus::Full, + }); + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(3), + expected_status: PayloadStatus::Empty, + }); + + // Genesis does NOT have payload_received (no payload at genesis). + ops.push(Operation::AssertPayloadReceived { + block_root: get_root(0), + expected: false, + }); + + // Block 1 does not have payload_received yet. + ops.push(Operation::AssertPayloadReceived { + block_root: get_root(1), + expected: false, + }); + + // Give one vote to each competing child so they have equal weight. + ops.push(Operation::ProcessAttestation { + validator_index: 0, + block_root: get_root(2), + attestation_slot: Slot::new(2), + }); + ops.push(Operation::ProcessAttestation { + validator_index: 1, + block_root: get_root(3), + attestation_slot: Slot::new(2), + }); + + // Before payload_received on block 1: only Empty direction available. + // Block 3 (Empty child) is reachable, Block 2 (Full child) is not. + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(3), + current_slot: Slot::new(100), + expected_payload_status: None, + }); + + // Process execution payload envelope for block 1 → payload_received becomes true. + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + ops.push(Operation::AssertPayloadReceived { + block_root: get_root(1), + expected: true, + }); + + // After payload_received on block 1: both Full and Empty directions available. + // Equal weight, tiebreaker prefers Full → Block 2 (Full child) wins. + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1, 1], + expected_head: get_root(2), + current_slot: Slot::new(100), + expected_payload_status: None, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + // Genesis has zero execution block hash (no payload at genesis). + execution_payload_parent_hash: Some(ExecutionBlockHash::zero()), + execution_payload_block_hash: Some(ExecutionBlockHash::zero()), + spec: Some(heze_spec()), + } +} + +/// When `current_slot == node.slot + 1`, spec `get_weight` zeroes out Full and Empty +/// weights so the tiebreaker decides. Tests that the zero-out is applied and +/// doesn't just compare raw payload weights. +pub fn get_heze_previous_slot_tiebreaker_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Block 1 at slot 1 with its payload received. + // Genesis has zero block hash so all its children are Empty (genesis never has + // payload_received). Block 1's parent_hash doesn't match zero → Empty child. + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + // Block 2 at slot 2 with a mismatched EL parent hash, giving it an Empty parent payload status. + ops.push(Operation::ProcessBlock { + slot: Slot::new(2), + root: get_root(2), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(99)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // More Full weight than Empty on block 1. + ops.push(Operation::ProcessGloasAttestation { + validator_index: 0, + block_root: get_root(1), + attestation_slot: Slot::new(2), + payload_present: true, + }); + + // Materialize the attestation into `full_payload_weight`. + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(1), + current_slot: Slot::new(1), + expected_payload_status: Some(PayloadStatus::Full), + }); + + // Before zero-out (current_slot == block 1's slot), raw weights decide payload status (Full) + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(1), + expected_status: PayloadStatus::Full, + current_slot: Some(Slot::new(1)), + proposer_boost_root: None, + }); + + // At current_slot == block 1's slot + 1, both weights zero out and the + // tiebreaker picks Empty (block 2 extends block 1 with an Empty parent + // payload status). + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(1), + expected_status: PayloadStatus::Empty, + current_slot: Some(Slot::new(2)), + proposer_boost_root: Some(get_root(2)), + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(ExecutionBlockHash::zero()), + execution_payload_block_hash: Some(ExecutionBlockHash::zero()), + spec: Some(heze_spec()), + } +} + +/// Proposer boost on a descendant can flip an ancestor's canonical payload status. +/// Boost supports the ancestor's Full variant (via the descendant's Full parent +/// payload status) but not Empty, so a large enough boost overrides raw Empty weight. +pub fn get_heze_proposer_boost_flips_ancestor_test_definition() -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Block 1 at slot 1 with payload received. + ops.push(Operation::ProcessBlock { + slot: Slot::new(1), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(0)), + execution_payload_block_hash: Some(get_hash(1)), + }); + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(1), + }); + + // Block 2 at slot 3 with a Full parent payload status (skip slot 2 so + // block 1's previous-slot zero-out doesn't fire at current_slot 3). + ops.push(Operation::ProcessBlock { + slot: Slot::new(3), + root: get_root(2), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // One Empty vote on block 1. Balance totals are chosen so the proposer + // boost score exceeds the single Empty voter's balance. + ops.push(Operation::ProcessGloasAttestation { + validator_index: 0, + block_root: get_root(1), + attestation_slot: Slot::new(2), + payload_present: false, + }); + + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![100, 10000], + expected_head: get_root(1), + current_slot: Slot::new(3), + expected_payload_status: Some(PayloadStatus::Empty), + }); + + // Without boost the raw weights decide and Empty wins. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(1), + expected_status: PayloadStatus::Empty, + current_slot: Some(Slot::new(3)), + proposer_boost_root: None, + }); + + // With boost on block 2 the boost supports block 1's Full variant, so Full wins. + ops.push(Operation::AssertPayloadStatusByWeight { + block_root: get_root(1), + expected_status: PayloadStatus::Full, + current_slot: Some(Slot::new(3)), + proposer_boost_root: Some(get_root(2)), + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: Some(ExecutionBlockHash::zero()), + execution_payload_block_hash: Some(ExecutionBlockHash::zero()), + spec: Some(heze_spec()), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn heze_fork_boundary_spec() -> ChainSpec { + let mut spec = MainnetEthSpec::default_spec(); + spec.proposer_score_boost = Some(50); + spec.heze_fork_epoch = Some(Epoch::new(1)); + spec + } + + /// Heze fork boundary: a chain starting pre-Heze (V17 nodes) that crosses into + /// Heze (V29 nodes). The head should advance through the fork boundary. + /// + /// Parameters: + /// - `skip_first_heze_slot`: if true, there is no block at the first Heze slot (slot 32); + /// the first V29 block appears at slot 33. + /// - `first_heze_block_full`: if true, the first V29 block extends the parent V17 node's + /// EL chain (Full parent payload status). If false, it doesn't (Empty). + fn get_heze_fork_boundary_test_definition( + skip_first_heze_slot: bool, + first_heze_block_full: bool, + ) -> ForkChoiceTestDefinition { + let mut ops = vec![]; + + // Block at slot 31 — last pre-Heze slot. Created as a V17 node because + // heze_fork_epoch = 1 means Heze starts at slot 32. + // + // The test harness sets execution_status = Optimistic(ExecutionBlockHash::from_root(root)), + // so this V17 node's EL block hash = ExecutionBlockHash::from_root(get_root(1)). + ops.push(Operation::ProcessBlock { + slot: Slot::new(31), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: None, + execution_payload_block_hash: None, + }); + + // First Heze block (V29 node). + let heze_slot = if skip_first_heze_slot { 33 } else { 32 }; + + // The first Heze block should always have the pre-Heze block as its execution parent, + // although this is currently not checked anywhere (the spec doesn't mention this). + ops.push(Operation::ProcessBlock { + slot: Slot::new(heze_slot), + root: get_root(2), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // Parent payload status of fork boundary block should always be Empty. + let expected_parent_status = PayloadStatus::Empty; + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(2), + expected_status: expected_parent_status, + }); + + // Mark root 2's execution payload as received so the Full virtual child exists. + if first_heze_block_full { + ops.push(Operation::ProcessExecutionPayloadEnvelope { + block_root: get_root(2), + }); + } + + // Extend the chain with another V29 block (Full child of root 2). + ops.push(Operation::ProcessBlock { + slot: Slot::new(heze_slot + 1), + root: get_root(3), + parent_root: get_root(2), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: if first_heze_block_full { + Some(get_hash(2)) + } else { + Some(get_hash(1)) + }, + execution_payload_block_hash: Some(get_hash(3)), + }); + + // Head should advance to the tip of the chain through the fork boundary. + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: vec![1], + expected_head: get_root(3), + current_slot: Slot::new(heze_slot + 1), + expected_payload_status: None, + }); + + ops.push(Operation::AssertParentPayloadStatus { + block_root: get_root(3), + expected_status: if first_heze_block_full { + PayloadStatus::Full + } else { + PayloadStatus::Empty + }, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + // Genesis is V17 (slot 0 < Heze fork slot 32), these are unused for V17. + execution_payload_parent_hash: None, + execution_payload_block_hash: None, + spec: Some(heze_fork_boundary_spec()), + } + } + + #[test] + fn fork_boundary_no_skip_full() { + get_heze_fork_boundary_test_definition(false, true).run(); + } + + #[test] + fn fork_boundary_no_skip_empty() { + get_heze_fork_boundary_test_definition(false, false).run(); + } + + #[test] + fn fork_boundary_skip_first_heze_slot_full() { + get_heze_fork_boundary_test_definition(true, true).run(); + } + + #[test] + fn fork_boundary_skip_first_heze_slot_empty() { + get_heze_fork_boundary_test_definition(true, false).run(); + } + + #[test] + fn chain_following() { + let test = get_heze_chain_following_test_definition(); + test.run(); + } + + #[test] + fn payload_probe() { + let test = get_heze_payload_probe_test_definition(); + test.run(); + } + + #[test] + fn find_head_vote_transition() { + let test = get_heze_find_head_vote_transition_test_definition(); + test.run(); + } + + #[test] + fn weight_priority_over_payload_preference() { + let test = get_heze_weight_priority_over_payload_preference_test_definition(); + test.run(); + } + + #[test] + fn parent_empty_when_child_points_to_grandparent() { + let test = get_heze_parent_empty_when_child_points_to_grandparent_test_definition(); + test.run(); + } + + #[test] + fn interleaved_attestations() { + let test = get_heze_interleaved_attestations_test_definition(); + test.run(); + } + + #[test] + fn payload_received_interleaving() { + let test = get_heze_payload_received_interleaving_test_definition(); + test.run(); + } + + #[test] + fn previous_slot_tiebreaker() { + let test = get_heze_previous_slot_tiebreaker_test_definition(); + test.run(); + } + + #[test] + fn proposer_boost_flips_ancestor() { + let test = get_heze_proposer_boost_flips_ancestor_test_definition(); + test.run(); + } + + /// Test that execution payload invalidation propagates across the V17→V29 fork + /// boundary: after invalidating a V17 parent, head must not select any descendant. + /// + /// genesis(V17) -> block_1(V17, slot 31) -> block_2(V29, slot 32) + #[test] + fn mixed_v17_v29_invalidation() { + let balances = vec![1]; + let mut ops = vec![]; + + // V17 block at slot 31 (pre-Heze). + ops.push(Operation::ProcessBlock { + slot: Slot::new(31), + root: get_root(1), + parent_root: get_root(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: None, + execution_payload_block_hash: None, + }); + + // V29 block at slot 32 (first Heze slot), child of block 1. + ops.push(Operation::ProcessBlock { + slot: Slot::new(32), + root: get_root(2), + parent_root: get_root(1), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + execution_payload_parent_hash: Some(get_hash(1)), + execution_payload_block_hash: Some(get_hash(2)), + }); + + // Vote for block 2 (V29) so both blocks have weight. + ops.push(Operation::ProcessAttestation { + validator_index: 0, + block_root: get_root(2), + attestation_slot: Slot::new(32), + }); + + // FindHead triggers apply_score_changes which materializes the vote. + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: balances.clone(), + expected_head: get_root(2), + current_slot: Slot::new(32), + expected_payload_status: None, + }); + + // Invalidate block 1 (V17). filter_block_tree excludes the entire branch. + ops.push(Operation::InvalidatePayload { + head_block_root: get_root(1), + latest_valid_ancestor_root: Some(get_hash(0)), + }); + + // Head falls back to genesis — the invalid branch is no longer selectable. + ops.push(Operation::FindHead { + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + justified_state_balances: balances.clone(), + expected_head: get_root(0), + current_slot: Slot::new(32), + expected_payload_status: None, + }); + + ForkChoiceTestDefinition { + finalized_block_slot: Slot::new(0), + justified_checkpoint: get_checkpoint(0), + finalized_checkpoint: get_checkpoint(0), + operations: ops, + execution_payload_parent_hash: None, + execution_payload_block_hash: None, + spec: Some(heze_fork_boundary_spec()), + } + .run(); + } +} diff --git a/consensus/state_processing/src/common/get_attestation_participation.rs b/consensus/state_processing/src/common/get_attestation_participation.rs index 2262b59ac1..8f1f000f40 100644 --- a/consensus/state_processing/src/common/get_attestation_participation.rs +++ b/consensus/state_processing/src/common/get_attestation_participation.rs @@ -17,7 +17,7 @@ use types::{ /// This function will return an error if the source of the attestation doesn't match the /// state's relevant justified checkpoint. /// -/// This function has been abstracted to work for all forks from Altair to Gloas. +/// This function has been abstracted to work for all forks from Altair to Heze. pub fn get_attestation_participation_flag_indices( state: &BeaconState, data: &AttestationData, diff --git a/consensus/state_processing/src/genesis.rs b/consensus/state_processing/src/genesis.rs index 0900c97aac..1cce5bd6a6 100644 --- a/consensus/state_processing/src/genesis.rs +++ b/consensus/state_processing/src/genesis.rs @@ -4,8 +4,8 @@ use super::per_block_processing::{ use crate::common::DepositDataTree; use crate::upgrade::electra::upgrade_state_to_electra; use crate::upgrade::{ - upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb, - upgrade_to_eip7805, upgrade_to_fulu, upgrade_to_gloas, + upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb, upgrade_to_fulu, + upgrade_to_gloas, upgrade_to_heze, }; use fixed_bytes::FixedBytesExtended; use safe_arith::{ArithError, SafeArith}; @@ -141,22 +141,6 @@ pub fn initialize_beacon_state_from_eth1( } } - // Upgrade to eip7805 if configured from genesis. - if spec - .eip7805_fork_epoch - .is_some_and(|fork_epoch| fork_epoch == E::genesis_epoch()) - { - upgrade_to_eip7805(&mut state, spec)?; - - // Remove intermediate Electra fork from `state.fork`. - state.fork_mut().previous_version = spec.eip7805_fork_version; - - // Override latest execution payload header. - if let Some(ExecutionPayloadHeader::Eip7805(ref header)) = execution_payload_header { - *state.latest_execution_payload_header_eip7805_mut()? = header.clone(); - } - } - // Upgrade to fulu if configured from genesis. if spec .fulu_fork_epoch @@ -198,6 +182,17 @@ pub fn initialize_beacon_state_from_eth1( state.latest_block_header_mut().body_root = genesis_body_root; } + // Upgrade to heze if configured from genesis. + if spec + .heze_fork_epoch + .is_some_and(|fork_epoch| fork_epoch == E::genesis_epoch()) + { + upgrade_to_heze(&mut state, spec)?; + + // Remove intermediate Gloas fork from `state.fork`. + state.fork_mut().previous_version = spec.heze_fork_version; + } + // Now that we have our validators, initialize the caches (including the committees) state.build_caches(spec)?; @@ -209,10 +204,9 @@ pub fn initialize_beacon_state_from_eth1( /// Create an unsigned genesis `BeaconBlock`. /// -/// Per spec, the genesis block body is empty (all default fields) except for Gloas, -/// where `body.signed_execution_payload_bid.message` is initialised from -/// `state.latest_execution_payload_bid` so that the first post-genesis proposer can -/// build on the correct execution layer head. +/// For Gloas and later, the block's `signed_execution_payload_bid` is populated from the state's +/// `latest_execution_payload_bid` so that the body root is consistent with +/// `state.latest_block_header.body_root`. /// /// `state.latest_block_header.body_root` is set from this same block's body, so the /// two must stay in sync. @@ -221,9 +215,16 @@ pub fn genesis_block( spec: &ChainSpec, ) -> Result, BeaconStateError> { let mut block = BeaconBlock::empty(spec); - if let BeaconBlock::Gloas(ref mut gloas_block) = block { - let bid = state.latest_execution_payload_bid()?.clone(); - gloas_block.body.signed_execution_payload_bid.message = bid; + if let Ok(block) = block.as_gloas_mut() { + let state_bid = state.latest_execution_payload_bid()?; + let bid = &mut block.body.signed_execution_payload_bid.message; + bid.block_hash = state_bid.block_hash; + bid.execution_requests_root = state_bid.execution_requests_root; + } else if let Ok(block) = block.as_heze_mut() { + let state_bid = state.latest_execution_payload_bid()?; + let bid = &mut block.body.signed_execution_payload_bid.message; + bid.block_hash = state_bid.block_hash; + bid.execution_requests_root = state_bid.execution_requests_root; } Ok(block) } diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 89374ca721..fc0456cff1 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -472,9 +472,9 @@ pub fn process_execution_payload>( _ => return Err(BlockProcessingError::IncorrectStateType), } } - ExecutionPayloadHeaderRefMut::Eip7805(header_mut) => { + ExecutionPayloadHeaderRefMut::Heze(header_mut) => { match payload.to_execution_payload_header() { - ExecutionPayloadHeader::Eip7805(header) => *header_mut = header, + ExecutionPayloadHeader::Heze(header) => *header_mut = header, _ => return Err(BlockProcessingError::IncorrectStateType), } } diff --git a/consensus/state_processing/src/per_slot_processing.rs b/consensus/state_processing/src/per_slot_processing.rs index 77adb4c7d1..7933fba9c5 100644 --- a/consensus/state_processing/src/per_slot_processing.rs +++ b/consensus/state_processing/src/per_slot_processing.rs @@ -1,6 +1,6 @@ use crate::upgrade::{ upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb, - upgrade_to_eip7805, upgrade_to_electra, upgrade_to_fulu, upgrade_to_gloas, + upgrade_to_electra, upgrade_to_fulu, upgrade_to_gloas, upgrade_to_heze, }; use crate::{per_epoch_processing::EpochProcessingSummary, *}; use fixed_bytes::FixedBytesExtended; @@ -96,15 +96,20 @@ pub fn per_slot_processing( if spec.fulu_fork_epoch == Some(state.current_epoch()) { upgrade_to_fulu(state, spec)?; } - // Eip7805. - if spec.eip7805_fork_epoch == Some(state.current_epoch()) { - upgrade_to_eip7805(state, spec)?; + // Heze. + if spec.heze_fork_epoch == Some(state.current_epoch()) { + upgrade_to_heze(state, spec)?; } // Gloas. if spec.gloas_fork_epoch == Some(state.current_epoch()) { upgrade_to_gloas(state, spec)?; } + // Heze. + if spec.heze_fork_epoch == Some(state.current_epoch()) { + upgrade_to_heze(state, spec)?; + } + // Additionally build all caches so that all valid states that are advanced always have // committee caches built, and we don't have to worry about initialising them at higher // layers. diff --git a/consensus/state_processing/src/upgrade.rs b/consensus/state_processing/src/upgrade.rs index 85fce5695f..03c9dad5bc 100644 --- a/consensus/state_processing/src/upgrade.rs +++ b/consensus/state_processing/src/upgrade.rs @@ -2,16 +2,16 @@ pub mod altair; pub mod bellatrix; pub mod capella; pub mod deneb; -pub mod eip7805; pub mod electra; pub mod fulu; pub mod gloas; +pub mod heze; pub use altair::upgrade_to_altair; pub use bellatrix::upgrade_to_bellatrix; pub use capella::upgrade_to_capella; pub use deneb::upgrade_to_deneb; -pub use eip7805::upgrade_to_eip7805; pub use electra::upgrade_to_electra; pub use fulu::upgrade_to_fulu; pub use gloas::upgrade_to_gloas; +pub use heze::upgrade_to_heze; diff --git a/consensus/state_processing/src/upgrade/eip7805.rs b/consensus/state_processing/src/upgrade/heze.rs similarity index 74% rename from consensus/state_processing/src/upgrade/eip7805.rs rename to consensus/state_processing/src/upgrade/heze.rs index 14896fef1a..e9156418c1 100644 --- a/consensus/state_processing/src/upgrade/eip7805.rs +++ b/consensus/state_processing/src/upgrade/heze.rs @@ -1,39 +1,37 @@ use std::mem; -use types::{BeaconState, BeaconStateEip7805, BeaconStateError as Error, ChainSpec, EthSpec, Fork}; +use types::{BeaconState, BeaconStateError as Error, BeaconStateHeze, ChainSpec, EthSpec, Fork}; -/// Transform a `Electra` state into an `Eip7805s` state. -pub fn upgrade_to_eip7805( +/// Transform a `Gloas` state into a `Heze` state. +pub fn upgrade_to_heze( pre_state: &mut BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { - let _epoch = pre_state.current_epoch(); - - let post = upgrade_state_to_eip7805(pre_state, spec)?; + let post = upgrade_state_to_heze(pre_state, spec)?; *pre_state = post; Ok(()) } -pub fn upgrade_state_to_eip7805( +pub fn upgrade_state_to_heze( pre_state: &mut BeaconState, spec: &ChainSpec, ) -> Result, Error> { let epoch = pre_state.current_epoch(); - let pre = pre_state.as_fulu_mut()?; + let pre = pre_state.as_gloas_mut()?; // Where possible, use something like `mem::take` to move fields from behind the &mut // reference. For other fields that don't have a good default value, use `clone`. // // Fixed size vectors get cloned because replacing them would require the same size // allocation as cloning. - let post = BeaconState::Eip7805(BeaconStateEip7805 { + let post = BeaconState::Heze(BeaconStateHeze { // Versioning genesis_time: pre.genesis_time, genesis_validators_root: pre.genesis_validators_root, slot: pre.slot, fork: Fork { previous_version: pre.fork.current_version, - current_version: spec.eip7805_fork_version, + current_version: spec.heze_fork_version, epoch, }, // History @@ -52,7 +50,7 @@ pub fn upgrade_state_to_eip7805( randao_mixes: pre.randao_mixes.clone(), // Slashings slashings: pre.slashings.clone(), - // `Participation + // Participation previous_epoch_participation: mem::take(&mut pre.previous_epoch_participation), current_epoch_participation: mem::take(&mut pre.current_epoch_participation), // Finality @@ -65,8 +63,8 @@ pub fn upgrade_state_to_eip7805( // Sync committees current_sync_committee: pre.current_sync_committee.clone(), next_sync_committee: pre.next_sync_committee.clone(), - // Execution - latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip7805(), + // Execution Bid + latest_execution_payload_bid: pre.latest_execution_payload_bid.clone(), // Capella next_withdrawal_index: pre.next_withdrawal_index, next_withdrawal_validator_index: pre.next_withdrawal_validator_index, @@ -81,6 +79,16 @@ pub fn upgrade_state_to_eip7805( pending_deposits: pre.pending_deposits.clone(), pending_partial_withdrawals: pre.pending_partial_withdrawals.clone(), pending_consolidations: pre.pending_consolidations.clone(), + proposer_lookahead: mem::take(&mut pre.proposer_lookahead), + // Gloas + builders: mem::take(&mut pre.builders), + next_withdrawal_builder_index: pre.next_withdrawal_builder_index, + execution_payload_availability: pre.execution_payload_availability.clone(), + builder_pending_payments: pre.builder_pending_payments.clone(), + builder_pending_withdrawals: mem::take(&mut pre.builder_pending_withdrawals), + latest_block_hash: pre.latest_block_hash, + payload_expected_withdrawals: mem::take(&mut pre.payload_expected_withdrawals), + ptc_window: pre.ptc_window.clone(), // Caches total_active_balance: pre.total_active_balance, progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache), @@ -89,7 +97,7 @@ pub fn upgrade_state_to_eip7805( exit_cache: mem::take(&mut pre.exit_cache), slashings_cache: mem::take(&mut pre.slashings_cache), epoch_cache: mem::take(&mut pre.epoch_cache), - proposer_lookahead: pre.proposer_lookahead.clone(), }); + Ok(post) } diff --git a/consensus/types/src/block/beacon_block.rs b/consensus/types/src/block/beacon_block.rs index 5ca7ce065f..cc4d4906c7 100644 --- a/consensus/types/src/block/beacon_block.rs +++ b/consensus/types/src/block/beacon_block.rs @@ -19,9 +19,9 @@ use crate::{ attestation::{AttestationBase, AttestationData, IndexedAttestationBase}, block::{ BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyBellatrix, - BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyEip7805, - BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconBlockBodyRef, - BeaconBlockBodyRefMut, BeaconBlockHeader, SignedBeaconBlock, SignedBeaconBlockHeader, + BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu, + BeaconBlockBodyGloas, BeaconBlockBodyHeze, BeaconBlockBodyRef, BeaconBlockBodyRefMut, + BeaconBlockHeader, SignedBeaconBlock, SignedBeaconBlockHeader, }, core::{ChainSpec, Domain, Epoch, EthSpec, Graffiti, Hash256, SignedRoot, Slot}, deposit::{Deposit, DepositData}, @@ -39,7 +39,7 @@ use crate::{ /// A block of the `BeaconChain`. #[superstruct( - variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive( Debug, @@ -105,10 +105,10 @@ pub struct BeaconBlock = FullPayload pub body: BeaconBlockBodyElectra, #[superstruct(only(Fulu), partial_getter(rename = "body_fulu"))] pub body: BeaconBlockBodyFulu, - #[superstruct(only(Eip7805), partial_getter(rename = "body_eip7805"))] - pub body: BeaconBlockBodyEip7805, #[superstruct(only(Gloas), partial_getter(rename = "body_gloas"))] pub body: BeaconBlockBodyGloas, + #[superstruct(only(Heze), partial_getter(rename = "body_heze"))] + pub body: BeaconBlockBodyHeze, } pub type BlindedBeaconBlock = BeaconBlock>; @@ -161,9 +161,9 @@ impl> BeaconBlock { /// Usually it's better to prefer `from_ssz_bytes` which will decode the correct variant based /// on the fork slot. pub fn any_from_ssz_bytes(bytes: &[u8]) -> Result { - BeaconBlockGloas::from_ssz_bytes(bytes) - .map(BeaconBlock::Gloas) - .or_else(|_| BeaconBlockEip7805::from_ssz_bytes(bytes).map(BeaconBlock::Eip7805)) + BeaconBlockHeze::from_ssz_bytes(bytes) + .map(BeaconBlock::Heze) + .or_else(|_| BeaconBlockGloas::from_ssz_bytes(bytes).map(BeaconBlock::Gloas)) .or_else(|_| BeaconBlockFulu::from_ssz_bytes(bytes).map(BeaconBlock::Fulu)) .or_else(|_| BeaconBlockElectra::from_ssz_bytes(bytes).map(BeaconBlock::Electra)) .or_else(|_| BeaconBlockDeneb::from_ssz_bytes(bytes).map(BeaconBlock::Deneb)) @@ -264,8 +264,8 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockRef<'a, E, Payl BeaconBlockRef::Deneb { .. } => ForkName::Deneb, BeaconBlockRef::Electra { .. } => ForkName::Electra, BeaconBlockRef::Fulu { .. } => ForkName::Fulu, - BeaconBlockRef::Eip7805 { .. } => ForkName::Eip7805, BeaconBlockRef::Gloas { .. } => ForkName::Gloas, + BeaconBlockRef::Heze { .. } => ForkName::Heze, } } @@ -323,7 +323,6 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockRef<'a, E, Payl BeaconBlockRef::Deneb(block) => Some(block.body.blob_kzg_commitments.len()), BeaconBlockRef::Electra(block) => Some(block.body.blob_kzg_commitments.len()), BeaconBlockRef::Fulu(block) => Some(block.body.blob_kzg_commitments.len()), - BeaconBlockRef::Eip7805(block) => Some(block.body.blob_kzg_commitments.len()), BeaconBlockRef::Gloas(block) => Some( block .body @@ -332,6 +331,14 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockRef<'a, E, Payl .blob_kzg_commitments .len(), ), + BeaconBlockRef::Heze(block) => Some( + block + .body + .signed_execution_payload_bid + .message + .blob_kzg_commitments + .len(), + ), } } } @@ -664,37 +671,6 @@ impl> EmptyBlock for BeaconBlockElec } } -impl> EmptyBlock for BeaconBlockEip7805 { - /// Returns an empty Electra block to be used during genesis. - fn empty(spec: &ChainSpec) -> Self { - BeaconBlockEip7805 { - slot: spec.genesis_slot, - proposer_index: 0, - parent_root: Hash256::zero(), - state_root: Hash256::zero(), - body: BeaconBlockBodyEip7805 { - randao_reveal: Signature::empty(), - eth1_data: Eth1Data { - deposit_root: Hash256::zero(), - block_hash: Hash256::zero(), - deposit_count: 0, - }, - graffiti: Graffiti::default(), - proposer_slashings: VariableList::empty(), - attester_slashings: VariableList::empty(), - attestations: VariableList::empty(), - deposits: VariableList::empty(), - voluntary_exits: VariableList::empty(), - sync_aggregate: SyncAggregate::empty(), - execution_payload: Payload::Eip7805::default(), - bls_to_execution_changes: VariableList::empty(), - blob_kzg_commitments: VariableList::empty(), - execution_requests: ExecutionRequests::default(), - }, - } - } -} - impl> EmptyBlock for BeaconBlockFulu { /// Returns an empty Fulu block to be used during genesis. fn empty(spec: &ChainSpec) -> Self { @@ -761,6 +737,38 @@ impl> EmptyBlock for BeaconBlockGloa } } +impl> EmptyBlock for BeaconBlockHeze { + /// Returns an empty Heze block to be used during genesis. + fn empty(spec: &ChainSpec) -> Self { + BeaconBlockHeze { + slot: spec.genesis_slot, + proposer_index: 0, + parent_root: Hash256::zero(), + state_root: Hash256::zero(), + body: BeaconBlockBodyHeze { + randao_reveal: Signature::empty(), + eth1_data: Eth1Data { + deposit_root: Hash256::zero(), + block_hash: Hash256::zero(), + deposit_count: 0, + }, + graffiti: Graffiti::default(), + proposer_slashings: VariableList::empty(), + attester_slashings: VariableList::empty(), + attestations: VariableList::empty(), + deposits: VariableList::empty(), + voluntary_exits: VariableList::empty(), + sync_aggregate: SyncAggregate::empty(), + bls_to_execution_changes: VariableList::empty(), + parent_execution_requests: ExecutionRequests::default(), + signed_execution_payload_bid: SignedExecutionPayloadBid::empty(), + payload_attestations: VariableList::empty(), + _phantom: PhantomData, + }, + } + } +} + // TODO(EIP-7732) Mark's branch had the following implementation but not sure if it's needed so will just add header below for reference // impl> BeaconBlockEIP7732 { @@ -787,6 +795,29 @@ impl From>> } } +// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas +impl From>> + for BeaconBlockHeze> +{ + fn from(block: BeaconBlockHeze>) -> Self { + let BeaconBlockHeze { + slot, + proposer_index, + parent_root, + state_root, + body, + } = block; + + BeaconBlockHeze { + slot, + proposer_index, + parent_root, + state_root, + body: body.into(), + } + } +} + // We can convert pre-Bellatrix blocks without payloads into blocks "with" payloads. impl From>> for BeaconBlockBase> @@ -868,9 +899,9 @@ impl_from!(BeaconBlockBellatrix, >, >, |b impl_from!(BeaconBlockCapella, >, >, |body: BeaconBlockBodyCapella<_, _>| body.into()); impl_from!(BeaconBlockDeneb, >, >, |body: BeaconBlockBodyDeneb<_, _>| body.into()); impl_from!(BeaconBlockElectra, >, >, |body: BeaconBlockBodyElectra<_, _>| body.into()); -impl_from!(BeaconBlockEip7805, >, >, |body: BeaconBlockBodyEip7805<_, _>| body.into()); impl_from!(BeaconBlockFulu, >, >, |body: BeaconBlockBodyFulu<_, _>| body.into()); impl_from!(BeaconBlockGloas, >, >, |body: BeaconBlockBodyGloas<_, _>| body.into()); +impl_from!(BeaconBlockHeze, >, >, |body: BeaconBlockBodyHeze<_, _>| body.into()); // We can clone blocks with payloads to blocks without payloads, without cloning the payload. macro_rules! impl_clone_as_blinded { @@ -905,8 +936,8 @@ impl_clone_as_blinded!(BeaconBlockCapella, >, >, >); impl_clone_as_blinded!(BeaconBlockElectra, >, >); impl_clone_as_blinded!(BeaconBlockFulu, >, >); -impl_clone_as_blinded!(BeaconBlockEip7805, >, >); impl_clone_as_blinded!(BeaconBlockGloas, >, >); +impl_clone_as_blinded!(BeaconBlockHeze, >, >); // A reference to a full beacon block can be cloned into a blinded beacon block, without cloning the // execution payload. @@ -1080,19 +1111,19 @@ mod tests { } #[test] - fn roundtrip_eip7805_block() { + fn roundtrip_heze_block() { let rng = &mut XorShiftRng::from_seed([42; 16]); - let spec = &ForkName::Eip7805.make_genesis_spec(MainnetEthSpec::default_spec()); + let spec = &ForkName::Heze.make_genesis_spec(MainnetEthSpec::default_spec()); - let inner_block = BeaconBlockEip7805 { + let inner_block = BeaconBlockHeze { slot: Slot::random_for_test(rng), proposer_index: u64::random_for_test(rng), parent_root: Hash256::random_for_test(rng), state_root: Hash256::random_for_test(rng), - body: BeaconBlockBodyEip7805::random_for_test(rng), + body: BeaconBlockBodyHeze::random_for_test(rng), }; - let block = BeaconBlock::Eip7805(inner_block.clone()); + let block = BeaconBlock::Heze(inner_block.clone()); test_ssz_tree_hash_pair_with(&block, &inner_block, |bytes| { BeaconBlock::from_ssz_bytes(bytes, spec) @@ -1119,6 +1150,26 @@ mod tests { }); } + #[test] + fn roundtrip_heze_block() { + let rng = &mut XorShiftRng::from_seed([42; 16]); + let spec = &ForkName::Heze.make_genesis_spec(MainnetEthSpec::default_spec()); + + let inner_block = BeaconBlockHeze { + slot: Slot::random_for_test(rng), + proposer_index: u64::random_for_test(rng), + parent_root: Hash256::random_for_test(rng), + state_root: Hash256::random_for_test(rng), + body: BeaconBlockBodyHeze::random_for_test(rng), + }; + + let block = BeaconBlock::Heze(inner_block.clone()); + + test_ssz_tree_hash_pair_with(&block, &inner_block, |bytes| { + BeaconBlock::from_ssz_bytes(bytes, spec) + }); + } + #[test] fn roundtrip_gloas_block() { let rng = &mut XorShiftRng::from_seed([42; 16]); @@ -1158,20 +1209,23 @@ mod tests { let deneb_slot = deneb_epoch.start_slot(E::slots_per_epoch()); let electra_epoch = deneb_epoch + 1; let electra_slot = electra_epoch.start_slot(E::slots_per_epoch()); - let eip7805_epoch = electra_epoch + 1; - let eip7805_slot = eip7805_epoch.start_slot(E::slots_per_epoch()); - let fulu_epoch = eip7805_epoch + 1; + let heze_epoch = electra_epoch + 1; + let heze_slot = heze_epoch.start_slot(E::slots_per_epoch()); + let fulu_epoch = heze_epoch + 1; let fulu_slot = fulu_epoch.start_slot(E::slots_per_epoch()); let gloas_epoch = fulu_epoch + 1; let gloas_slot = gloas_epoch.start_slot(E::slots_per_epoch()); + let heze_epoch = gloas_epoch + 1; + let heze_slot = heze_epoch.start_slot(E::slots_per_epoch()); spec.altair_fork_epoch = Some(altair_epoch); spec.capella_fork_epoch = Some(capella_epoch); spec.deneb_fork_epoch = Some(deneb_epoch); spec.electra_fork_epoch = Some(electra_epoch); - spec.eip7805_fork_epoch = Some(eip7805_epoch); + spec.heze_fork_epoch = Some(heze_epoch); spec.fulu_fork_epoch = Some(fulu_epoch); spec.gloas_fork_epoch = Some(gloas_epoch); + spec.heze_fork_epoch = Some(heze_epoch); // BeaconBlockBase { @@ -1283,10 +1337,10 @@ mod tests { .expect_err("bad electra block cannot be decoded"); } - // BeaconBlockEip7805 + // BeaconBlockHeze { - let good_block = BeaconBlock::Eip7805(BeaconBlockEip7805 { - slot: eip7805_slot, + let good_block = BeaconBlock::Heze(BeaconBlockHeze { + slot: heze_slot, ..<_>::random_for_test(rng) }); // It's invalid to have an Electra block with a epoch lower than the fork epoch. @@ -1298,11 +1352,11 @@ mod tests { assert_eq!( BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec) - .expect("good eip7805 block can be decoded"), + .expect("good heze block can be decoded"), good_block ); BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec) - .expect_err("bad eip7805 block cannot be decoded"); + .expect_err("bad heze block cannot be decoded"); } // BeaconBlockFulu @@ -1343,5 +1397,29 @@ mod tests { //BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec) // .expect_err("bad gloas block cannot be decoded"); } + + // BeaconBlockHeze + { + let good_block = BeaconBlock::Heze(BeaconBlockHeze { + slot: heze_slot, + ..<_>::random_for_test(rng) + }); + let _bad_block = { + let mut bad = good_block.clone(); + *bad.slot_mut() = gloas_slot; + bad + }; + + assert_eq!( + BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec) + .expect("good heze block can be decoded"), + good_block + ); + + // TODO(heze): Uncomment once Heze has features since without features + // and with a Gloas slot it decodes successfully to Gloas. + //BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec) + // .expect_err("bad heze block cannot be decoded"); + } } } diff --git a/consensus/types/src/block/beacon_block_body.rs b/consensus/types/src/block/beacon_block_body.rs index a40c8bdc5a..d922611ad5 100644 --- a/consensus/types/src/block/beacon_block_body.rs +++ b/consensus/types/src/block/beacon_block_body.rs @@ -23,11 +23,11 @@ use crate::{ deposit::Deposit, execution::{ AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella, - BlindedPayloadDeneb, BlindedPayloadEip7805, BlindedPayloadElectra, BlindedPayloadFulu, + BlindedPayloadDeneb, BlindedPayloadHeze, BlindedPayloadElectra, BlindedPayloadFulu, Eth1Data, ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, - ExecutionPayloadDeneb, ExecutionPayloadEip7805, ExecutionPayloadElectra, + ExecutionPayloadDeneb, ExecutionPayloadHeze, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionRequests, FullPayload, - FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadEip7805, + FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadHeze, FullPayloadElectra, FullPayloadFulu, SignedBlsToExecutionChange, }, exit::SignedVoluntaryExit, @@ -56,7 +56,7 @@ pub const BLOB_KZG_COMMITMENTS_INDEX: usize = 11; /// /// This *superstruct* abstracts over the hard-fork. #[superstruct( - variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive( Debug, @@ -89,8 +89,8 @@ pub const BLOB_KZG_COMMITMENTS_INDEX: usize = 11; Deneb(metastruct(mappings(beacon_block_body_deneb_fields(groups(fields))))), Electra(metastruct(mappings(beacon_block_body_electra_fields(groups(fields))))), Fulu(metastruct(mappings(beacon_block_body_fulu_fields(groups(fields))))), - Eip7805(metastruct(mappings(beacon_block_body_eip7805_fields(groups(fields))))), Gloas(metastruct(mappings(beacon_block_body_gloas_fields(groups(fields))))), + Heze(metastruct(mappings(beacon_block_body_heze_fields(groups(fields))))), ), cast_error( ty = "BeaconStateError", @@ -122,7 +122,7 @@ pub struct BeaconBlockBody = FullPay )] pub attester_slashings: VariableList, E::MaxAttesterSlashings>, #[superstruct( - only(Electra, Fulu, Eip7805, Gloas), + only(Electra, Fulu, Gloas, Heze), partial_getter(rename = "attester_slashings_electra") )] pub attester_slashings: @@ -133,13 +133,13 @@ pub struct BeaconBlockBody = FullPay )] pub attestations: VariableList, E::MaxAttestations>, #[superstruct( - only(Electra, Fulu, Eip7805, Gloas), + only(Electra, Fulu, Gloas, Heze), partial_getter(rename = "attestations_electra") )] pub attestations: VariableList, E::MaxAttestationsElectra>, pub deposits: VariableList, pub voluntary_exits: VariableList, - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze))] pub sync_aggregate: SyncAggregate, // We flatten the execution payload so that serde can use the name of the inner type, // either `execution_payload` for full payloads, or `execution_payload_header` for blinded @@ -159,26 +159,23 @@ pub struct BeaconBlockBody = FullPay #[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))] #[serde(flatten)] pub execution_payload: Payload::Electra, - #[superstruct(only(Eip7805), partial_getter(rename = "execution_payload_eip7805"))] - #[serde(flatten)] - pub execution_payload: Payload::Eip7805, #[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))] #[serde(flatten)] pub execution_payload: Payload::Fulu, - #[superstruct(only(Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas, Heze))] pub bls_to_execution_changes: VariableList, - #[superstruct(only(Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Deneb, Electra, Fulu))] pub blob_kzg_commitments: KzgCommitments, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Fulu))] pub execution_requests: ExecutionRequests, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub signed_execution_payload_bid: SignedExecutionPayloadBid, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub payload_attestations: VariableList, E::MaxPayloadAttestations>, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub parent_execution_requests: ExecutionRequests, - #[superstruct(only(Base, Altair, Gloas))] + #[superstruct(only(Base, Altair, Gloas, Heze))] #[metastruct(exclude_from(fields))] #[ssz(skip_serializing, skip_deserializing)] #[tree_hash(skip_hashing)] @@ -206,9 +203,9 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, Self::Capella(body) => Ok(Payload::Ref::from(&body.execution_payload)), Self::Deneb(body) => Ok(Payload::Ref::from(&body.execution_payload)), Self::Electra(body) => Ok(Payload::Ref::from(&body.execution_payload)), - Self::Eip7805(body) => Ok(Payload::Ref::from(&body.execution_payload)), Self::Fulu(body) => Ok(Payload::Ref::from(&body.execution_payload)), Self::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant), + Self::Heze(_) => Err(BeaconStateError::IncorrectStateVariant), } } @@ -239,8 +236,8 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, beacon_block_body_electra_fields!(body, |_, field| leaves .push(field.tree_hash_root())); } - Self::Eip7805(body) => { - beacon_block_body_eip7805_fields!(body, |_, field| leaves + Self::Heze(body) => { + beacon_block_body_heze_fields!(body, |_, field| leaves .push(field.tree_hash_root())); } Self::Fulu(body) => { @@ -251,6 +248,10 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, beacon_block_body_gloas_fields!(body, |_, field| leaves .push(field.tree_hash_root())); } + Self::Heze(body) => { + beacon_block_body_heze_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } } leaves } @@ -281,8 +282,9 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, | Self::Altair(_) | Self::Bellatrix(_) | Self::Capella(_) - | Self::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant), - Self::Deneb(_) | Self::Electra(_) | Self::Fulu(_) | Self::Eip7805(_) => { + | Self::Gloas(_) + | Self::Heze(_) => Err(BeaconStateError::IncorrectStateVariant), + Self::Deneb(_) | Self::Electra(_) | Self::Fulu(_) => { complete_kzg_commitment_merkle_proof::( self.blob_kzg_commitments()?, index, @@ -364,9 +366,10 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, Self::Capella(body) => Box::new(body.attestations.iter().map(AttestationRef::Base)), Self::Deneb(body) => Box::new(body.attestations.iter().map(AttestationRef::Base)), Self::Electra(body) => Box::new(body.attestations.iter().map(AttestationRef::Electra)), - Self::Eip7805(body) => Box::new(body.attestations.iter().map(AttestationRef::Electra)), + Self::Heze(body) => Box::new(body.attestations.iter().map(AttestationRef::Electra)), Self::Fulu(body) => Box::new(body.attestations.iter().map(AttestationRef::Electra)), Self::Gloas(body) => Box::new(body.attestations.iter().map(AttestationRef::Electra)), + Self::Heze(body) => Box::new(body.attestations.iter().map(AttestationRef::Electra)), } } @@ -402,7 +405,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, .iter() .map(AttesterSlashingRef::Electra), ), - Self::Eip7805(body) => Box::new( + Self::Heze(body) => Box::new( body.attester_slashings .iter() .map(AttesterSlashingRef::Electra), @@ -417,6 +420,11 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, .iter() .map(AttesterSlashingRef::Electra), ), + Self::Heze(body) => Box::new( + body.attester_slashings + .iter() + .map(AttesterSlashingRef::Electra), + ), } } } @@ -442,7 +450,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRefMut<'a, Self::Electra(body) => { Box::new(body.attestations.iter_mut().map(AttestationRefMut::Electra)) } - Self::Eip7805(body) => { + Self::Heze(body) => { Box::new(body.attestations.iter_mut().map(AttestationRefMut::Electra)) } Self::Fulu(body) => { @@ -451,6 +459,9 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRefMut<'a, Self::Gloas(body) => { Box::new(body.attestations.iter_mut().map(AttestationRefMut::Electra)) } + Self::Heze(body) => { + Box::new(body.attestations.iter_mut().map(AttestationRefMut::Electra)) + } } } } @@ -465,9 +476,10 @@ impl> BeaconBlockBodyRef<'_, E, Payl BeaconBlockBodyRef::Capella { .. } => ForkName::Capella, BeaconBlockBodyRef::Deneb { .. } => ForkName::Deneb, BeaconBlockBodyRef::Electra { .. } => ForkName::Electra, - BeaconBlockBodyRef::Eip7805 { .. } => ForkName::Eip7805, + BeaconBlockBodyRef::Heze { .. } => ForkName::Heze, BeaconBlockBodyRef::Fulu { .. } => ForkName::Fulu, BeaconBlockBodyRef::Gloas { .. } => ForkName::Gloas, + BeaconBlockBodyRef::Heze { .. } => ForkName::Heze, } } } @@ -577,6 +589,48 @@ impl From>> } } +// Post-Fulu block bodies without payloads can be converted into block bodies with payloads +// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas +impl From>> + for BeaconBlockBodyHeze> +{ + fn from(body: BeaconBlockBodyHeze>) -> Self { + let BeaconBlockBodyHeze { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + bls_to_execution_changes, + parent_execution_requests, + signed_execution_payload_bid, + payload_attestations, + _phantom, + } = body; + + BeaconBlockBodyHeze { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + bls_to_execution_changes, + parent_execution_requests, + signed_execution_payload_bid, + payload_attestations, + _phantom: PhantomData, + } + } +} + // Likewise bodies with payloads can be transformed into bodies without. impl From>> for ( @@ -824,52 +878,6 @@ impl From>> } } -impl From>> - for ( - BeaconBlockBodyEip7805>, - Option>, - ) -{ - fn from(body: BeaconBlockBodyEip7805>) -> Self { - let BeaconBlockBodyEip7805 { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - execution_payload: FullPayloadEip7805 { execution_payload }, - bls_to_execution_changes, - blob_kzg_commitments, - execution_requests, - } = body; - - ( - BeaconBlockBodyEip7805 { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - execution_payload: BlindedPayloadEip7805 { - execution_payload_header: From::from(&execution_payload), - }, - bls_to_execution_changes, - blob_kzg_commitments: blob_kzg_commitments.clone(), - execution_requests, - }, - Some(execution_payload), - ) - } -} - impl From>> for ( BeaconBlockBodyFulu>, @@ -962,6 +970,52 @@ impl From>> } } +impl From>> + for ( + BeaconBlockBodyHeze>, + Option>, + ) +{ + fn from(body: BeaconBlockBodyHeze>) -> Self { + let BeaconBlockBodyHeze { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + bls_to_execution_changes, + parent_execution_requests, + signed_execution_payload_bid, + payload_attestations, + _phantom, + } = body; + + ( + BeaconBlockBodyHeze { + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + bls_to_execution_changes, + parent_execution_requests, + signed_execution_payload_bid, + payload_attestations, + _phantom: PhantomData, + }, + None, + ) + } +} + // We can clone a full block into a blinded block, without cloning the payload. impl BeaconBlockBodyBase> { pub fn clone_as_blinded(&self) -> BeaconBlockBodyBase> { @@ -1117,44 +1171,6 @@ impl BeaconBlockBodyElectra> { } } -impl BeaconBlockBodyEip7805> { - pub fn clone_as_blinded(&self) -> BeaconBlockBodyEip7805> { - let BeaconBlockBodyEip7805 { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - execution_payload: FullPayloadEip7805 { execution_payload }, - bls_to_execution_changes, - blob_kzg_commitments, - execution_requests, - } = self; - - BeaconBlockBodyEip7805 { - randao_reveal: randao_reveal.clone(), - eth1_data: eth1_data.clone(), - graffiti: *graffiti, - proposer_slashings: proposer_slashings.clone(), - attester_slashings: attester_slashings.clone(), - attestations: attestations.clone(), - deposits: deposits.clone(), - voluntary_exits: voluntary_exits.clone(), - sync_aggregate: sync_aggregate.clone(), - execution_payload: BlindedPayloadEip7805 { - execution_payload_header: execution_payload.into(), - }, - bls_to_execution_changes: bls_to_execution_changes.clone(), - blob_kzg_commitments: blob_kzg_commitments.clone(), - execution_requests: execution_requests.clone(), - } - } -} - impl BeaconBlockBodyFulu> { pub fn clone_as_blinded(&self) -> BeaconBlockBodyFulu> { let BeaconBlockBodyFulu { @@ -1200,6 +1216,13 @@ impl BeaconBlockBodyGloas> { } } +impl BeaconBlockBodyHeze> { + pub fn clone_as_blinded(&self) -> BeaconBlockBodyHeze> { + let (block_body, _payload) = self.clone().into(); + block_body + } +} + impl From>> for ( BeaconBlockBody>, diff --git a/consensus/types/src/block/mod.rs b/consensus/types/src/block/mod.rs index 94c4a1da8d..d7e58f025f 100644 --- a/consensus/types/src/block/mod.rs +++ b/consensus/types/src/block/mod.rs @@ -6,21 +6,21 @@ mod signed_beacon_block_header; pub use beacon_block::{ BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockBellatrix, BeaconBlockCapella, - BeaconBlockDeneb, BeaconBlockEip7805, BeaconBlockElectra, BeaconBlockFulu, BeaconBlockGloas, + BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu, BeaconBlockGloas, BeaconBlockHeze, BeaconBlockRef, BeaconBlockRefMut, BlindedBeaconBlock, BlockImportSource, EmptyBlock, }; pub use beacon_block_body::{ BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockBody, BeaconBlockBodyAltair, BeaconBlockBodyBase, - BeaconBlockBodyBellatrix, BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyEip7805, - BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconBlockBodyRef, + BeaconBlockBodyBellatrix, BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, + BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconBlockBodyHeze, BeaconBlockBodyRef, BeaconBlockBodyRefMut, NUM_BEACON_BLOCK_BODY_HASH_TREE_ROOT_LEAVES, }; pub use beacon_block_header::BeaconBlockHeader; pub use signed_beacon_block::{ SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix, - SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockEip7805, - SignedBeaconBlockElectra, SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBeaconBlockHash, + SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra, + SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBeaconBlockHash, SignedBeaconBlockHeze, SignedBlindedBeaconBlock, ssz_tagged_signed_beacon_block, ssz_tagged_signed_beacon_block_arc, }; pub use signed_beacon_block_header::SignedBeaconBlockHeader; diff --git a/consensus/types/src/block/signed_beacon_block.rs b/consensus/types/src/block/signed_beacon_block.rs index 8660094bae..8f3378e91d 100644 --- a/consensus/types/src/block/signed_beacon_block.rs +++ b/consensus/types/src/block/signed_beacon_block.rs @@ -18,19 +18,18 @@ use crate::{ block::{ BLOB_KZG_COMMITMENTS_INDEX, BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockBellatrix, BeaconBlockBodyBellatrix, BeaconBlockBodyCapella, - BeaconBlockBodyDeneb, BeaconBlockBodyEip7805, BeaconBlockBodyElectra, BeaconBlockBodyFulu, - BeaconBlockCapella, BeaconBlockDeneb, BeaconBlockEip7805, BeaconBlockElectra, - BeaconBlockFulu, BeaconBlockGloas, BeaconBlockHeader, BeaconBlockRef, BeaconBlockRefMut, - SignedBeaconBlockHeader, + BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockCapella, + BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu, BeaconBlockGloas, BeaconBlockHeader, + BeaconBlockHeze, BeaconBlockRef, BeaconBlockRefMut, SignedBeaconBlockHeader, }, core::{ChainSpec, Domain, Epoch, EthSpec, Hash256, SignedRoot, SigningData, Slot}, execution::{ AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella, - BlindedPayloadDeneb, BlindedPayloadEip7805, BlindedPayloadElectra, BlindedPayloadFulu, + BlindedPayloadDeneb, BlindedPayloadHeze, BlindedPayloadElectra, BlindedPayloadFulu, ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, - ExecutionPayloadDeneb, ExecutionPayloadEip7805, ExecutionPayloadElectra, + ExecutionPayloadDeneb, ExecutionPayloadHeze, ExecutionPayloadElectra, ExecutionPayloadFulu, FullPayload, FullPayloadBellatrix, FullPayloadCapella, - FullPayloadDeneb, FullPayloadEip7805, FullPayloadElectra, FullPayloadFulu, + FullPayloadDeneb, FullPayloadHeze, FullPayloadElectra, FullPayloadFulu, }, fork::{Fork, ForkName, ForkVersionDecode, InconsistentFork, map_fork_name}, kzg_ext::format_kzg_commitments, @@ -68,7 +67,7 @@ impl From for Hash256 { /// A `BeaconBlock` and a signature from its proposer. #[superstruct( - variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive( Debug, @@ -117,12 +116,12 @@ pub struct SignedBeaconBlock = FullP pub message: BeaconBlockDeneb, #[superstruct(only(Electra), partial_getter(rename = "message_electra"))] pub message: BeaconBlockElectra, - #[superstruct(only(Eip7805), partial_getter(rename = "message_eip7805"))] - pub message: BeaconBlockEip7805, #[superstruct(only(Fulu), partial_getter(rename = "message_fulu"))] pub message: BeaconBlockFulu, #[superstruct(only(Gloas), partial_getter(rename = "message_gloas"))] pub message: BeaconBlockGloas, + #[superstruct(only(Heze), partial_getter(rename = "message_heze"))] + pub message: BeaconBlockHeze, pub signature: Signature, } @@ -206,8 +205,8 @@ impl> SignedBeaconBlock BeaconBlock::Electra(message) => { SignedBeaconBlock::Electra(SignedBeaconBlockElectra { message, signature }) } - BeaconBlock::Eip7805(message) => { - SignedBeaconBlock::Eip7805(SignedBeaconBlockEip7805 { message, signature }) + BeaconBlock::Heze(message) => { + SignedBeaconBlock::Heze(SignedBeaconBlockHeze { message, signature }) } BeaconBlock::Fulu(message) => { SignedBeaconBlock::Fulu(SignedBeaconBlockFulu { message, signature }) @@ -215,6 +214,9 @@ impl> SignedBeaconBlock BeaconBlock::Gloas(message) => { SignedBeaconBlock::Gloas(SignedBeaconBlockGloas { message, signature }) } + BeaconBlock::Heze(message) => { + SignedBeaconBlock::Heze(SignedBeaconBlockHeze { message, signature }) + } } } @@ -659,64 +661,6 @@ impl SignedBeaconBlockElectra> { } } -impl SignedBeaconBlockEip7805> { - pub fn into_full_block( - self, - execution_payload: ExecutionPayloadEip7805, - ) -> SignedBeaconBlockEip7805> { - let SignedBeaconBlockEip7805 { - message: - BeaconBlockEip7805 { - slot, - proposer_index, - parent_root, - state_root, - body: - BeaconBlockBodyEip7805 { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - execution_payload: BlindedPayloadEip7805 { .. }, - bls_to_execution_changes, - blob_kzg_commitments, - execution_requests, - }, - }, - signature, - } = self; - SignedBeaconBlockEip7805 { - message: BeaconBlockEip7805 { - slot, - proposer_index, - parent_root, - state_root, - body: BeaconBlockBodyEip7805 { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - execution_payload: FullPayloadEip7805 { execution_payload }, - bls_to_execution_changes, - blob_kzg_commitments, - execution_requests, - }, - }, - signature, - } - } -} - impl SignedBeaconBlockFulu> { pub fn into_full_block( self, @@ -789,6 +733,19 @@ impl From>> } } +// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas +impl From>> + for SignedBeaconBlockHeze> +{ + fn from(signed_block: SignedBeaconBlockHeze>) -> Self { + let SignedBeaconBlockHeze { message, signature } = signed_block; + SignedBeaconBlockHeze { + message: message.into(), + signature, + } + } +} + impl SignedBeaconBlock> { pub fn try_into_full_block( self, @@ -809,22 +766,19 @@ impl SignedBeaconBlock> { (SignedBeaconBlock::Electra(block), Some(ExecutionPayload::Electra(payload))) => { SignedBeaconBlock::Electra(block.into_full_block(payload)) } - (SignedBeaconBlock::Eip7805(block), Some(ExecutionPayload::Eip7805(payload))) => { - SignedBeaconBlock::Eip7805(block.into_full_block(payload)) - } (SignedBeaconBlock::Fulu(block), Some(ExecutionPayload::Fulu(payload))) => { SignedBeaconBlock::Fulu(block.into_full_block(payload)) } (SignedBeaconBlock::Gloas(block), _) => SignedBeaconBlock::Gloas(block.into()), + (SignedBeaconBlock::Heze(block), _) => SignedBeaconBlock::Heze(block.into()), // avoid wildcard matching forks so that compiler will // direct us here when a new fork has been added (SignedBeaconBlock::Bellatrix(_), _) => return None, (SignedBeaconBlock::Capella(_), _) => return None, (SignedBeaconBlock::Deneb(_), _) => return None, (SignedBeaconBlock::Electra(_), _) => return None, - (SignedBeaconBlock::Eip7805(_), _) => return None, (SignedBeaconBlock::Fulu(_), _) => return None, - // TODO(EIP-7732) Determine if need a match arm for gloas here + // TODO(EIP-7732) Determine if need a match arm for gloas/heze here }; Some(full_block) } @@ -967,8 +921,8 @@ pub mod ssz_tagged_signed_beacon_block { ForkName::Electra => Ok(SignedBeaconBlock::Electra( SignedBeaconBlockElectra::from_ssz_bytes(body)?, )), - ForkName::Eip7805 => Ok(SignedBeaconBlock::Eip7805( - SignedBeaconBlockEip7805::from_ssz_bytes(body)?, + ForkName::Heze => Ok(SignedBeaconBlock::Heze( + SignedBeaconBlockHeze::from_ssz_bytes(body)?, )), ForkName::Fulu => Ok(SignedBeaconBlock::Fulu( SignedBeaconBlockFulu::from_ssz_bytes(body)?, @@ -976,6 +930,9 @@ pub mod ssz_tagged_signed_beacon_block { ForkName::Gloas => Ok(SignedBeaconBlock::Gloas( SignedBeaconBlockGloas::from_ssz_bytes(body)?, )), + ForkName::Heze => Ok(SignedBeaconBlock::Heze( + SignedBeaconBlockHeze::from_ssz_bytes(body)?, + )), } } } @@ -1057,6 +1014,7 @@ mod test { chain_spec.electra_fork_epoch = Some(Epoch::new(5)); chain_spec.fulu_fork_epoch = Some(Epoch::new(6)); chain_spec.gloas_fork_epoch = Some(Epoch::new(7)); + chain_spec.heze_fork_epoch = Some(Epoch::new(8)); // check that we have all forks covered assert!(chain_spec.fork_epoch(ForkName::latest()).is_some()); @@ -1099,10 +1057,10 @@ mod test { sig.clone(), ), SignedBeaconBlock::from_block( - BeaconBlock::Eip7805(BeaconBlockEip7805::empty(spec)), + BeaconBlock::Gloas(BeaconBlockGloas::empty(spec)), sig.clone(), ), - SignedBeaconBlock::from_block(BeaconBlock::Gloas(BeaconBlockGloas::empty(spec)), sig), + SignedBeaconBlock::from_block(BeaconBlock::Heze(BeaconBlockHeze::empty(spec)), sig), ]; for block in blocks { diff --git a/consensus/types/src/builder/builder_bid.rs b/consensus/types/src/builder/builder_bid.rs index 393a89f526..c6f5b7c9bb 100644 --- a/consensus/types/src/builder/builder_bid.rs +++ b/consensus/types/src/builder/builder_bid.rs @@ -12,7 +12,7 @@ use crate::{ core::{ChainSpec, EthSpec, SignedRoot, Uint256}, execution::{ ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella, - ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderEip7805, ExecutionPayloadHeaderElectra, + ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderHeze, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, ExecutionRequests, }, @@ -22,7 +22,7 @@ use crate::{ }; #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu), + variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu), variant_attributes( derive( PartialEq, @@ -53,13 +53,13 @@ pub struct BuilderBid { pub header: ExecutionPayloadHeaderDeneb, #[superstruct(only(Electra), partial_getter(rename = "header_electra"))] pub header: ExecutionPayloadHeaderElectra, - #[superstruct(only(Eip7805), partial_getter(rename = "header_eip7805"))] - pub header: ExecutionPayloadHeaderEip7805, + #[superstruct(only(Heze), partial_getter(rename = "header_heze"))] + pub header: ExecutionPayloadHeaderHeze, #[superstruct(only(Fulu), partial_getter(rename = "header_fulu"))] pub header: ExecutionPayloadHeaderFulu, - #[superstruct(only(Deneb, Electra, Eip7805, Fulu))] + #[superstruct(only(Deneb, Electra, Heze, Fulu))] pub blob_kzg_commitments: KzgCommitments, - #[superstruct(only(Electra, Eip7805, Fulu))] + #[superstruct(only(Electra, Heze, Fulu))] pub execution_requests: ExecutionRequests, #[serde(with = "serde_utils::quoted_u256")] pub value: Uint256, @@ -103,7 +103,7 @@ impl ForkVersionDecode for BuilderBid { ForkName::Capella => BuilderBid::Capella(BuilderBidCapella::from_ssz_bytes(bytes)?), ForkName::Deneb => BuilderBid::Deneb(BuilderBidDeneb::from_ssz_bytes(bytes)?), ForkName::Electra => BuilderBid::Electra(BuilderBidElectra::from_ssz_bytes(bytes)?), - ForkName::Eip7805 => BuilderBid::Eip7805(BuilderBidEip7805::from_ssz_bytes(bytes)?), + ForkName::Heze => BuilderBid::Heze(BuilderBidHeze::from_ssz_bytes(bytes)?), ForkName::Fulu => BuilderBid::Fulu(BuilderBidFulu::from_ssz_bytes(bytes)?), }; Ok(builder_bid) @@ -157,12 +157,12 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for BuilderBid { ForkName::Electra => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Eip7805 => { - Self::Eip7805(Deserialize::deserialize(deserializer).map_err(convert_err)?) - } ForkName::Fulu => { Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?) } + ForkName::Heze => { + Self::Heze(Deserialize::deserialize(deserializer).map_err(convert_err)?) + } ForkName::Base | ForkName::Altair | ForkName::Gloas => { return Err(serde::de::Error::custom(format!( "BuilderBid failed to deserialize: unsupported fork '{}'", diff --git a/consensus/types/src/builder/mod.rs b/consensus/types/src/builder/mod.rs index 2ec489a3ca..983dccc232 100644 --- a/consensus/types/src/builder/mod.rs +++ b/consensus/types/src/builder/mod.rs @@ -6,7 +6,7 @@ mod proposer_preferences; pub use builder::{Builder, BuilderIndex}; pub use builder_bid::{ - BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidEip7805, + BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidHeze, BuilderBidElectra, BuilderBidFulu, SignedBuilderBid, }; pub use builder_pending_payment::BuilderPendingPayment; diff --git a/consensus/types/src/core/chain_spec.rs b/consensus/types/src/core/chain_spec.rs index d5262acbdb..e6cf1a01e3 100644 --- a/consensus/types/src/core/chain_spec.rs +++ b/consensus/types/src/core/chain_spec.rs @@ -235,8 +235,6 @@ pub struct ChainSpec { */ pub domain_inclusion_list_committee: u32, pub inclusion_list_committee_size: u64, - pub eip7805_fork_epoch: Option, - pub eip7805_fork_version: [u8; 4], /* * Fulu hard fork params @@ -264,6 +262,13 @@ pub struct ChainSpec { pub consolidation_churn_limit_quotient: u64, pub max_per_epoch_activation_churn_limit_gloas: u64, + /* + * Heze hard fork params + */ + pub heze_fork_version: [u8; 4], + /// The Heze fork epoch is optional, with `None` representing "Heze never happens". + pub heze_fork_epoch: Option, + /* * Networking */ @@ -386,8 +391,8 @@ impl ChainSpec { /// Returns the name of the fork which is active at `epoch`. pub fn fork_name_at_epoch(&self, epoch: Epoch) -> ForkName { let forks = [ + (self.heze_fork_epoch, ForkName::Heze), (self.gloas_fork_epoch, ForkName::Gloas), - (self.eip7805_fork_epoch, ForkName::Eip7805), (self.fulu_fork_epoch, ForkName::Fulu), (self.electra_fork_epoch, ForkName::Electra), (self.deneb_fork_epoch, ForkName::Deneb), @@ -417,9 +422,9 @@ impl ChainSpec { ForkName::Capella => self.capella_fork_version, ForkName::Deneb => self.deneb_fork_version, ForkName::Electra => self.electra_fork_version, - ForkName::Eip7805 => self.eip7805_fork_version, ForkName::Fulu => self.fulu_fork_version, ForkName::Gloas => self.gloas_fork_version, + ForkName::Heze => self.heze_fork_version, } } @@ -437,9 +442,9 @@ impl ChainSpec { ForkName::Capella => self.capella_fork_epoch, ForkName::Deneb => self.deneb_fork_epoch, ForkName::Electra => self.electra_fork_epoch, - ForkName::Eip7805 => self.eip7805_fork_epoch, ForkName::Fulu => self.fulu_fork_epoch, ForkName::Gloas => self.gloas_fork_epoch, + ForkName::Heze => self.heze_fork_epoch, } } @@ -478,16 +483,16 @@ impl ChainSpec { .is_some_and(|fulu_fork_epoch| fulu_fork_epoch != self.far_future_epoch) } - /// Returns true if the given epoch is greater than or equal to the `EIP7805_FORK_EPOCH`. + /// Returns true if the given epoch is greater than or equal to the `HEZE_FORK_EPOCH`. pub fn is_focil_enabled_for_epoch(&self, block_epoch: Epoch) -> bool { - self.eip7805_fork_epoch - .is_some_and(|eip7805_fork_epoch| block_epoch >= eip7805_fork_epoch) + self.heze_fork_epoch + .is_some_and(|heze_fork_epoch| block_epoch >= heze_fork_epoch) } - /// Returns true if `EIP7805_FORK_EPOCH` is set and is not set to `FAR_FUTURE_EPOCH`. + /// Returns true if `HEZE_FORK_EPOCH` is set and is not set to `FAR_FUTURE_EPOCH`. pub fn is_focil_scheduled(&self) -> bool { - self.eip7805_fork_epoch - .is_some_and(|eip7805_fork_epoch| eip7805_fork_epoch != self.far_future_epoch) + self.heze_fork_epoch + .is_some_and(|heze_fork_epoch| heze_fork_epoch != self.far_future_epoch) } /// Returns true if `GLOAS_FORK_EPOCH` is set and is not set to `FAR_FUTURE_EPOCH`. @@ -496,6 +501,12 @@ impl ChainSpec { .is_some_and(|gloas_fork_epoch| gloas_fork_epoch != self.far_future_epoch) } + /// Returns true if `HEZE_FORK_EPOCH` is set and is not set to `FAR_FUTURE_EPOCH`. + pub fn is_heze_scheduled(&self) -> bool { + self.heze_fork_epoch + .is_some_and(|heze_fork_epoch| heze_fork_epoch != self.far_future_epoch) + } + /// Returns a full `Fork` struct for a given epoch. pub fn fork_at_epoch(&self, epoch: Epoch) -> Fork { let current_fork_name = self.fork_name_at_epoch(epoch); @@ -1281,8 +1292,6 @@ impl ChainSpec { */ domain_inclusion_list_committee: 12, inclusion_list_committee_size: 16, - eip7805_fork_epoch: None, - eip7805_fork_version: [0x06, 0x00, 0x00, 0x00], /* * Fulu hard fork params @@ -1314,6 +1323,12 @@ impl ChainSpec { .expect("calculation does not overflow"), max_request_payloads: 128, + /* + * Heze hard fork params + */ + heze_fork_version: [0x08, 0x00, 0x00, 0x00], + heze_fork_epoch: None, + /* * Network specific */ @@ -1451,9 +1466,6 @@ impl ChainSpec { u64::checked_pow(2, 7)?.checked_mul(u64::checked_pow(10, 9)?) }) .expect("calculation does not overflow"), - // FOCIL - eip7805_fork_epoch: None, - eip7805_fork_version: [0x06, 0x00, 0x00, 0x00], // Fulu fulu_fork_version: [0x07, 0x00, 0x00, 0x00], fulu_fork_epoch: None, @@ -1469,6 +1481,9 @@ impl ChainSpec { u64::checked_pow(2, 7)?.checked_mul(u64::checked_pow(10, 9)?) }) .expect("calculation does not overflow"), + // Heze + heze_fork_version: [0x08, 0x00, 0x00, 0x01], + heze_fork_epoch: None, /* * Derived time values (set by `compute_derived_values()`) @@ -1715,8 +1730,6 @@ impl ChainSpec { */ domain_inclusion_list_committee: 12, inclusion_list_committee_size: 16, - eip7805_fork_epoch: None, - eip7805_fork_version: [0x06, 0x00, 0x00, 0x00], /* * Fulu hard fork params @@ -1748,6 +1761,12 @@ impl ChainSpec { .expect("calculation does not overflow"), max_request_payloads: 128, + /* + * Heze hard fork params + */ + heze_fork_version: [0x08, 0x00, 0x00, 0x64], + heze_fork_epoch: None, + /* * Network specific */ @@ -2014,14 +2033,6 @@ pub struct Config { #[serde(deserialize_with = "deserialize_fork_epoch")] pub fulu_fork_epoch: Option>, - #[serde(default = "default_eip7805_fork_version")] - #[serde(with = "serde_utils::bytes_4_hex")] - eip7805_fork_version: [u8; 4], - #[serde(default)] - #[serde(serialize_with = "serialize_fork_epoch")] - #[serde(deserialize_with = "deserialize_fork_epoch")] - pub eip7805_fork_epoch: Option>, - #[serde(default = "default_gloas_fork_version")] #[serde(with = "serde_utils::bytes_4_hex")] gloas_fork_version: [u8; 4], @@ -2030,6 +2041,14 @@ pub struct Config { #[serde(deserialize_with = "deserialize_fork_epoch")] pub gloas_fork_epoch: Option>, + #[serde(default = "default_heze_fork_version")] + #[serde(with = "serde_utils::bytes_4_hex")] + heze_fork_version: [u8; 4], + #[serde(default)] + #[serde(serialize_with = "serialize_fork_epoch")] + #[serde(deserialize_with = "deserialize_fork_epoch")] + pub heze_fork_epoch: Option>, + #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] seconds_per_slot: Option>, @@ -2235,7 +2254,7 @@ fn default_electra_fork_version() -> [u8; 4] { [0xff, 0xff, 0xff, 0xff] } -fn default_eip7805_fork_version() -> [u8; 4] { +fn default_heze_fork_version() -> [u8; 4] { // This value shouldn't be used. [0xff, 0xff, 0xff, 0xff] } @@ -2633,16 +2652,16 @@ impl Config { .fulu_fork_epoch .map(|epoch| MaybeQuoted { value: epoch }), - eip7805_fork_version: spec.eip7805_fork_version, - eip7805_fork_epoch: spec - .eip7805_fork_epoch - .map(|epoch| MaybeQuoted { value: epoch }), - gloas_fork_version: spec.gloas_fork_version, gloas_fork_epoch: spec .gloas_fork_epoch .map(|epoch| MaybeQuoted { value: epoch }), + heze_fork_version: spec.heze_fork_version, + heze_fork_epoch: spec + .heze_fork_epoch + .map(|epoch| MaybeQuoted { value: epoch }), + seconds_per_slot: Some(MaybeQuoted { value: spec.seconds_per_slot, }), @@ -2761,12 +2780,12 @@ impl Config { deneb_fork_version, electra_fork_epoch, electra_fork_version, - eip7805_fork_version, - eip7805_fork_epoch, fulu_fork_epoch, fulu_fork_version, gloas_fork_version, gloas_fork_epoch, + heze_fork_version, + heze_fork_epoch, seconds_per_slot, slot_duration_ms, seconds_per_eth1_block, @@ -2861,12 +2880,12 @@ impl Config { deneb_fork_version, electra_fork_epoch: electra_fork_epoch.map(|q| q.value), electra_fork_version, - eip7805_fork_version, - eip7805_fork_epoch: eip7805_fork_epoch.map(|q| q.value), fulu_fork_epoch: fulu_fork_epoch.map(|q| q.value), fulu_fork_version, gloas_fork_version, gloas_fork_epoch: gloas_fork_epoch.map(|q| q.value), + heze_fork_version, + heze_fork_epoch: heze_fork_epoch.map(|q| q.value), seconds_per_slot: seconds_per_slot .map(|q| q.value) .or_else(|| slot_duration_ms.and_then(|q| q.value.checked_div(1000)))?, @@ -3842,8 +3861,6 @@ mod yaml_tests { /// list as new forks are added. const UPSTREAM_KEYS_NOT_IN_LIGHTHOUSE: &[&str] = &[ // Forks not yet implemented - "HEZE_FORK_VERSION", - "HEZE_FORK_EPOCH", "EIP7928_FORK_VERSION", "EIP7928_FORK_EPOCH", // Gloas params not yet in Config diff --git a/consensus/types/src/core/config_and_preset.rs b/consensus/types/src/core/config_and_preset.rs index b2cd9c889b..94f002c88c 100644 --- a/consensus/types/src/core/config_and_preset.rs +++ b/consensus/types/src/core/config_and_preset.rs @@ -6,14 +6,14 @@ use superstruct::superstruct; use crate::core::{ AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, ChainSpec, Config, DenebPreset, - Eip7805Preset, ElectraPreset, EthSpec, FuluPreset, GloasPreset, consts, + ElectraPreset, EthSpec, FuluPreset, GloasPreset, HezePreset, consts, }; /// Fusion of a runtime-config with the compile-time preset values. /// /// Mostly useful for the API. #[superstruct( - variants(Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Deneb, Electra, Fulu, Gloas, Heze), variant_attributes(derive(Serialize, Deserialize, Debug, PartialEq, Clone)) )] #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] @@ -32,18 +32,18 @@ pub struct ConfigAndPreset { pub capella_preset: CapellaPreset, #[serde(flatten)] pub deneb_preset: DenebPreset, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] #[serde(flatten)] pub electra_preset: ElectraPreset, - #[superstruct(only(Fulu, Eip7805, Gloas))] + #[superstruct(only(Fulu, Gloas, Heze))] #[serde(flatten)] pub fulu_preset: FuluPreset, - #[superstruct(only(Eip7805, Gloas))] - #[serde(flatten)] - pub eip7805_preset: Eip7805Preset, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[serde(flatten)] pub gloas_preset: GloasPreset, + #[superstruct(only(Heze))] + #[serde(flatten)] + pub heze_preset: HezePreset, /// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks. #[serde(flatten)] pub extra_fields: HashMap, @@ -59,10 +59,28 @@ impl ConfigAndPreset { let deneb_preset = DenebPreset::from_chain_spec::(spec); let extra_fields = get_extra_fields(spec); - if spec.is_gloas_scheduled() { + if spec.is_heze_scheduled() { + let electra_preset = ElectraPreset::from_chain_spec::(spec); + let fulu_preset = FuluPreset::from_chain_spec::(spec); + let gloas_preset = GloasPreset::from_chain_spec::(spec); + let heze_preset = HezePreset::from_chain_spec::(spec); + + ConfigAndPreset::Heze(ConfigAndPresetHeze { + config, + base_preset, + altair_preset, + bellatrix_preset, + capella_preset, + deneb_preset, + electra_preset, + fulu_preset, + gloas_preset, + heze_preset, + extra_fields, + }) + } else if spec.is_gloas_scheduled() { let electra_preset = ElectraPreset::from_chain_spec::(spec); let fulu_preset = FuluPreset::from_chain_spec::(spec); - let eip7805_preset = Eip7805Preset::from_chain_spec(spec); let gloas_preset = GloasPreset::from_chain_spec::(spec); ConfigAndPreset::Gloas(ConfigAndPresetGloas { @@ -74,27 +92,9 @@ impl ConfigAndPreset { deneb_preset, electra_preset, fulu_preset, - eip7805_preset, gloas_preset, extra_fields, }) - } else if spec.is_focil_scheduled() { - let electra_preset = ElectraPreset::from_chain_spec::(spec); - let fulu_preset = FuluPreset::from_chain_spec::(spec); - let eip7805_preset = Eip7805Preset::from_chain_spec(spec); - - ConfigAndPreset::Eip7805(ConfigAndPresetEip7805 { - config, - base_preset, - altair_preset, - bellatrix_preset, - capella_preset, - deneb_preset, - electra_preset, - fulu_preset, - eip7805_preset, - extra_fields, - }) } else if spec.is_fulu_scheduled() { let electra_preset = ElectraPreset::from_chain_spec::(spec); let fulu_preset = FuluPreset::from_chain_spec::(spec); @@ -187,8 +187,8 @@ mod test { .open(tmp_file.as_ref()) .expect("error opening file"); let mut mainnet_spec = ChainSpec::mainnet(); - // setting gloas_fork_epoch because we are roundtripping a gloas config - mainnet_spec.gloas_fork_epoch = Some(Epoch::new(42)); + // setting heze_fork_epoch because we are roundtripping a heze config + mainnet_spec.heze_fork_epoch = Some(Epoch::new(42)); let mut yamlconfig = ConfigAndPreset::from_chain_spec::(&mainnet_spec); let (k1, v1) = ("SAMPLE_HARDFORK_KEY1", "123456789"); let (k2, v2) = ("SAMPLE_HARDFORK_KEY2", "987654321"); @@ -206,9 +206,9 @@ mod test { .write(false) .open(tmp_file.as_ref()) .expect("error while opening the file"); - let from: ConfigAndPresetGloas = + let from: ConfigAndPresetHeze = yaml_serde::from_reader(reader).expect("error while deserializing"); - assert_eq!(ConfigAndPreset::Gloas(from), yamlconfig); + assert_eq!(ConfigAndPreset::Heze(from), yamlconfig); } #[test] diff --git a/consensus/types/src/core/eth_spec.rs b/consensus/types/src/core/eth_spec.rs index 109aa2edec..bb11ca2cd2 100644 --- a/consensus/types/src/core/eth_spec.rs +++ b/consensus/types/src/core/eth_spec.rs @@ -183,7 +183,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + type MaxBuildersPerWithdrawalsSweep: Unsigned + Clone + Sync + Send + Debug + PartialEq; /* - * New in Eip7805 + * New in Heze */ type InclusionListCommitteeSize: Unsigned + Clone + Sync + Send + Debug + PartialEq; type MaxTransactionsPerInclusionList: Unsigned + Clone + Sync + Send + Debug + PartialEq; diff --git a/consensus/types/src/core/mod.rs b/consensus/types/src/core/mod.rs index 9d12b89d44..471e53309d 100644 --- a/consensus/types/src/core/mod.rs +++ b/consensus/types/src/core/mod.rs @@ -22,7 +22,7 @@ pub use application_domain::{APPLICATION_DOMAIN_BUILDER, ApplicationDomain}; pub use chain_spec::{BlobParameters, BlobSchedule, ChainSpec, Config, Domain}; pub use config_and_preset::{ ConfigAndPreset, ConfigAndPresetDeneb, ConfigAndPresetElectra, ConfigAndPresetFulu, - ConfigAndPresetGloas, get_extra_fields, + ConfigAndPresetGloas, ConfigAndPresetHeze, get_extra_fields, }; pub use enr_fork_id::EnrForkId; pub use eth_spec::{EthSpec, EthSpecId, GNOSIS, GnosisEthSpec, MainnetEthSpec, MinimalEthSpec}; @@ -30,8 +30,8 @@ pub use execution_block_hash::ExecutionBlockHash; pub use graffiti::{GRAFFITI_BYTES_LEN, Graffiti, GraffitiString}; pub use non_zero_usize::new_non_zero_usize; pub use preset::{ - AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, DenebPreset, Eip7805Preset, - ElectraPreset, FuluPreset, GloasPreset, + AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, DenebPreset, ElectraPreset, + FuluPreset, GloasPreset, HezePreset, }; pub use relative_epoch::{Error as RelativeEpochError, RelativeEpoch}; pub use signing_data::{SignedRoot, SigningData}; diff --git a/consensus/types/src/core/preset.rs b/consensus/types/src/core/preset.rs index d787a3f9e6..242c7cb32a 100644 --- a/consensus/types/src/core/preset.rs +++ b/consensus/types/src/core/preset.rs @@ -303,15 +303,15 @@ impl ElectraPreset { #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] #[serde(rename_all = "UPPERCASE")] -pub struct Eip7805Preset { +pub struct HezePreset { #[serde(with = "serde_utils::quoted_u32")] pub domain_inclusion_list_committee: u32, #[serde(with = "serde_utils::quoted_u64")] pub inclusion_list_committee_size: u64, } -impl Eip7805Preset { - pub fn from_chain_spec(spec: &ChainSpec) -> Self { +impl HezePreset { + pub fn from_chain_spec(spec: &ChainSpec) -> Self { Self { domain_inclusion_list_committee: spec.domain_inclusion_list_committee, inclusion_list_committee_size: spec.inclusion_list_committee_size, @@ -374,6 +374,7 @@ impl GloasPreset { } } + #[cfg(test)] mod test { use super::*; @@ -419,8 +420,8 @@ mod test { let electra: ElectraPreset = preset_from_file(&preset_name, "electra.yaml"); assert_eq!(electra, ElectraPreset::from_chain_spec::(&spec)); - let eip7805: Eip7805Preset = preset_from_file(&preset_name, "eip7805.yaml"); - assert_eq!(eip7805, Eip7805Preset::from_chain_spec(&spec)); + let heze: HezePreset = preset_from_file(&preset_name, "heze.yaml"); + assert_eq!(heze, HezePreset::from_chain_spec(&spec)); let fulu: FuluPreset = preset_from_file(&preset_name, "fulu.yaml"); assert_eq!(fulu, FuluPreset::from_chain_spec::(&spec)); diff --git a/consensus/types/src/data/data_column_sidecar.rs b/consensus/types/src/data/data_column_sidecar.rs index a653ee338c..5c2404b1ca 100644 --- a/consensus/types/src/data/data_column_sidecar.rs +++ b/consensus/types/src/data/data_column_sidecar.rs @@ -44,7 +44,7 @@ pub struct DataColumnsByRootIdentifier { pub type DataColumnSidecarList = Vec>>; #[superstruct( - variants(Fulu, Gloas), + variants(Fulu, Gloas, Heze), variant_attributes( derive( Debug, @@ -95,9 +95,9 @@ pub struct DataColumnSidecar { /// An inclusion proof, proving the inclusion of `blob_kzg_commitments` in `BeaconBlockBody`. #[superstruct(only(Fulu))] pub kzg_commitments_inclusion_proof: FixedVector, - #[superstruct(only(Gloas), partial_getter(rename = "slot_gloas"))] + #[superstruct(only(Gloas, Heze), partial_getter(rename = "slot_gloas"))] pub slot: Slot, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub beacon_block_root: Hash256, } @@ -106,6 +106,7 @@ impl DataColumnSidecar { match self { DataColumnSidecar::Fulu(column) => column.slot(), DataColumnSidecar::Gloas(column) => column.slot, + DataColumnSidecar::Heze(column) => column.slot, } } @@ -117,6 +118,7 @@ impl DataColumnSidecar { match self { DataColumnSidecar::Fulu(column) => column.block_root(), DataColumnSidecar::Gloas(column) => column.beacon_block_root, + DataColumnSidecar::Heze(column) => column.beacon_block_root, } } @@ -132,13 +134,15 @@ impl DataColumnSidecar { | ForkName::Capella | ForkName::Deneb | ForkName::Electra => Err(ssz::DecodeError::NoMatchingVariant), - ForkName::Eip7805 => Err(ssz::DecodeError::NoMatchingVariant), ForkName::Fulu => Ok(DataColumnSidecar::Fulu( DataColumnSidecarFulu::from_ssz_bytes(bytes)?, )), ForkName::Gloas => Ok(DataColumnSidecar::Gloas( DataColumnSidecarGloas::from_ssz_bytes(bytes)?, )), + ForkName::Heze => Ok(DataColumnSidecar::Heze( + DataColumnSidecarHeze::from_ssz_bytes(bytes)?, + )), } } @@ -311,6 +315,33 @@ impl DataColumnSidecarGloas { } } +impl DataColumnSidecarHeze { + pub fn min_size() -> usize { + // min size is one cell + Self { + index: 0, + column: VariableList::new(vec![Cell::::default()]).unwrap(), + kzg_proofs: VariableList::new(vec![KzgProof::empty()]).unwrap(), + slot: Slot::new(0), + beacon_block_root: Hash256::ZERO, + } + .as_ssz_bytes() + .len() + } + + pub fn max_size(max_blobs_per_block: usize) -> usize { + Self { + index: 0, + column: VariableList::new(vec![Cell::::default(); max_blobs_per_block]).unwrap(), + kzg_proofs: VariableList::new(vec![KzgProof::empty(); max_blobs_per_block]).unwrap(), + slot: Slot::new(0), + beacon_block_root: Hash256::ZERO, + } + .as_ssz_bytes() + .len() + } +} + #[derive(Debug)] pub enum DataColumnSidecarError { ArithError(ArithError), diff --git a/consensus/types/src/data/mod.rs b/consensus/types/src/data/mod.rs index 9c7eb42626..9c9d65295a 100644 --- a/consensus/types/src/data/mod.rs +++ b/consensus/types/src/data/mod.rs @@ -14,7 +14,7 @@ pub use data_column_custody_group::{ }; pub use data_column_sidecar::{ Cell, ColumnIndex, DataColumn, DataColumnSidecar, DataColumnSidecarError, - DataColumnSidecarFulu, DataColumnSidecarGloas, DataColumnSidecarList, + DataColumnSidecarFulu, DataColumnSidecarGloas, DataColumnSidecarHeze, DataColumnSidecarList, DataColumnsByRootIdentifier, }; pub use data_column_subnet_id::{DataColumnSubnetId, all_data_column_sidecar_subnets_from_spec}; diff --git a/consensus/types/src/execution/dumb_macros.rs b/consensus/types/src/execution/dumb_macros.rs index bee782294b..8b4a773cba 100644 --- a/consensus/types/src/execution/dumb_macros.rs +++ b/consensus/types/src/execution/dumb_macros.rs @@ -29,11 +29,11 @@ macro_rules! map_execution_payload_into_full_payload { let f: fn(ExecutionPayloadFulu<_>, fn(_) -> _) -> _ = $f; f(inner, FullPayload::Fulu) } - ExecutionPayload::Eip7805(inner) => { - let f: fn(ExecutionPayloadEip7805<_>, fn(_) -> _) -> _ = $f; - f(inner, FullPayload::Eip7805) - } ExecutionPayload::Gloas(_) => panic!("FullPayload::Gloas does not exist!"), + ExecutionPayload::Heze(inner) => { + let f: fn(ExecutionPayloadHeze<_>, fn(_) -> _) -> _ = $f; + f(inner, FullPayload::Heze) + } } }; } @@ -62,11 +62,11 @@ macro_rules! map_execution_payload_into_blinded_payload { let f: fn(ExecutionPayloadFulu<_>, fn(_) -> _) -> _ = $f; f(inner, BlindedPayload::Fulu) } - ExecutionPayload::Eip7805(inner) => { - let f: fn(ExecutionPayloadEip7805<_>, fn(_) -> _) -> _ = $f; - f(inner, BlindedPayload::Eip7805) - } ExecutionPayload::Gloas(_) => panic!("BlindedPayload::Gloas does not exist!"), + ExecutionPayload::Heze(inner) => { + let f: fn(ExecutionPayloadHeze<_>, fn(_) -> _) -> _ = $f; + f(inner, BlindedPayload::Heze) + } } }; } @@ -110,14 +110,14 @@ macro_rules! map_execution_payload_ref_into_execution_payload_header { ) -> _ = $f; f(inner, ExecutionPayloadHeader::Fulu) } - ExecutionPayloadRef::Eip7805(inner) => { + ExecutionPayloadRef::Gloas(_) => panic!("ExecutionPayloadHeader::Gloas does not exist!"), + ExecutionPayloadRef::Heze(inner) => { let f: fn( - &$lifetime ExecutionPayloadEip7805<_>, + &$lifetime ExecutionPayloadHeze<_>, fn(_) -> _, ) -> _ = $f; - f(inner, ExecutionPayloadHeader::Eip7805) + f(inner, ExecutionPayloadHeader::Heze) } - ExecutionPayloadRef::Gloas(_) => panic!("ExecutionPayloadHeader::Gloas does not exist!"), } } } diff --git a/consensus/types/src/execution/execution_payload.rs b/consensus/types/src/execution/execution_payload.rs index 0d8a3e8f25..be228485c5 100644 --- a/consensus/types/src/execution/execution_payload.rs +++ b/consensus/types/src/execution/execution_payload.rs @@ -24,7 +24,7 @@ pub type Transactions = VariableList< >; #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive( Default, @@ -101,19 +101,19 @@ pub struct ExecutionPayload { pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: Transactions, - #[superstruct(only(Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas, Heze))] pub withdrawals: Withdrawals, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[serde(with = "serde_utils::quoted_u64")] pub blob_gas_used: u64, - #[superstruct(only(Deneb, Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Deneb, Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[serde(with = "serde_utils::quoted_u64")] pub excess_blob_gas: u64, /// EIP-7928: Block access list - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[serde(with = "ssz_types::serde_utils::hex_var_list")] pub block_access_list: VariableList, - #[superstruct(only(Gloas), partial_getter(copy))] + #[superstruct(only(Gloas, Heze), partial_getter(copy))] pub slot_number: Slot, } @@ -140,9 +140,9 @@ impl ForkVersionDecode for ExecutionPayload { ForkName::Capella => ExecutionPayloadCapella::from_ssz_bytes(bytes).map(Self::Capella), ForkName::Deneb => ExecutionPayloadDeneb::from_ssz_bytes(bytes).map(Self::Deneb), ForkName::Electra => ExecutionPayloadElectra::from_ssz_bytes(bytes).map(Self::Electra), - ForkName::Eip7805 => ExecutionPayloadEip7805::from_ssz_bytes(bytes).map(Self::Eip7805), ForkName::Fulu => ExecutionPayloadFulu::from_ssz_bytes(bytes).map(Self::Fulu), ForkName::Gloas => ExecutionPayloadGloas::from_ssz_bytes(bytes).map(Self::Gloas), + ForkName::Heze => ExecutionPayloadHeze::from_ssz_bytes(bytes).map(Self::Heze), } } } @@ -188,15 +188,15 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for ExecutionPayload ForkName::Electra => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Eip7805 => { - Self::Eip7805(Deserialize::deserialize(deserializer).map_err(convert_err)?) - } ForkName::Fulu => { Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?) } ForkName::Gloas => { Self::Gloas(Deserialize::deserialize(deserializer).map_err(convert_err)?) } + ForkName::Heze => { + Self::Heze(Deserialize::deserialize(deserializer).map_err(convert_err)?) + } }) } } @@ -208,9 +208,9 @@ impl ExecutionPayload { ExecutionPayload::Capella(_) => ForkName::Capella, ExecutionPayload::Deneb(_) => ForkName::Deneb, ExecutionPayload::Electra(_) => ForkName::Electra, - ExecutionPayload::Eip7805(_) => ForkName::Eip7805, ExecutionPayload::Fulu(_) => ForkName::Fulu, ExecutionPayload::Gloas(_) => ForkName::Gloas, + ExecutionPayload::Heze(_) => ForkName::Heze, } } } diff --git a/consensus/types/src/execution/execution_payload_header.rs b/consensus/types/src/execution/execution_payload_header.rs index 052f16e57d..0ca470dc85 100644 --- a/consensus/types/src/execution/execution_payload_header.rs +++ b/consensus/types/src/execution/execution_payload_header.rs @@ -14,7 +14,7 @@ use crate::{ core::{Address, EthSpec, ExecutionBlockHash, Hash256, Uint256}, execution::{ ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb, - ExecutionPayloadEip7805, ExecutionPayloadElectra, ExecutionPayloadFulu, + ExecutionPayloadHeze, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadRef, Transactions, }, fork::ForkName, @@ -24,7 +24,7 @@ use crate::{ }; #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu), + variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu), variant_attributes( derive( Default, @@ -106,12 +106,12 @@ pub struct ExecutionPayloadHeader { pub block_hash: ExecutionBlockHash, #[superstruct(getter(copy))] pub transactions_root: Hash256, - #[superstruct(only(Capella, Deneb, Electra, Eip7805, Fulu), partial_getter(copy))] + #[superstruct(only(Capella, Deneb, Electra, Heze, Fulu), partial_getter(copy))] pub withdrawals_root: Hash256, - #[superstruct(only(Deneb, Electra, Eip7805, Fulu), partial_getter(copy))] + #[superstruct(only(Deneb, Electra, Heze, Fulu), partial_getter(copy))] #[serde(with = "serde_utils::quoted_u64")] pub blob_gas_used: u64, - #[superstruct(only(Deneb, Electra, Eip7805, Fulu), partial_getter(copy))] + #[superstruct(only(Deneb, Electra, Heze, Fulu), partial_getter(copy))] #[serde(with = "serde_utils::quoted_u64")] pub excess_blob_gas: u64, } @@ -136,11 +136,8 @@ impl ExecutionPayloadHeader { ForkName::Electra => { ExecutionPayloadHeaderElectra::from_ssz_bytes(bytes).map(Self::Electra) } - ForkName::Eip7805 => { - ExecutionPayloadHeaderEip7805::from_ssz_bytes(bytes).map(Self::Eip7805) - } ForkName::Fulu => ExecutionPayloadHeaderFulu::from_ssz_bytes(bytes).map(Self::Fulu), - ForkName::Gloas => Err(ssz::DecodeError::BytesInvalid(format!( + ForkName::Gloas | ForkName::Heze => Err(ssz::DecodeError::BytesInvalid(format!( "unsupported fork for ExecutionPayloadHeader: {fork_name}", ))), } @@ -149,7 +146,10 @@ impl ExecutionPayloadHeader { #[allow(clippy::arithmetic_side_effects)] pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize { // TODO(newfork): Add a new case here if there are new variable fields - if fork_name.gloas_enabled() { + if fork_name.heze_enabled() { + // TODO(Heze): check this + 0 + } else if fork_name.gloas_enabled() { // TODO(EIP7732): check this 0 } else if fork_name.bellatrix_enabled() { @@ -166,7 +166,7 @@ impl ExecutionPayloadHeader { ExecutionPayloadHeader::Capella(_) => ForkName::Capella, ExecutionPayloadHeader::Deneb(_) => ForkName::Deneb, ExecutionPayloadHeader::Electra(_) => ForkName::Electra, - ExecutionPayloadHeader::Eip7805(_) => ForkName::Eip7805, + ExecutionPayloadHeader::Heze(_) => ForkName::Heze, ExecutionPayloadHeader::Fulu(_) => ForkName::Fulu, } } @@ -252,8 +252,8 @@ impl ExecutionPayloadHeaderDeneb { } impl ExecutionPayloadHeaderFulu { - pub fn upgrade_to_eip7805(&self) -> ExecutionPayloadHeaderEip7805 { - ExecutionPayloadHeaderEip7805 { + pub fn upgrade_to_heze(&self) -> ExecutionPayloadHeaderHeze { + ExecutionPayloadHeaderHeze { parent_hash: self.parent_hash, fee_recipient: self.fee_recipient, state_root: self.state_root, @@ -390,8 +390,8 @@ impl<'a, E: EthSpec> From<&'a ExecutionPayloadElectra> for ExecutionPayloadHe } } -impl<'a, E: EthSpec> From<&'a ExecutionPayloadEip7805> for ExecutionPayloadHeaderEip7805 { - fn from(payload: &'a ExecutionPayloadEip7805) -> Self { +impl<'a, E: EthSpec> From<&'a ExecutionPayloadHeze> for ExecutionPayloadHeaderHeze { + fn from(payload: &'a ExecutionPayloadHeze) -> Self { Self { parent_hash: payload.parent_hash, fee_recipient: payload.fee_recipient, @@ -464,7 +464,7 @@ impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderElectra { } } -impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderEip7805 { +impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderHeze { fn from(payload: &'a Self) -> Self { payload.clone() } @@ -534,7 +534,7 @@ impl ExecutionPayloadHeaderRefMut<'_, E> { ExecutionPayloadHeaderRefMut::Electra(mut_ref) => { *mut_ref = header.try_into()?; } - ExecutionPayloadHeaderRefMut::Eip7805(mut_ref) => { + ExecutionPayloadHeaderRefMut::Heze(mut_ref) => { *mut_ref = header.try_into()?; } ExecutionPayloadHeaderRefMut::Fulu(mut_ref) => { @@ -557,11 +557,11 @@ impl TryFrom> for ExecutionPayloadHeaderEl } } -impl TryFrom> for ExecutionPayloadHeaderEip7805 { +impl TryFrom> for ExecutionPayloadHeaderHeze { type Error = BeaconStateError; fn try_from(header: ExecutionPayloadHeader) -> Result { match header { - ExecutionPayloadHeader::Eip7805(execution_payload_header) => { + ExecutionPayloadHeader::Heze(execution_payload_header) => { Ok(execution_payload_header) } _ => Err(BeaconStateError::IncorrectStateVariant), @@ -603,14 +603,11 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for ExecutionPayloadHead ForkName::Electra => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Eip7805 => { - Self::Eip7805(Deserialize::deserialize(deserializer).map_err(convert_err)?) - } ForkName::Fulu => { Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Base | ForkName::Altair | ForkName::Gloas => { + ForkName::Base | ForkName::Altair | ForkName::Gloas | ForkName::Heze => { return Err(serde::de::Error::custom(format!( "ExecutionPayloadHeader failed to deserialize: unsupported fork '{}'", context diff --git a/consensus/types/src/execution/mod.rs b/consensus/types/src/execution/mod.rs index bd30dcb19b..16040a358e 100644 --- a/consensus/types/src/execution/mod.rs +++ b/consensus/types/src/execution/mod.rs @@ -19,14 +19,14 @@ pub use eth1_data::Eth1Data; pub use execution_block_header::{EncodableExecutionBlockHeader, ExecutionBlockHeader}; pub use execution_payload::{ ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb, - ExecutionPayloadEip7805, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, + ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeze, ExecutionPayloadRef, Transaction, Transactions, }; pub use execution_payload_bid::ExecutionPayloadBid; pub use execution_payload_envelope::ExecutionPayloadEnvelope; pub use execution_payload_header::{ ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella, - ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderEip7805, ExecutionPayloadHeaderElectra, + ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderHeze, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, }; pub use execution_requests::{ @@ -37,9 +37,9 @@ pub use inclusion_list::{ }; pub use payload::{ AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella, - BlindedPayloadDeneb, BlindedPayloadEip7805, BlindedPayloadElectra, BlindedPayloadFulu, + BlindedPayloadDeneb, BlindedPayloadHeze, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadRef, BlockProductionVersion, BlockType, ExecPayload, FullPayload, - FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadEip7805, + FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadHeze, FullPayloadElectra, FullPayloadFulu, FullPayloadRef, OwnedExecPayload, }; pub use signed_bls_to_execution_change::SignedBlsToExecutionChange; diff --git a/consensus/types/src/execution/payload.rs b/consensus/types/src/execution/payload.rs index b3dc96366f..8057e07f94 100644 --- a/consensus/types/src/execution/payload.rs +++ b/consensus/types/src/execution/payload.rs @@ -14,9 +14,9 @@ use crate::{ core::{Address, EthSpec, ExecutionBlockHash, Hash256}, execution::{ ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, - ExecutionPayloadDeneb, ExecutionPayloadEip7805, ExecutionPayloadElectra, + ExecutionPayloadDeneb, ExecutionPayloadHeze, ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, - ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderEip7805, + ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderHeze, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu, ExecutionPayloadRef, Transactions, }, @@ -120,7 +120,7 @@ pub trait AbstractExecPayload: + TryInto + TryInto + TryInto - + TryInto + + TryInto + Sync { type Ref<'a>: ExecPayload @@ -130,7 +130,7 @@ pub trait AbstractExecPayload: + From<&'a Self::Deneb> + From<&'a Self::Electra> + From<&'a Self::Fulu> - + From<&'a Self::Eip7805>; + + From<&'a Self::Heze>; type Bellatrix: OwnedExecPayload + Into @@ -157,15 +157,15 @@ pub trait AbstractExecPayload: + for<'a> From>> + TryFrom> + Sync; - type Eip7805: OwnedExecPayload + type Heze: OwnedExecPayload + Into - + for<'a> From>> - + TryFrom> + + for<'a> From>> + + TryFrom> + Sync; } #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu), + variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu), variant_attributes( derive( Debug, @@ -224,8 +224,8 @@ pub struct FullPayload { pub execution_payload: ExecutionPayloadDeneb, #[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))] pub execution_payload: ExecutionPayloadElectra, - #[superstruct(only(Eip7805), partial_getter(rename = "execution_payload_eip7805"))] - pub execution_payload: ExecutionPayloadEip7805, + #[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))] + pub execution_payload: ExecutionPayloadHeze, #[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))] pub execution_payload: ExecutionPayloadFulu, } @@ -339,7 +339,7 @@ impl ExecPayload for FullPayload { FullPayload::Deneb(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()), FullPayload::Electra(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()), FullPayload::Fulu(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()), - FullPayload::Eip7805(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()), + FullPayload::Heze(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()), } } @@ -351,7 +351,7 @@ impl ExecPayload for FullPayload { FullPayload::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used), FullPayload::Electra(inner) => Ok(inner.execution_payload.blob_gas_used), FullPayload::Fulu(inner) => Ok(inner.execution_payload.blob_gas_used), - FullPayload::Eip7805(inner) => Ok(inner.execution_payload.blob_gas_used), + FullPayload::Heze(inner) => Ok(inner.execution_payload.blob_gas_used), } } @@ -382,9 +382,8 @@ impl FullPayload { ForkName::Capella => Ok(FullPayloadCapella::default().into()), ForkName::Deneb => Ok(FullPayloadDeneb::default().into()), ForkName::Electra => Ok(FullPayloadElectra::default().into()), - ForkName::Eip7805 => Ok(FullPayloadEip7805::default().into()), ForkName::Fulu => Ok(FullPayloadFulu::default().into()), - ForkName::Gloas => Err(BeaconStateError::IncorrectStateVariant), + ForkName::Gloas | ForkName::Heze => Err(BeaconStateError::IncorrectStateVariant), } } } @@ -484,7 +483,7 @@ impl ExecPayload for FullPayloadRef<'_, E> { FullPayloadRef::Electra(inner) => { Ok(inner.execution_payload.withdrawals.tree_hash_root()) } - FullPayloadRef::Eip7805(inner) => { + FullPayloadRef::Heze(inner) => { Ok(inner.execution_payload.withdrawals.tree_hash_root()) } FullPayloadRef::Fulu(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()), @@ -498,7 +497,7 @@ impl ExecPayload for FullPayloadRef<'_, E> { } FullPayloadRef::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used), FullPayloadRef::Electra(inner) => Ok(inner.execution_payload.blob_gas_used), - FullPayloadRef::Eip7805(inner) => Ok(inner.execution_payload.blob_gas_used), + FullPayloadRef::Heze(inner) => Ok(inner.execution_payload.blob_gas_used), FullPayloadRef::Fulu(inner) => Ok(inner.execution_payload.blob_gas_used), } } @@ -522,7 +521,7 @@ impl AbstractExecPayload for FullPayload { type Capella = FullPayloadCapella; type Deneb = FullPayloadDeneb; type Electra = FullPayloadElectra; - type Eip7805 = FullPayloadEip7805; + type Heze = FullPayloadHeze; type Fulu = FullPayloadFulu; } @@ -542,7 +541,7 @@ impl TryFrom> for FullPayload { } #[superstruct( - variants(Bellatrix, Capella, Deneb, Electra, Eip7805, Fulu), + variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu), variant_attributes( derive( Debug, @@ -600,8 +599,8 @@ pub struct BlindedPayload { pub execution_payload_header: ExecutionPayloadHeaderDeneb, #[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))] pub execution_payload_header: ExecutionPayloadHeaderElectra, - #[superstruct(only(Eip7805), partial_getter(rename = "execution_payload_eip7805"))] - pub execution_payload_header: ExecutionPayloadHeaderEip7805, + #[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))] + pub execution_payload_header: ExecutionPayloadHeaderHeze, #[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))] pub execution_payload_header: ExecutionPayloadHeaderFulu, } @@ -693,7 +692,7 @@ impl ExecPayload for BlindedPayload { BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.withdrawals_root), BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.withdrawals_root), BlindedPayload::Fulu(inner) => Ok(inner.execution_payload_header.withdrawals_root), - BlindedPayload::Eip7805(inner) => Ok(inner.execution_payload_header.withdrawals_root), + BlindedPayload::Heze(inner) => Ok(inner.execution_payload_header.withdrawals_root), } } @@ -705,7 +704,7 @@ impl ExecPayload for BlindedPayload { BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used), BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used), BlindedPayload::Fulu(inner) => Ok(inner.execution_payload_header.blob_gas_used), - BlindedPayload::Eip7805(inner) => Ok(inner.execution_payload_header.blob_gas_used), + BlindedPayload::Heze(inner) => Ok(inner.execution_payload_header.blob_gas_used), } } @@ -804,7 +803,7 @@ impl<'b, E: EthSpec> ExecPayload for BlindedPayloadRef<'b, E> { BlindedPayloadRef::Electra(inner) => { Ok(inner.execution_payload_header.withdrawals_root) } - BlindedPayloadRef::Eip7805(inner) => { + BlindedPayloadRef::Heze(inner) => { Ok(inner.execution_payload_header.withdrawals_root) } BlindedPayloadRef::Fulu(inner) => Ok(inner.execution_payload_header.withdrawals_root), @@ -818,7 +817,7 @@ impl<'b, E: EthSpec> ExecPayload for BlindedPayloadRef<'b, E> { } BlindedPayloadRef::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used), BlindedPayloadRef::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used), - BlindedPayloadRef::Eip7805(inner) => Ok(inner.execution_payload_header.blob_gas_used), + BlindedPayloadRef::Heze(inner) => Ok(inner.execution_payload_header.blob_gas_used), BlindedPayloadRef::Fulu(inner) => Ok(inner.execution_payload_header.blob_gas_used), } } @@ -1126,11 +1125,11 @@ impl_exec_payload_for_fork!( ); impl_exec_payload_for_fork!( - BlindedPayloadEip7805, - FullPayloadEip7805, - ExecutionPayloadHeaderEip7805, - ExecutionPayloadEip7805, - Eip7805 + BlindedPayloadHeze, + FullPayloadHeze, + ExecutionPayloadHeaderHeze, + ExecutionPayloadHeze, + Heze ); impl_exec_payload_for_fork!( BlindedPayloadFulu, @@ -1146,7 +1145,7 @@ impl AbstractExecPayload for BlindedPayload { type Capella = BlindedPayloadCapella; type Deneb = BlindedPayloadDeneb; type Electra = BlindedPayloadElectra; - type Eip7805 = BlindedPayloadEip7805; + type Heze = BlindedPayloadHeze; type Fulu = BlindedPayloadFulu; } @@ -1184,8 +1183,8 @@ impl From> for BlindedPayload { execution_payload_header, }) } - ExecutionPayloadHeader::Eip7805(execution_payload_header) => { - Self::Eip7805(BlindedPayloadEip7805 { + ExecutionPayloadHeader::Heze(execution_payload_header) => { + Self::Heze(BlindedPayloadHeze { execution_payload_header, }) } @@ -1213,8 +1212,8 @@ impl From> for ExecutionPayloadHeader { BlindedPayload::Electra(blinded_payload) => { ExecutionPayloadHeader::Electra(blinded_payload.execution_payload_header) } - BlindedPayload::Eip7805(blinded_payload) => { - ExecutionPayloadHeader::Eip7805(blinded_payload.execution_payload_header) + BlindedPayload::Heze(blinded_payload) => { + ExecutionPayloadHeader::Heze(blinded_payload.execution_payload_header) } BlindedPayload::Fulu(blinded_payload) => { ExecutionPayloadHeader::Fulu(blinded_payload.execution_payload_header) diff --git a/consensus/types/src/fork/fork_macros.rs b/consensus/types/src/fork/fork_macros.rs index 2adc1fb88b..3fa8bcf1fb 100644 --- a/consensus/types/src/fork/fork_macros.rs +++ b/consensus/types/src/fork/fork_macros.rs @@ -51,14 +51,18 @@ macro_rules! map_fork_name_with { let (value, extra_data) = $body; ($t::Fulu(value), extra_data) } - $crate::fork::ForkName::Eip7805 => { + $crate::fork::ForkName::Heze => { let (value, extra_data) = $body; - ($t::Eip7805(value), extra_data) + ($t::Heze(value), extra_data) } $crate::fork::ForkName::Gloas => { let (value, extra_data) = $body; ($t::Gloas(value), extra_data) } + $crate::fork::ForkName::Heze => { + let (value, extra_data) = $body; + ($t::Heze(value), extra_data) + } } }; } diff --git a/consensus/types/src/fork/fork_name.rs b/consensus/types/src/fork/fork_name.rs index ce78115811..0d8132cd9a 100644 --- a/consensus/types/src/fork/fork_name.rs +++ b/consensus/types/src/fork/fork_name.rs @@ -22,8 +22,8 @@ pub enum ForkName { Deneb, Electra, Fulu, - Eip7805, Gloas, + Heze, } impl ForkName { @@ -36,8 +36,8 @@ impl ForkName { ForkName::Deneb, ForkName::Electra, ForkName::Fulu, - ForkName::Eip7805, ForkName::Gloas, + ForkName::Heze, ] } @@ -72,8 +72,9 @@ impl ForkName { spec.deneb_fork_epoch = None; spec.electra_fork_epoch = None; spec.fulu_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.heze_fork_epoch = None; spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Altair => { @@ -83,8 +84,9 @@ impl ForkName { spec.deneb_fork_epoch = None; spec.electra_fork_epoch = None; spec.fulu_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.heze_fork_epoch = None; spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Bellatrix => { @@ -94,8 +96,9 @@ impl ForkName { spec.deneb_fork_epoch = None; spec.electra_fork_epoch = None; spec.fulu_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.heze_fork_epoch = None; spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Capella => { @@ -105,8 +108,9 @@ impl ForkName { spec.deneb_fork_epoch = None; spec.electra_fork_epoch = None; spec.fulu_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.heze_fork_epoch = None; spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Deneb => { @@ -116,8 +120,9 @@ impl ForkName { spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.electra_fork_epoch = None; spec.fulu_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.heze_fork_epoch = None; spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Electra => { @@ -127,21 +132,11 @@ impl ForkName { spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.electra_fork_epoch = Some(Epoch::new(0)); spec.fulu_fork_epoch = None; - spec.eip7805_fork_epoch = None; + spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Fulu => { - spec.altair_fork_epoch = Some(Epoch::new(0)); - spec.bellatrix_fork_epoch = Some(Epoch::new(0)); - spec.capella_fork_epoch = Some(Epoch::new(0)); - spec.deneb_fork_epoch = Some(Epoch::new(0)); - spec.electra_fork_epoch = Some(Epoch::new(0)); - spec.fulu_fork_epoch = Some(Epoch::new(0)); - spec.eip7805_fork_epoch = None; - spec.gloas_fork_epoch = None; - spec - } - ForkName::Eip7805 => { spec.altair_fork_epoch = Some(Epoch::new(0)); spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(0)); @@ -149,6 +144,7 @@ impl ForkName { spec.electra_fork_epoch = Some(Epoch::new(0)); spec.fulu_fork_epoch = Some(Epoch::new(0)); spec.gloas_fork_epoch = None; + spec.heze_fork_epoch = None; spec } ForkName::Gloas => { @@ -158,8 +154,19 @@ impl ForkName { spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.electra_fork_epoch = Some(Epoch::new(0)); spec.fulu_fork_epoch = Some(Epoch::new(0)); - spec.eip7805_fork_epoch = Some(Epoch::new(0)); spec.gloas_fork_epoch = Some(Epoch::new(0)); + spec.heze_fork_epoch = None; + spec + } + ForkName::Heze => { + spec.altair_fork_epoch = Some(Epoch::new(0)); + spec.bellatrix_fork_epoch = Some(Epoch::new(0)); + spec.capella_fork_epoch = Some(Epoch::new(0)); + spec.deneb_fork_epoch = Some(Epoch::new(0)); + spec.electra_fork_epoch = Some(Epoch::new(0)); + spec.fulu_fork_epoch = Some(Epoch::new(0)); + spec.gloas_fork_epoch = Some(Epoch::new(0)); + spec.heze_fork_epoch = Some(Epoch::new(0)); spec } } @@ -177,8 +184,8 @@ impl ForkName { ForkName::Deneb => Some(ForkName::Capella), ForkName::Electra => Some(ForkName::Deneb), ForkName::Fulu => Some(ForkName::Electra), - ForkName::Eip7805 => Some(ForkName::Fulu), - ForkName::Gloas => Some(ForkName::Eip7805), + ForkName::Gloas => Some(ForkName::Fulu), + ForkName::Heze => Some(ForkName::Gloas), } } @@ -193,9 +200,9 @@ impl ForkName { ForkName::Capella => Some(ForkName::Deneb), ForkName::Deneb => Some(ForkName::Electra), ForkName::Electra => Some(ForkName::Fulu), - ForkName::Fulu => Some(ForkName::Eip7805), - ForkName::Eip7805 => Some(ForkName::Gloas), - ForkName::Gloas => None, + ForkName::Fulu => Some(ForkName::Gloas), + ForkName::Gloas => Some(ForkName::Heze), + ForkName::Heze => None, } } @@ -223,14 +230,14 @@ impl ForkName { self >= ForkName::Fulu } - pub fn eip7805_enabled(self) -> bool { - self >= ForkName::Eip7805 - } - pub fn gloas_enabled(self) -> bool { self >= ForkName::Gloas } + pub fn heze_enabled(self) -> bool { + self >= ForkName::Heze + } + pub fn fork_ascii(self) { if self == ForkName::Fulu { println!( @@ -283,9 +290,9 @@ impl FromStr for ForkName { "capella" => ForkName::Capella, "deneb" => ForkName::Deneb, "electra" => ForkName::Electra, - "eip7805" => ForkName::Eip7805, "fulu" => ForkName::Fulu, "gloas" => ForkName::Gloas, + "heze" => ForkName::Heze, _ => return Err(format!("unknown fork name: {}", fork_name)), }) } @@ -300,9 +307,9 @@ impl Display for ForkName { ForkName::Capella => "capella".fmt(f), ForkName::Deneb => "deneb".fmt(f), ForkName::Electra => "electra".fmt(f), - ForkName::Eip7805 => "eip7805".fmt(f), ForkName::Fulu => "fulu".fmt(f), ForkName::Gloas => "gloas".fmt(f), + ForkName::Heze => "heze".fmt(f), } } } diff --git a/consensus/types/src/light_client/error.rs b/consensus/types/src/light_client/error.rs index 4c7a30db5e..17a499962c 100644 --- a/consensus/types/src/light_client/error.rs +++ b/consensus/types/src/light_client/error.rs @@ -15,6 +15,7 @@ pub enum LightClientError { BeaconBlockBodyError, InconsistentFork, GloasNotImplemented, + HezeNotImplemented, } impl From for LightClientError { diff --git a/consensus/types/src/light_client/light_client_bootstrap.rs b/consensus/types/src/light_client/light_client_bootstrap.rs index 43cdc6a6bd..f0b6b3f7a9 100644 --- a/consensus/types/src/light_client/light_client_bootstrap.rs +++ b/consensus/types/src/light_client/light_client_bootstrap.rs @@ -115,12 +115,12 @@ impl LightClientBootstrap { } ForkName::Capella => Self::Capella(LightClientBootstrapCapella::from_ssz_bytes(bytes)?), ForkName::Deneb => Self::Deneb(LightClientBootstrapDeneb::from_ssz_bytes(bytes)?), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(LightClientBootstrapElectra::from_ssz_bytes(bytes)?) } ForkName::Fulu => Self::Fulu(LightClientBootstrapFulu::from_ssz_bytes(bytes)?), // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(ssz::DecodeError::BytesInvalid(format!( "LightClientBootstrap decoding for {fork_name} not implemented" ))); @@ -139,12 +139,14 @@ impl LightClientBootstrap { } ForkName::Capella => as Encode>::ssz_fixed_len(), ForkName::Deneb => as Encode>::ssz_fixed_len(), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { as Encode>::ssz_fixed_len() } ForkName::Fulu => as Encode>::ssz_fixed_len(), // TODO(gloas): implement Gloas light client - ForkName::Gloas => as Encode>::ssz_fixed_len(), + ForkName::Gloas | ForkName::Heze => { + as Encode>::ssz_fixed_len() + } }; fixed_len + LightClientHeader::::ssz_max_var_len_for_fork(fork_name) } @@ -181,7 +183,7 @@ impl LightClientBootstrap { .try_into() .map_err(LightClientError::SszTypesError)?, }), - ForkName::Electra | ForkName::Eip7805 => Self::Electra(LightClientBootstrapElectra { + ForkName::Electra | ForkName::Heze => Self::Electra(LightClientBootstrapElectra { header: LightClientHeaderElectra::block_to_light_client_header(block)?, current_sync_committee, current_sync_committee_branch: current_sync_committee_branch @@ -197,6 +199,7 @@ impl LightClientBootstrap { }), // TODO(gloas): implement Gloas light client ForkName::Gloas => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::HezeNotImplemented), }; Ok(light_client_bootstrap) @@ -236,7 +239,7 @@ impl LightClientBootstrap { .try_into() .map_err(LightClientError::SszTypesError)?, }), - ForkName::Electra | ForkName::Eip7805 => Self::Electra(LightClientBootstrapElectra { + ForkName::Electra | ForkName::Heze => Self::Electra(LightClientBootstrapElectra { header: LightClientHeaderElectra::block_to_light_client_header(block)?, current_sync_committee, current_sync_committee_branch: current_sync_committee_branch @@ -252,6 +255,7 @@ impl LightClientBootstrap { }), // TODO(gloas): implement Gloas light client ForkName::Gloas => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::HezeNotImplemented), }; Ok(light_client_bootstrap) @@ -285,13 +289,13 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientBootstrap ForkName::Deneb => { Self::Deneb(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } ForkName::Fulu => { Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Gloas => { + ForkName::Gloas | ForkName::Heze => { // TODO(EIP-7732): check if this is correct return Err(serde::de::Error::custom(format!( "LightClientBootstrap failed to deserialize: unsupported fork '{}'", diff --git a/consensus/types/src/light_client/light_client_finality_update.rs b/consensus/types/src/light_client/light_client_finality_update.rs index 7b6bd6bc98..2a17def874 100644 --- a/consensus/types/src/light_client/light_client_finality_update.rs +++ b/consensus/types/src/light_client/light_client_finality_update.rs @@ -177,8 +177,9 @@ impl LightClientFinalityUpdate { sync_aggregate, signature_slot, }), - ForkName::Eip7805 => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::GloasNotImplemented), ForkName::Gloas => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::HezeNotImplemented), ForkName::Base => return Err(LightClientError::AltairForkNotActive), }; @@ -228,12 +229,12 @@ impl LightClientFinalityUpdate { Self::Capella(LightClientFinalityUpdateCapella::from_ssz_bytes(bytes)?) } ForkName::Deneb => Self::Deneb(LightClientFinalityUpdateDeneb::from_ssz_bytes(bytes)?), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(LightClientFinalityUpdateElectra::from_ssz_bytes(bytes)?) } ForkName::Fulu => Self::Fulu(LightClientFinalityUpdateFulu::from_ssz_bytes(bytes)?), // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(ssz::DecodeError::BytesInvalid(format!( "LightClientFinalityUpdate decoding for {fork_name} not implemented" ))); @@ -252,12 +253,12 @@ impl LightClientFinalityUpdate { } ForkName::Capella => as Encode>::ssz_fixed_len(), ForkName::Deneb => as Encode>::ssz_fixed_len(), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { as Encode>::ssz_fixed_len() } ForkName::Fulu => as Encode>::ssz_fixed_len(), // TODO(gloas): implement Gloas light client - ForkName::Gloas => 0, + ForkName::Gloas | ForkName::Heze => 0, }; // `2 *` because there are two headers in the update fixed_size + 2 * LightClientHeader::::ssz_max_var_len_for_fork(fork_name) @@ -304,13 +305,13 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientFinalityU ForkName::Deneb => { Self::Deneb(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } ForkName::Fulu => { Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Gloas => { + ForkName::Gloas | ForkName::Heze => { // TODO(EIP-7732): check if this is correct return Err(serde::de::Error::custom(format!( "LightClientBootstrap failed to deserialize: unsupported fork '{}'", diff --git a/consensus/types/src/light_client/light_client_header.rs b/consensus/types/src/light_client/light_client_header.rs index 8db1e01be4..72283766e2 100644 --- a/consensus/types/src/light_client/light_client_header.rs +++ b/consensus/types/src/light_client/light_client_header.rs @@ -103,7 +103,7 @@ impl LightClientHeader { ForkName::Deneb => LightClientHeader::Deneb( LightClientHeaderDeneb::block_to_light_client_header(block)?, ), - ForkName::Electra | ForkName::Eip7805 => LightClientHeader::Electra( + ForkName::Electra | ForkName::Heze => LightClientHeader::Electra( LightClientHeaderElectra::block_to_light_client_header(block)?, ), ForkName::Fulu => { @@ -111,6 +111,7 @@ impl LightClientHeader { } // TODO(gloas): implement Gloas light client ForkName::Gloas => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::HezeNotImplemented), }; Ok(header) } @@ -126,14 +127,14 @@ impl LightClientHeader { ForkName::Deneb => { LightClientHeader::Deneb(LightClientHeaderDeneb::from_ssz_bytes(bytes)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { LightClientHeader::Electra(LightClientHeaderElectra::from_ssz_bytes(bytes)?) } ForkName::Fulu => { LightClientHeader::Fulu(LightClientHeaderFulu::from_ssz_bytes(bytes)?) } // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(ssz::DecodeError::BytesInvalid(format!( "LightClientHeader decoding for {fork_name} not implemented" ))); @@ -152,7 +153,7 @@ impl LightClientHeader { } pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize { - if fork_name.gloas_enabled() { + if fork_name.gloas_enabled() || fork_name.heze_enabled() { // TODO(EIP7732): check this 0 } else if fork_name.capella_enabled() { @@ -364,7 +365,7 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientHeader }; Ok(match context { // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(serde::de::Error::custom(format!( "LightClientFinalityUpdate failed to deserialize: unsupported fork '{}'", context @@ -379,7 +380,7 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientHeader ForkName::Deneb => { Self::Deneb(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } ForkName::Fulu => { diff --git a/consensus/types/src/light_client/light_client_optimistic_update.rs b/consensus/types/src/light_client/light_client_optimistic_update.rs index 9d6da2b1d2..f92d4f640b 100644 --- a/consensus/types/src/light_client/light_client_optimistic_update.rs +++ b/consensus/types/src/light_client/light_client_optimistic_update.rs @@ -109,7 +109,7 @@ impl LightClientOptimisticUpdate { sync_aggregate, signature_slot, }), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(LightClientOptimisticUpdateElectra { attested_header: LightClientHeaderElectra::block_to_light_client_header( attested_block, @@ -126,6 +126,7 @@ impl LightClientOptimisticUpdate { signature_slot, }), ForkName::Gloas => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::HezeNotImplemented), ForkName::Base => return Err(LightClientError::AltairForkNotActive), }; @@ -177,12 +178,12 @@ impl LightClientOptimisticUpdate { ForkName::Deneb => { Self::Deneb(LightClientOptimisticUpdateDeneb::from_ssz_bytes(bytes)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(LightClientOptimisticUpdateElectra::from_ssz_bytes(bytes)?) } ForkName::Fulu => Self::Fulu(LightClientOptimisticUpdateFulu::from_ssz_bytes(bytes)?), // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(ssz::DecodeError::BytesInvalid(format!( "LightClientOptimisticUpdate decoding for {fork_name} not implemented" ))); @@ -201,12 +202,12 @@ impl LightClientOptimisticUpdate { } ForkName::Capella => as Encode>::ssz_fixed_len(), ForkName::Deneb => as Encode>::ssz_fixed_len(), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { as Encode>::ssz_fixed_len() } ForkName::Fulu => as Encode>::ssz_fixed_len(), // TODO(gloas): implement Gloas light client - ForkName::Gloas => 0, + ForkName::Gloas | ForkName::Heze => 0, }; fixed_len + LightClientHeader::::ssz_max_var_len_for_fork(fork_name) } @@ -252,13 +253,13 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientOptimisti ForkName::Deneb => { Self::Deneb(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } ForkName::Fulu => { Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Gloas => { + ForkName::Gloas | ForkName::Heze => { // TODO(EIP-7732): check if this is correct return Err(serde::de::Error::custom(format!( "LightClientBootstrap failed to deserialize: unsupported fork '{}'", diff --git a/consensus/types/src/light_client/light_client_update.rs b/consensus/types/src/light_client/light_client_update.rs index da103c7976..6498d9bbf8 100644 --- a/consensus/types/src/light_client/light_client_update.rs +++ b/consensus/types/src/light_client/light_client_update.rs @@ -141,7 +141,7 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientUpdate }; Ok(match context { // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(serde::de::Error::custom(format!( "LightClientUpdate failed to deserialize: unsupported fork '{}'", context @@ -156,7 +156,7 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for LightClientUpdate ForkName::Deneb => { Self::Deneb(Deserialize::deserialize(deserializer).map_err(convert_err)?) } - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(Deserialize::deserialize(deserializer).map_err(convert_err)?) } ForkName::Fulu => { @@ -267,7 +267,7 @@ impl LightClientUpdate { signature_slot: block_slot, }) } - fork_name @ ForkName::Electra | fork_name @ ForkName::Eip7805 => { + fork_name @ ForkName::Electra | fork_name @ ForkName::Heze => { let attested_header = LightClientHeaderElectra::block_to_light_client_header(attested_block)?; @@ -328,6 +328,7 @@ impl LightClientUpdate { // if you need to test or support lightclient usages // TODO(gloas): implement Gloas light client ForkName::Gloas => return Err(LightClientError::GloasNotImplemented), + ForkName::Heze => return Err(LightClientError::HezeNotImplemented), }; Ok(light_client_update) @@ -340,12 +341,12 @@ impl LightClientUpdate { } ForkName::Capella => Self::Capella(LightClientUpdateCapella::from_ssz_bytes(bytes)?), ForkName::Deneb => Self::Deneb(LightClientUpdateDeneb::from_ssz_bytes(bytes)?), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { Self::Electra(LightClientUpdateElectra::from_ssz_bytes(bytes)?) } ForkName::Fulu => Self::Fulu(LightClientUpdateFulu::from_ssz_bytes(bytes)?), // TODO(gloas): implement Gloas light client - ForkName::Base | ForkName::Gloas => { + ForkName::Base | ForkName::Gloas | ForkName::Heze => { return Err(ssz::DecodeError::BytesInvalid(format!( "LightClientUpdate decoding for {fork_name} not implemented" ))); @@ -499,12 +500,12 @@ impl LightClientUpdate { ForkName::Altair => as Encode>::ssz_fixed_len(), ForkName::Capella => as Encode>::ssz_fixed_len(), ForkName::Deneb => as Encode>::ssz_fixed_len(), - ForkName::Electra | ForkName::Eip7805 => { + ForkName::Electra | ForkName::Heze => { as Encode>::ssz_fixed_len() } ForkName::Fulu => as Encode>::ssz_fixed_len(), // TODO(gloas): implement Gloas light client - ForkName::Gloas => 0, + ForkName::Gloas | ForkName::Heze => 0, }; fixed_len + 2 * LightClientHeader::::ssz_max_var_len_for_fork(fork_name) } diff --git a/consensus/types/src/state/beacon_state.rs b/consensus/types/src/state/beacon_state.rs index 52be7fd029..1478561c43 100644 --- a/consensus/types/src/state/beacon_state.rs +++ b/consensus/types/src/state/beacon_state.rs @@ -36,7 +36,7 @@ use crate::{ deposit::PendingDeposit, execution::{ Eth1Data, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella, - ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderEip7805, ExecutionPayloadHeaderElectra, + ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderHeze, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, InclusionListCommittee, InclusionListDuty, }, @@ -279,7 +279,7 @@ impl From for Hash256 { /// /// https://github.com/sigp/milhouse/issues/43 #[superstruct( - variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas), + variants(Base, Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze), variant_attributes( derive( Educe, @@ -400,20 +400,6 @@ impl From for Hash256 { )), num_fields(all()), )), - Eip7805(metastruct( - mappings( - map_beacon_state_eip7805_fields(), - map_beacon_state_eip7805_tree_list_fields(mutable, fallible, groups(tree_lists)), - map_beacon_state_eip7805_tree_list_fields_immutable(groups(tree_lists)), - ), - bimappings(bimap_beacon_state_eip7805_tree_list_fields( - other_type = "BeaconStateEip7805", - self_mutable, - fallible, - groups(tree_lists) - )), - num_fields(all()), - )), Gloas(metastruct( mappings( map_beacon_state_gloas_fields(), @@ -427,6 +413,20 @@ impl From for Hash256 { groups(tree_lists) )), num_fields(all()), + )), + Heze(metastruct( + mappings( + map_beacon_state_heze_fields(), + map_beacon_state_heze_tree_list_fields(mutable, fallible, groups(tree_lists)), + map_beacon_state_heze_tree_list_fields_immutable(groups(tree_lists)), + ), + bimappings(bimap_beacon_state_heze_tree_list_fields( + other_type = "BeaconStateHeze", + self_mutable, + fallible, + groups(tree_lists) + )), + num_fields(all()), )) ), cast_error( @@ -519,11 +519,11 @@ where // Participation (Altair and later) #[compare_fields(as_iter)] - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze))] #[test_random(default)] #[compare_fields(as_iter)] pub previous_epoch_participation: List, - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze))] #[test_random(default)] pub current_epoch_participation: List, @@ -543,15 +543,15 @@ where // Inactivity #[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")] - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze))] #[test_random(default)] pub inactivity_scores: List, // Light-client sync committees - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze))] #[metastruct(exclude_from(tree_lists))] pub current_sync_committee: Arc>, - #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Altair, Bellatrix, Capella, Deneb, Electra, Fulu, Gloas, Heze))] #[metastruct(exclude_from(tree_lists))] pub next_sync_committee: Arc>, @@ -586,117 +586,105 @@ where )] #[metastruct(exclude_from(tree_lists))] pub latest_execution_payload_header: ExecutionPayloadHeaderFulu, - #[superstruct( - only(Eip7805), - partial_getter(rename = "latest_execution_payload_header_eip7805") - )] - #[metastruct(exclude_from(tree_lists))] - pub latest_execution_payload_header: ExecutionPayloadHeaderEip7805, #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[metastruct(exclude_from(tree_lists))] pub latest_block_hash: ExecutionBlockHash, - #[superstruct( - only(Capella, Deneb, Electra, Fulu, Eip7805, Gloas), - partial_getter(copy) - )] + #[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[serde(with = "serde_utils::quoted_u64")] #[metastruct(exclude_from(tree_lists))] pub next_withdrawal_index: u64, - #[superstruct( - only(Capella, Deneb, Electra, Fulu, Eip7805, Gloas), - partial_getter(copy) - )] + #[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[serde(with = "serde_utils::quoted_u64")] #[metastruct(exclude_from(tree_lists))] pub next_withdrawal_validator_index: u64, // Deep history valid from Capella onwards. - #[superstruct(only(Capella, Deneb, Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas, Heze))] #[test_random(default)] pub historical_summaries: List, // Electra - #[superstruct(only(Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[metastruct(exclude_from(tree_lists))] #[serde(with = "serde_utils::quoted_u64")] pub deposit_requests_start_index: u64, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[metastruct(exclude_from(tree_lists))] #[serde(with = "serde_utils::quoted_u64")] pub deposit_balance_to_consume: u64, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[metastruct(exclude_from(tree_lists))] #[serde(with = "serde_utils::quoted_u64")] pub exit_balance_to_consume: u64, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[metastruct(exclude_from(tree_lists))] pub earliest_exit_epoch: Epoch, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[metastruct(exclude_from(tree_lists))] #[serde(with = "serde_utils::quoted_u64")] pub consolidation_balance_to_consume: u64, - #[superstruct(only(Electra, Fulu, Eip7805, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Fulu, Gloas, Heze), partial_getter(copy))] #[metastruct(exclude_from(tree_lists))] pub earliest_consolidation_epoch: Epoch, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] pub pending_deposits: List, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] pub pending_partial_withdrawals: List, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Electra, Fulu, Eip7805, Gloas))] + #[superstruct(only(Electra, Fulu, Gloas, Heze))] pub pending_consolidations: List, // Fulu #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Fulu, Eip7805, Gloas))] + #[superstruct(only(Fulu, Gloas, Heze))] #[serde(with = "ssz_types::serde_utils::quoted_u64_fixed_vec")] pub proposer_lookahead: Vector, // Gloas #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub builders: List, #[metastruct(exclude_from(tree_lists))] #[serde(with = "serde_utils::quoted_u64")] - #[superstruct(only(Gloas), partial_getter(copy))] + #[superstruct(only(Gloas, Heze), partial_getter(copy))] pub next_withdrawal_builder_index: BuilderIndex, #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[metastruct(exclude_from(tree_lists))] pub execution_payload_availability: BitVector, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub builder_pending_payments: Vector, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub builder_pending_withdrawals: List, - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] #[metastruct(exclude_from(tree_lists))] pub latest_execution_payload_bid: ExecutionPayloadBid, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub payload_expected_withdrawals: List, #[compare_fields(as_iter)] #[test_random(default)] - #[superstruct(only(Gloas))] + #[superstruct(only(Gloas, Heze))] pub ptc_window: Vector, E::PtcWindowLength>, // Caching (not in the spec) @@ -838,8 +826,9 @@ impl BeaconState { BeaconState::Deneb { .. } => ForkName::Deneb, BeaconState::Electra { .. } => ForkName::Electra, BeaconState::Fulu { .. } => ForkName::Fulu, - BeaconState::Eip7805 { .. } => ForkName::Eip7805, + BeaconState::Heze { .. } => ForkName::Heze, BeaconState::Gloas { .. } => ForkName::Gloas, + BeaconState::Heze { .. } => ForkName::Heze, } } @@ -1318,11 +1307,9 @@ impl BeaconState { BeaconState::Fulu(state) => Ok(ExecutionPayloadHeaderRef::Fulu( &state.latest_execution_payload_header, )), - BeaconState::Eip7805(state) => Ok(ExecutionPayloadHeaderRef::Eip7805( - &state.latest_execution_payload_header, - )), // TODO(EIP-7732): investigate calling functions BeaconState::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant), + BeaconState::Heze(_) => Err(BeaconStateError::IncorrectStateVariant), } } @@ -1348,11 +1335,9 @@ impl BeaconState { BeaconState::Fulu(state) => Ok(ExecutionPayloadHeaderRefMut::Fulu( &mut state.latest_execution_payload_header, )), - BeaconState::Eip7805(state) => Ok(ExecutionPayloadHeaderRefMut::Eip7805( - &mut state.latest_execution_payload_header, - )), // TODO(EIP-7732): investigate calling functions BeaconState::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant), + BeaconState::Heze(_) => Err(BeaconStateError::IncorrectStateVariant), } } @@ -1974,7 +1959,7 @@ impl BeaconState { &mut state.exit_cache, &mut state.epoch_cache, )), - BeaconState::Eip7805(state) => Ok(( + BeaconState::Heze(state) => Ok(( &mut state.validators, &mut state.balances, &state.previous_epoch_participation, @@ -2004,6 +1989,16 @@ impl BeaconState { &mut state.exit_cache, &mut state.epoch_cache, )), + BeaconState::Heze(state) => Ok(( + &mut state.validators, + &mut state.balances, + &state.previous_epoch_participation, + &state.current_epoch_participation, + &mut state.inactivity_scores, + &mut state.progressive_balances_cache, + &mut state.exit_cache, + &mut state.epoch_cache, + )), } } @@ -2268,8 +2263,8 @@ impl BeaconState { BeaconState::Deneb(_) | BeaconState::Electra(_) | BeaconState::Fulu(_) - | BeaconState::Eip7805(_) - | BeaconState::Gloas(_) => std::cmp::min( + | BeaconState::Gloas(_) + | BeaconState::Heze(_) => std::cmp::min( spec.max_per_epoch_activation_churn_limit, self.get_validator_churn_limit(spec)?, ), @@ -2440,8 +2435,9 @@ impl BeaconState { BeaconState::Deneb(state) => Ok(&mut state.current_epoch_participation), BeaconState::Electra(state) => Ok(&mut state.current_epoch_participation), BeaconState::Fulu(state) => Ok(&mut state.current_epoch_participation), - BeaconState::Eip7805(state) => Ok(&mut state.current_epoch_participation), + BeaconState::Heze(state) => Ok(&mut state.current_epoch_participation), BeaconState::Gloas(state) => Ok(&mut state.current_epoch_participation), + BeaconState::Heze(state) => Ok(&mut state.current_epoch_participation), } } else if epoch == previous_epoch { match self { @@ -2452,8 +2448,9 @@ impl BeaconState { BeaconState::Deneb(state) => Ok(&mut state.previous_epoch_participation), BeaconState::Electra(state) => Ok(&mut state.previous_epoch_participation), BeaconState::Fulu(state) => Ok(&mut state.previous_epoch_participation), - BeaconState::Eip7805(state) => Ok(&mut state.previous_epoch_participation), + BeaconState::Heze(state) => Ok(&mut state.previous_epoch_participation), BeaconState::Gloas(state) => Ok(&mut state.previous_epoch_participation), + BeaconState::Heze(state) => Ok(&mut state.previous_epoch_participation), } } else { Err(BeaconStateError::EpochOutOfBounds) @@ -2617,7 +2614,7 @@ impl BeaconState { | BeaconState::Deneb(_) | BeaconState::Electra(_) | BeaconState::Fulu(_) - | BeaconState::Eip7805(_) => true, + | BeaconState::Heze(_) => true, BeaconState::Gloas(state) => { state.latest_execution_payload_bid.block_hash == state.latest_block_hash } @@ -2764,8 +2761,8 @@ impl BeaconState { } ); } - Self::Eip7805(self_inner) => { - map_beacon_state_eip7805_tree_list_fields_immutable!( + Self::Heze(self_inner) => { + map_beacon_state_heze_tree_list_fields_immutable!( self_inner, |_, self_field| { any_pending_mutations |= self_field.has_pending_updates(); @@ -2782,6 +2779,11 @@ impl BeaconState { any_pending_mutations |= self_field.has_pending_updates(); }); } + Self::Heze(self_inner) => { + map_beacon_state_heze_tree_list_fields_immutable!(self_inner, |_, self_field| { + any_pending_mutations |= self_field.has_pending_updates(); + }); + } }; any_pending_mutations } @@ -3080,8 +3082,8 @@ impl BeaconState { | BeaconState::Deneb(_) => Err(BeaconStateError::IncorrectStateVariant), BeaconState::Electra(_) | BeaconState::Fulu(_) - | BeaconState::Eip7805(_) - | BeaconState::Gloas(_) => { + | BeaconState::Gloas(_) + | BeaconState::Heze(_) => { // Consume the balance and update state variables *self.exit_balance_to_consume_mut()? = exit_balance_to_consume.safe_sub(exit_balance)?; @@ -3130,8 +3132,8 @@ impl BeaconState { | BeaconState::Deneb(_) => Err(BeaconStateError::IncorrectStateVariant), BeaconState::Electra(_) | BeaconState::Fulu(_) - | BeaconState::Eip7805(_) - | BeaconState::Gloas(_) => { + | BeaconState::Gloas(_) + | BeaconState::Heze(_) => { // Consume the balance and update state variables. *self.consolidation_balance_to_consume_mut()? = consolidation_balance_to_consume.safe_sub(consolidation_balance)?; @@ -3201,14 +3203,14 @@ impl BeaconState { ); } (Self::Fulu(_), _) => (), - (Self::Eip7805(self_inner), Self::Eip7805(base_inner)) => { - bimap_beacon_state_eip7805_tree_list_fields!( + (Self::Heze(self_inner), Self::Heze(base_inner)) => { + bimap_beacon_state_heze_tree_list_fields!( self_inner, base_inner, |_, self_field, base_field| { self_field.rebase_on(base_field) } ); } - (Self::Eip7805(_), _) => (), + (Self::Heze(_), _) => (), (Self::Gloas(self_inner), Self::Gloas(base_inner)) => { bimap_beacon_state_gloas_tree_list_fields!( self_inner, @@ -3217,6 +3219,14 @@ impl BeaconState { ); } (Self::Gloas(_), _) => (), + (Self::Heze(self_inner), Self::Heze(base_inner)) => { + bimap_beacon_state_heze_tree_list_fields!( + self_inner, + base_inner, + |_, self_field, base_field| { self_field.rebase_on(base_field) } + ); + } + (Self::Heze(_), _) => (), } // Use sync committees from `base` if they are equal. @@ -3537,8 +3547,9 @@ impl BeaconState { ForkName::Deneb => BeaconStateDeneb::::NUM_FIELDS.next_power_of_two(), ForkName::Electra => BeaconStateElectra::::NUM_FIELDS.next_power_of_two(), ForkName::Fulu => BeaconStateFulu::::NUM_FIELDS.next_power_of_two(), - ForkName::Eip7805 => BeaconStateEip7805::::NUM_FIELDS.next_power_of_two(), + ForkName::Heze => BeaconStateHeze::::NUM_FIELDS.next_power_of_two(), ForkName::Gloas => BeaconStateGloas::::NUM_FIELDS.next_power_of_two(), + ForkName::Heze => BeaconStateHeze::::NUM_FIELDS.next_power_of_two(), } } @@ -3586,8 +3597,8 @@ impl BeaconState { Self::Electra(inner) => { map_beacon_state_electra_tree_list_fields!(inner, |_, x| { x.apply_updates() }) } - Self::Eip7805(inner) => { - map_beacon_state_eip7805_tree_list_fields!(inner, |_, x| { x.apply_updates() }) + Self::Heze(inner) => { + map_beacon_state_heze_tree_list_fields!(inner, |_, x| { x.apply_updates() }) } Self::Fulu(inner) => { map_beacon_state_fulu_tree_list_fields!(inner, |_, x| { x.apply_updates() }) @@ -3595,6 +3606,9 @@ impl BeaconState { Self::Gloas(inner) => { map_beacon_state_gloas_tree_list_fields!(inner, |_, x| { x.apply_updates() }) } + Self::Heze(inner) => { + map_beacon_state_heze_tree_list_fields!(inner, |_, x| { x.apply_updates() }) + } } Ok(()) } @@ -3702,8 +3716,8 @@ impl BeaconState { leaves.push(field.tree_hash_root()); }); } - BeaconState::Eip7805(state) => { - map_beacon_state_eip7805_fields!(state, |_, field| { + BeaconState::Heze(state) => { + map_beacon_state_heze_fields!(state, |_, field| { leaves.push(field.tree_hash_root()); }); } @@ -3717,6 +3731,11 @@ impl BeaconState { leaves.push(field.tree_hash_root()); }); } + BeaconState::Heze(state) => { + map_beacon_state_heze_fields!(state, |_, field| { + leaves.push(field.tree_hash_root()); + }); + } }; leaves @@ -3774,9 +3793,10 @@ impl CompareFields for BeaconState { (BeaconState::Capella(x), BeaconState::Capella(y)) => x.compare_fields(y), (BeaconState::Deneb(x), BeaconState::Deneb(y)) => x.compare_fields(y), (BeaconState::Electra(x), BeaconState::Electra(y)) => x.compare_fields(y), - (BeaconState::Eip7805(x), BeaconState::Eip7805(y)) => x.compare_fields(y), + (BeaconState::Heze(x), BeaconState::Heze(y)) => x.compare_fields(y), (BeaconState::Fulu(x), BeaconState::Fulu(y)) => x.compare_fields(y), (BeaconState::Gloas(x), BeaconState::Gloas(y)) => x.compare_fields(y), + (BeaconState::Heze(x), BeaconState::Heze(y)) => x.compare_fields(y), _ => panic!("compare_fields: mismatched state variants",), } } diff --git a/consensus/types/src/state/inclusion_list_cache.rs b/consensus/types/src/state/inclusion_list_cache.rs index bad5df9736..ccc5eceda3 100644 --- a/consensus/types/src/state/inclusion_list_cache.rs +++ b/consensus/types/src/state/inclusion_list_cache.rs @@ -102,7 +102,7 @@ impl InclusionListCache { .iter() .cloned() .collect::>(); - // TODO(eip7805) should return an error instead of None? + // TODO(heze) should return an error instead of None? il.try_into().ok() } } diff --git a/consensus/types/src/state/mod.rs b/consensus/types/src/state/mod.rs index c833fadb64..9b1d69bd9a 100644 --- a/consensus/types/src/state/mod.rs +++ b/consensus/types/src/state/mod.rs @@ -17,8 +17,8 @@ pub use activation_queue::ActivationQueue; pub use balance::Balance; pub use beacon_state::{ BeaconState, BeaconStateAltair, BeaconStateBase, BeaconStateBellatrix, BeaconStateCapella, - BeaconStateDeneb, BeaconStateEip7805, BeaconStateElectra, BeaconStateError, BeaconStateFulu, - BeaconStateGloas, BeaconStateHash, BeaconStateRef, CACHED_EPOCHS, DEFAULT_PRE_ELECTRA_WS_PERIOD, + BeaconStateDeneb, BeaconStateElectra, BeaconStateError, BeaconStateFulu, BeaconStateGloas, + BeaconStateHash, BeaconStateHeze, BeaconStateRef, CACHED_EPOCHS, DEFAULT_PRE_ELECTRA_WS_PERIOD, Validators, }; pub use committee_cache::{ diff --git a/consensus/types/src/withdrawal/expected_withdrawals.rs b/consensus/types/src/withdrawal/expected_withdrawals.rs index f9809e6e73..1c8932a7ad 100644 --- a/consensus/types/src/withdrawal/expected_withdrawals.rs +++ b/consensus/types/src/withdrawal/expected_withdrawals.rs @@ -2,17 +2,17 @@ use crate::{EthSpec, Withdrawals}; use superstruct::superstruct; #[superstruct( - variants(Capella, Electra, Gloas), + variants(Capella, Electra, Gloas, Heze), variant_attributes(derive(Debug, PartialEq, Clone)) )] #[derive(Debug, PartialEq, Clone)] pub struct ExpectedWithdrawals { pub withdrawals: Withdrawals, - #[superstruct(only(Gloas), partial_getter(copy))] + #[superstruct(only(Gloas, Heze), partial_getter(copy))] pub processed_builder_withdrawals_count: u64, - #[superstruct(only(Electra, Gloas), partial_getter(copy))] + #[superstruct(only(Electra, Gloas, Heze), partial_getter(copy))] pub processed_partial_withdrawals_count: u64, - #[superstruct(only(Gloas), partial_getter(copy))] + #[superstruct(only(Gloas, Heze), partial_getter(copy))] pub processed_builders_sweep_count: u64, #[superstruct(getter(copy))] pub processed_sweep_withdrawals_count: u64, @@ -24,6 +24,7 @@ impl From> for Withdrawals { ExpectedWithdrawals::Capella(ew) => ew.withdrawals, ExpectedWithdrawals::Electra(ew) => ew.withdrawals, ExpectedWithdrawals::Gloas(ew) => ew.withdrawals, + ExpectedWithdrawals::Heze(ew) => ew.withdrawals, } } } diff --git a/consensus/types/src/withdrawal/mod.rs b/consensus/types/src/withdrawal/mod.rs index fbe7351754..696dbbd64c 100644 --- a/consensus/types/src/withdrawal/mod.rs +++ b/consensus/types/src/withdrawal/mod.rs @@ -6,7 +6,7 @@ mod withdrawal_request; pub use expected_withdrawals::{ ExpectedWithdrawals, ExpectedWithdrawalsCapella, ExpectedWithdrawalsElectra, - ExpectedWithdrawalsGloas, + ExpectedWithdrawalsGloas, ExpectedWithdrawalsHeze, }; pub use pending_partial_withdrawal::PendingPartialWithdrawal; pub use withdrawal::{Withdrawal, Withdrawals}; diff --git a/lcli/src/mock_el.rs b/lcli/src/mock_el.rs index dc913595e2..ec8f0216ee 100644 --- a/lcli/src/mock_el.rs +++ b/lcli/src/mock_el.rs @@ -18,9 +18,9 @@ pub fn run(mut env: Environment, matches: &ArgMatches) -> Result< let shanghai_time = parse_required(matches, "shanghai-time")?; let cancun_time = parse_optional(matches, "cancun-time")?; let prague_time = parse_optional(matches, "prague-time")?; - let eip7805_time = parse_optional(matches, "eip7805-time")?; let osaka_time = parse_optional(matches, "osaka-time")?; let amsterdam_time = parse_optional(matches, "amsterdam-time")?; + let heze_time: Option = parse_optional(matches, "heze-time")?; let handle = env.core_context().executor.handle().unwrap(); @@ -48,11 +48,11 @@ pub fn run(mut env: Environment, matches: &ArgMatches) -> Result< }, jwt_key, shanghai_time: Some(shanghai_time), - eip7805_time, cancun_time, prague_time, osaka_time, amsterdam_time, + heze_time, }; let kzg = None; let server: MockServer = MockServer::new_with_config(&handle, config, kzg); diff --git a/testing/ef_tests/src/cases/fork.rs b/testing/ef_tests/src/cases/fork.rs index 45d976f7c9..a425e662d9 100644 --- a/testing/ef_tests/src/cases/fork.rs +++ b/testing/ef_tests/src/cases/fork.rs @@ -4,7 +4,7 @@ use crate::decode::{ssz_decode_state, yaml_decode_file}; use serde::Deserialize; use state_processing::upgrade::{ upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb, - upgrade_to_eip7805, upgrade_to_electra, upgrade_to_fulu, upgrade_to_gloas, + upgrade_to_electra, upgrade_to_fulu, upgrade_to_gloas, upgrade_to_heze, }; use types::BeaconState; @@ -71,9 +71,10 @@ impl Case for ForkTest { ForkName::Capella => upgrade_to_capella(&mut result_state, spec).map(|_| result_state), ForkName::Deneb => upgrade_to_deneb(&mut result_state, spec).map(|_| result_state), ForkName::Electra => upgrade_to_electra(&mut result_state, spec).map(|_| result_state), - ForkName::Eip7805 => upgrade_to_eip7805(&mut result_state, spec).map(|_| result_state), + ForkName::Heze => upgrade_to_heze(&mut result_state, spec).map(|_| result_state), ForkName::Fulu => upgrade_to_fulu(&mut result_state, spec).map(|_| result_state), ForkName::Gloas => upgrade_to_gloas(&mut result_state, spec).map(|_| result_state), + ForkName::Heze => upgrade_to_heze(&mut result_state, spec).map(|_| result_state), }; compare_beacon_state_results_without_caches(&mut result, &mut expected) diff --git a/testing/ef_tests/src/cases/merkle_proof_validity.rs b/testing/ef_tests/src/cases/merkle_proof_validity.rs index 55098a2f82..819d704ce6 100644 --- a/testing/ef_tests/src/cases/merkle_proof_validity.rs +++ b/testing/ef_tests/src/cases/merkle_proof_validity.rs @@ -5,8 +5,8 @@ use ssz_types::FixedVector; use tree_hash::Hash256; use typenum::Unsigned; use types::{ - BeaconBlockBody, BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyEip7805, - BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconState, FullPayload, + BeaconBlockBody, BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, + BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconBlockBodyHeze, BeaconState, FullPayload, light_client, }; @@ -172,8 +172,8 @@ impl LoadCase for KzgInclusionMerkleProofValidity { ssz_decode_file::>(&path.join("object.ssz_snappy"))? .into() } - ForkName::Eip7805 => { - ssz_decode_file::>(&path.join("object.ssz_snappy"))? + ForkName::Heze => { + ssz_decode_file::>(&path.join("object.ssz_snappy"))? .into() } ForkName::Fulu => { @@ -182,6 +182,9 @@ impl LoadCase for KzgInclusionMerkleProofValidity { ForkName::Gloas => { ssz_decode_file::>(&path.join("object.ssz_snappy"))?.into() } + ForkName::Heze => { + ssz_decode_file::>(&path.join("object.ssz_snappy"))?.into() + } }; let merkle_proof = yaml_decode_file(&path.join("proof.yaml"))?; // Metadata does not exist in these tests but it is left like this just in case. @@ -297,8 +300,8 @@ impl LoadCase for BeaconBlockBodyMerkleProofValidity { ssz_decode_file::>(&path.join("object.ssz_snappy"))? .into() } - ForkName::Eip7805 => { - ssz_decode_file::>(&path.join("object.ssz_snappy"))? + ForkName::Heze => { + ssz_decode_file::>(&path.join("object.ssz_snappy"))? .into() } ForkName::Fulu => { @@ -307,6 +310,9 @@ impl LoadCase for BeaconBlockBodyMerkleProofValidity { ForkName::Gloas => { ssz_decode_file::>(&path.join("object.ssz_snappy"))?.into() } + ForkName::Heze => { + ssz_decode_file::>(&path.join("object.ssz_snappy"))?.into() + } }; let merkle_proof = yaml_decode_file(&path.join("proof.yaml"))?; // Metadata does not exist in these tests but it is left like this just in case. diff --git a/testing/ef_tests/src/cases/transition.rs b/testing/ef_tests/src/cases/transition.rs index 4ca838f77b..6b400a35f1 100644 --- a/testing/ef_tests/src/cases/transition.rs +++ b/testing/ef_tests/src/cases/transition.rs @@ -60,13 +60,13 @@ impl LoadCase for TransitionTest { spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.electra_fork_epoch = Some(metadata.fork_epoch); } - ForkName::Eip7805 => { + ForkName::Heze => { spec.altair_fork_epoch = Some(Epoch::new(0)); spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(0)); spec.deneb_fork_epoch = Some(Epoch::new(0)); spec.electra_fork_epoch = Some(Epoch::new(0)); - spec.eip7805_fork_epoch = Some(metadata.fork_epoch); + spec.heze_fork_epoch = Some(metadata.fork_epoch); } ForkName::Fulu => { spec.altair_fork_epoch = Some(Epoch::new(0)); @@ -85,6 +85,16 @@ impl LoadCase for TransitionTest { spec.fulu_fork_epoch = Some(Epoch::new(0)); spec.gloas_fork_epoch = Some(metadata.fork_epoch); } + ForkName::Heze => { + spec.altair_fork_epoch = Some(Epoch::new(0)); + spec.bellatrix_fork_epoch = Some(Epoch::new(0)); + spec.capella_fork_epoch = Some(Epoch::new(0)); + spec.deneb_fork_epoch = Some(Epoch::new(0)); + spec.electra_fork_epoch = Some(Epoch::new(0)); + spec.fulu_fork_epoch = Some(Epoch::new(0)); + spec.gloas_fork_epoch = Some(Epoch::new(0)); + spec.heze_fork_epoch = Some(metadata.fork_epoch); + } } // Load blocks diff --git a/testing/ef_tests/src/handler.rs b/testing/ef_tests/src/handler.rs index e380f51c0a..2a7e08dafe 100644 --- a/testing/ef_tests/src/handler.rs +++ b/testing/ef_tests/src/handler.rs @@ -309,6 +309,10 @@ impl SszStaticHandler { Self::for_forks(vec![ForkName::Gloas]) } + pub fn heze_only() -> Self { + Self::for_forks(vec![ForkName::Heze]) + } + pub fn altair_and_later() -> Self { Self::for_forks(ForkName::list_all()[1..].to_vec()) } @@ -337,6 +341,10 @@ impl SszStaticHandler { Self::for_forks(ForkName::list_all()[7..].to_vec()) } + pub fn heze_and_later() -> Self { + Self::for_forks(ForkName::list_all()[8..].to_vec()) + } + pub fn pre_electra() -> Self { Self::for_forks(ForkName::list_all()[0..5].to_vec()) } @@ -776,7 +784,7 @@ impl Handler for OptimisticSyncHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas optimistic sync tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1001,7 +1009,7 @@ impl Handler for KZGComputeCellsHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas KZG tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1026,7 +1034,7 @@ impl Handler for KZGComputeCellsAndKZGProofHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas KZG tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1051,7 +1059,7 @@ impl Handler for KZGVerifyCellKZGProofBatchHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas KZG tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1076,7 +1084,7 @@ impl Handler for KZGRecoverCellsAndKZGProofHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas KZG tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1105,7 +1113,7 @@ impl Handler for KzgInclusionMerkleProofValidityHandler Vec { // TODO(gloas): remove once we have Gloas KZG merkle proof tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1134,7 +1142,7 @@ impl Handler for MerkleProofValidityHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas light client tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } @@ -1164,7 +1172,7 @@ impl Handler for LightClientUpdateHandler { fn disabled_forks(&self) -> Vec { // TODO(gloas): remove once we have Gloas light client tests - vec![ForkName::Gloas] + vec![ForkName::Gloas, ForkName::Heze] } } diff --git a/testing/ef_tests/src/type_name.rs b/testing/ef_tests/src/type_name.rs index f64fd38ef7..3b447a1662 100644 --- a/testing/ef_tests/src/type_name.rs +++ b/testing/ef_tests/src/type_name.rs @@ -56,6 +56,7 @@ type_name_generic!(BeaconBlockBodyDeneb, "BeaconBlockBody"); type_name_generic!(BeaconBlockBodyElectra, "BeaconBlockBody"); type_name_generic!(BeaconBlockBodyFulu, "BeaconBlockBody"); type_name_generic!(BeaconBlockBodyGloas, "BeaconBlockBody"); +type_name_generic!(BeaconBlockBodyHeze, "BeaconBlockBody"); type_name!(BeaconBlockHeader); type_name_generic!(BeaconState); type_name!(BlobIdentifier); @@ -64,6 +65,7 @@ type_name_generic!(BlobSidecar); type_name_generic!(DataColumnSidecar); type_name_generic!(DataColumnSidecarFulu, "DataColumnSidecar"); type_name_generic!(DataColumnSidecarGloas, "DataColumnSidecar"); +type_name_generic!(DataColumnSidecarHeze, "DataColumnSidecar"); type_name!(Checkpoint); type_name!(ConsolidationRequest); type_name_generic!(ContributionAndProof); @@ -82,8 +84,8 @@ type_name_generic!(ExecutionPayloadCapella, "ExecutionPayload"); type_name_generic!(ExecutionPayloadDeneb, "ExecutionPayload"); type_name_generic!(ExecutionPayloadElectra, "ExecutionPayload"); type_name_generic!(ExecutionPayloadFulu, "ExecutionPayload"); -type_name_generic!(ExecutionPayloadEip7805, "ExecutionPayload"); type_name_generic!(ExecutionPayloadGloas, "ExecutionPayload"); +type_name_generic!(ExecutionPayloadHeze, "ExecutionPayload"); type_name_generic!(FullPayload, "ExecutionPayload"); type_name_generic!(ExecutionPayloadHeader); type_name_generic!(ExecutionPayloadHeaderBellatrix, "ExecutionPayloadHeader"); @@ -91,7 +93,7 @@ type_name_generic!(ExecutionPayloadHeaderCapella, "ExecutionPayloadHeader"); type_name_generic!(ExecutionPayloadHeaderDeneb, "ExecutionPayloadHeader"); type_name_generic!(ExecutionPayloadHeaderElectra, "ExecutionPayloadHeader"); type_name_generic!(ExecutionPayloadHeaderFulu, "ExecutionPayloadHeader"); -type_name_generic!(ExecutionPayloadHeaderEip7805, "ExecutionPayloadHeader"); +type_name_generic!(ExecutionPayloadHeaderHeze, "ExecutionPayloadHeader"); type_name_generic!(ExecutionPayloadBid); type_name_generic!(SignedExecutionPayloadBid); type_name_generic!(ExecutionRequests); diff --git a/testing/ef_tests/tests/tests.rs b/testing/ef_tests/tests/tests.rs index ca383efdb0..bdcba7dc15 100644 --- a/testing/ef_tests/tests/tests.rs +++ b/testing/ef_tests/tests/tests.rs @@ -417,6 +417,8 @@ mod ssz_static { .run(); SszStaticHandler::, MainnetEthSpec>::gloas_only() .run(); + SszStaticHandler::, MinimalEthSpec>::heze_only().run(); + SszStaticHandler::, MainnetEthSpec>::heze_only().run(); } // Altair and later @@ -648,6 +650,8 @@ mod ssz_static { .run(); SszStaticHandler::, MainnetEthSpec>::gloas_only() .run(); + SszStaticHandler::, MinimalEthSpec>::heze_only().run(); + SszStaticHandler::, MainnetEthSpec>::heze_only().run(); } #[test] @@ -734,6 +738,10 @@ mod ssz_static { .run(); SszStaticHandler::, MainnetEthSpec>::gloas_only() .run(); + SszStaticHandler::, MinimalEthSpec>::heze_only() + .run(); + SszStaticHandler::, MainnetEthSpec>::heze_only() + .run(); } #[test] diff --git a/validator_client/beacon_node_fallback/src/lib.rs b/validator_client/beacon_node_fallback/src/lib.rs index bbec7a0ff5..2cd7db557c 100644 --- a/validator_client/beacon_node_fallback/src/lib.rs +++ b/validator_client/beacon_node_fallback/src/lib.rs @@ -400,6 +400,13 @@ impl CandidateBeaconNode { hint = UPDATE_REQUIRED_LOG_HINT, "Beacon node has mismatched Gloas fork epoch" ); + } else if beacon_node_spec.heze_fork_epoch != spec.heze_fork_epoch { + warn!( + endpoint = %self.beacon_node, + endpoint_heze_fork_epoch = ?beacon_node_spec.heze_fork_epoch, + hint = UPDATE_REQUIRED_LOG_HINT, + "Beacon node has mismatched Heze fork epoch" + ); } Ok(()) diff --git a/validator_client/signing_method/src/web3signer.rs b/validator_client/signing_method/src/web3signer.rs index 800b4ae556..6dc19417b1 100644 --- a/validator_client/signing_method/src/web3signer.rs +++ b/validator_client/signing_method/src/web3signer.rs @@ -34,9 +34,9 @@ pub enum ForkName { Capella, Deneb, Electra, - Eip7805, Fulu, Gloas, + Heze, } #[derive(Debug, PartialEq, Serialize)] @@ -118,8 +118,8 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> Web3SignerObject<'a, E, Pa block: None, block_header: Some(block.block_header()), }), - BeaconBlock::Eip7805(_) => Ok(Web3SignerObject::BeaconBlock { - version: ForkName::Eip7805, + BeaconBlock::Heze(_) => Ok(Web3SignerObject::BeaconBlock { + version: ForkName::Heze, block: None, block_header: Some(block.block_header()), }), @@ -133,6 +133,11 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> Web3SignerObject<'a, E, Pa block: None, block_header: Some(block.block_header()), }), + BeaconBlock::Heze(_) => Ok(Web3SignerObject::BeaconBlock { + version: ForkName::Heze, + block: None, + block_header: Some(block.block_header()), + }), } }