diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index f3daf237b..cfbcdb912 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -1741,9 +1741,9 @@ impl ApiTester { pub async fn test_get_config_spec(self) -> Self { let result = self .client - .get_config_spec::() + .get_config_spec::() .await - .map(|res| ConfigAndPreset::Capella(res.data)) + .map(|res| ConfigAndPreset::Deneb(res.data)) .unwrap(); let expected = ConfigAndPreset::from_chain_spec::(&self.chain.spec, None); diff --git a/consensus/types/presets/gnosis/deneb.yaml b/consensus/types/presets/gnosis/deneb.yaml new file mode 100644 index 000000000..b78a95027 --- /dev/null +++ b/consensus/types/presets/gnosis/deneb.yaml @@ -0,0 +1,12 @@ +# Gnosis preset - Deneb +# NOTE: The below are PLACEHOLDER values from Mainnet. +# Gnosis preset for the Deneb fork TBD: https://github.com/gnosischain/configs/tree/main/presets/gnosis + +# Misc +# --------------------------------------------------------------- +# `uint64(4096)` +FIELD_ELEMENTS_PER_BLOB: 4096 +# `uint64(2**12)` (= 4096) +MAX_BLOB_COMMITMENTS_PER_BLOCK: 4096 +# `uint64(6)` +MAX_BLOBS_PER_BLOCK: 6 diff --git a/consensus/types/presets/mainnet/deneb.yaml b/consensus/types/presets/mainnet/deneb.yaml new file mode 100644 index 000000000..23889fd18 --- /dev/null +++ b/consensus/types/presets/mainnet/deneb.yaml @@ -0,0 +1,10 @@ +# Mainnet preset - Deneb + +# Misc +# --------------------------------------------------------------- +# `uint64(4096)` +FIELD_ELEMENTS_PER_BLOB: 4096 +# `uint64(2**12)` (= 4096) +MAX_BLOB_COMMITMENTS_PER_BLOCK: 4096 +# `uint64(6)` +MAX_BLOBS_PER_BLOCK: 6 diff --git a/consensus/types/presets/minimal/deneb.yaml b/consensus/types/presets/minimal/deneb.yaml new file mode 100644 index 000000000..e21d38777 --- /dev/null +++ b/consensus/types/presets/minimal/deneb.yaml @@ -0,0 +1,10 @@ +# Minimal preset - Deneb + +# Misc +# --------------------------------------------------------------- +# [customized] +FIELD_ELEMENTS_PER_BLOB: 4 +# [customized] +MAX_BLOB_COMMITMENTS_PER_BLOCK: 16 +# `uint64(6)` +MAX_BLOBS_PER_BLOCK: 6 diff --git a/consensus/types/src/config_and_preset.rs b/consensus/types/src/config_and_preset.rs index 1b6b8e592..911aa585d 100644 --- a/consensus/types/src/config_and_preset.rs +++ b/consensus/types/src/config_and_preset.rs @@ -1,6 +1,6 @@ use crate::{ consts::altair, AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, ChainSpec, Config, - EthSpec, ForkName, + DenebPreset, EthSpec, ForkName, }; use maplit::hashmap; use serde_derive::{Deserialize, Serialize}; @@ -12,7 +12,7 @@ use superstruct::superstruct; /// /// Mostly useful for the API. #[superstruct( - variants(Bellatrix, Capella), + variants(Capella, Deneb), variant_attributes(derive(Serialize, Deserialize, Debug, PartialEq, Clone)) )] #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] @@ -27,9 +27,11 @@ pub struct ConfigAndPreset { pub altair_preset: AltairPreset, #[serde(flatten)] pub bellatrix_preset: BellatrixPreset, - #[superstruct(only(Capella))] #[serde(flatten)] pub capella_preset: CapellaPreset, + #[superstruct(only(Deneb))] + #[serde(flatten)] + pub deneb_preset: DenebPreset, /// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks. #[serde(flatten)] pub extra_fields: HashMap, @@ -41,14 +43,24 @@ impl ConfigAndPreset { let base_preset = BasePreset::from_chain_spec::(spec); let altair_preset = AltairPreset::from_chain_spec::(spec); let bellatrix_preset = BellatrixPreset::from_chain_spec::(spec); + let capella_preset = CapellaPreset::from_chain_spec::(spec); let extra_fields = get_extra_fields(spec); - if spec.capella_fork_epoch.is_some() + if spec.deneb_fork_epoch.is_some() || fork_name.is_none() - || fork_name == Some(ForkName::Capella) + || fork_name == Some(ForkName::Deneb) { - let capella_preset = CapellaPreset::from_chain_spec::(spec); - + let deneb_preset = DenebPreset::from_chain_spec::(spec); + ConfigAndPreset::Deneb(ConfigAndPresetDeneb { + config, + base_preset, + altair_preset, + bellatrix_preset, + capella_preset, + deneb_preset, + extra_fields, + }) + } else { ConfigAndPreset::Capella(ConfigAndPresetCapella { config, base_preset, @@ -57,14 +69,6 @@ impl ConfigAndPreset { capella_preset, extra_fields, }) - } else { - ConfigAndPreset::Bellatrix(ConfigAndPresetBellatrix { - config, - base_preset, - altair_preset, - bellatrix_preset, - extra_fields, - }) } } } @@ -133,8 +137,8 @@ mod test { .write(false) .open(tmp_file.as_ref()) .expect("error while opening the file"); - let from: ConfigAndPresetCapella = + let from: ConfigAndPresetDeneb = serde_yaml::from_reader(reader).expect("error while deserializing"); - assert_eq!(ConfigAndPreset::Capella(from), yamlconfig); + assert_eq!(ConfigAndPreset::Deneb(from), yamlconfig); } } diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index 2cf756258..cde438e9e 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -260,6 +260,16 @@ pub trait EthSpec: Self::MaxBlobsPerBlock::to_usize() } + /// Returns the `MAX_BLOB_COMMITMENTS_PER_BLOCK` constant for this specification. + fn max_blob_commitments_per_block() -> usize { + Self::MaxBlobCommitmentsPerBlock::to_usize() + } + + /// Returns the `FIELD_ELEMENTS_PER_BLOB` constant for this specification. + fn field_elements_per_blob() -> usize { + Self::FieldElementsPerBlob::to_usize() + } + fn blob_from_bytes(bytes: &[u8]) -> Result<::Blob, kzg::Error> { ::Blob::from_bytes(bytes) } diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index 470e6acc1..9352c0b28 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -127,9 +127,7 @@ pub use crate::blob_sidecar::{ pub use crate::bls_to_execution_change::BlsToExecutionChange; pub use crate::chain_spec::{ChainSpec, Config, Domain}; pub use crate::checkpoint::Checkpoint; -pub use crate::config_and_preset::{ - ConfigAndPreset, ConfigAndPresetBellatrix, ConfigAndPresetCapella, -}; +pub use crate::config_and_preset::{ConfigAndPreset, ConfigAndPresetCapella, ConfigAndPresetDeneb}; pub use crate::contribution_and_proof::ContributionAndProof; pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH}; pub use crate::deposit_data::DepositData; @@ -166,7 +164,7 @@ pub use crate::payload::{ FullPayloadCapella, FullPayloadDeneb, FullPayloadMerge, FullPayloadRef, OwnedExecPayload, }; pub use crate::pending_attestation::PendingAttestation; -pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset, CapellaPreset}; +pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, DenebPreset}; pub use crate::proposer_preparation_data::ProposerPreparationData; pub use crate::proposer_slashing::ProposerSlashing; pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch}; diff --git a/consensus/types/src/preset.rs b/consensus/types/src/preset.rs index e65dd8f60..a1c1e7024 100644 --- a/consensus/types/src/preset.rs +++ b/consensus/types/src/preset.rs @@ -205,6 +205,27 @@ impl CapellaPreset { } } +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[serde(rename_all = "UPPERCASE")] +pub struct DenebPreset { + #[serde(with = "serde_utils::quoted_u64")] + pub max_blobs_per_block: u64, + #[serde(with = "serde_utils::quoted_u64")] + pub max_blob_commitments_per_block: u64, + #[serde(with = "serde_utils::quoted_u64")] + pub field_elements_per_blob: u64, +} + +impl DenebPreset { + pub fn from_chain_spec(_spec: &ChainSpec) -> Self { + Self { + max_blobs_per_block: T::max_blobs_per_block() as u64, + max_blob_commitments_per_block: T::max_blob_commitments_per_block() as u64, + field_elements_per_blob: T::field_elements_per_blob() as u64, + } + } +} + #[cfg(test)] mod test { use super::*; @@ -243,6 +264,9 @@ mod test { let capella: CapellaPreset = preset_from_file(&preset_name, "capella.yaml"); assert_eq!(capella, CapellaPreset::from_chain_spec::(&spec)); + + let deneb: DenebPreset = preset_from_file(&preset_name, "deneb.yaml"); + assert_eq!(deneb, DenebPreset::from_chain_spec::(&spec)); } #[test] diff --git a/validator_client/src/beacon_node_fallback.rs b/validator_client/src/beacon_node_fallback.rs index 531cec08a..3fce61a55 100644 --- a/validator_client/src/beacon_node_fallback.rs +++ b/validator_client/src/beacon_node_fallback.rs @@ -296,6 +296,14 @@ impl CandidateBeaconNode { "endpoint_capella_fork_epoch" => ?beacon_node_spec.capella_fork_epoch, "hint" => UPDATE_REQUIRED_LOG_HINT, ); + } else if beacon_node_spec.deneb_fork_epoch != spec.deneb_fork_epoch { + warn!( + log, + "Beacon node has mismatched Deneb fork epoch"; + "endpoint" => %self.beacon_node, + "endpoint_deneb_fork_epoch" => ?beacon_node_spec.deneb_fork_epoch, + "hint" => UPDATE_REQUIRED_LOG_HINT, + ); } Ok(()) diff --git a/validator_client/src/http_api/test_utils.rs b/validator_client/src/http_api/test_utils.rs index c7558dd58..916c098cd 100644 --- a/validator_client/src/http_api/test_utils.rs +++ b/validator_client/src/http_api/test_utils.rs @@ -249,9 +249,9 @@ impl ApiTester { pub async fn test_get_lighthouse_spec(self) -> Self { let result = self .client - .get_lighthouse_spec::() + .get_lighthouse_spec::() .await - .map(|res| ConfigAndPreset::Bellatrix(res.data)) + .map(|res| ConfigAndPreset::Capella(res.data)) .unwrap(); let expected = ConfigAndPreset::from_chain_spec::(&E::default_spec(), None); diff --git a/validator_client/src/http_api/tests.rs b/validator_client/src/http_api/tests.rs index 3bff44470..ebdee7a1e 100644 --- a/validator_client/src/http_api/tests.rs +++ b/validator_client/src/http_api/tests.rs @@ -205,9 +205,9 @@ impl ApiTester { pub async fn test_get_lighthouse_spec(self) -> Self { let result = self .client - .get_lighthouse_spec::() + .get_lighthouse_spec::() .await - .map(|res| ConfigAndPreset::Capella(res.data)) + .map(|res| ConfigAndPreset::Deneb(res.data)) .unwrap(); let expected = ConfigAndPreset::from_chain_spec::(&E::default_spec(), None);