diff --git a/beacon-api-client/Cargo.toml b/beacon-api-client/Cargo.toml index 39c353d46..6ff323905 100644 --- a/beacon-api-client/Cargo.toml +++ b/beacon-api-client/Cargo.toml @@ -10,7 +10,7 @@ license = "MIT OR Apache-2.0" default = ["cli", "native-tls"] cli = ["clap"] rustls = ["reqwest/rustls-tls"] -native-tls = ["reqwest/default-tls"] +native-tls = ["reqwest/default-tls"] [dependencies] tokio = { version = "1.0", features = ["full"] } diff --git a/beacon-api-client/src/types.rs b/beacon-api-client/src/types.rs index 965f3c8b7..2a3a1f20f 100644 --- a/beacon-api-client/src/types.rs +++ b/beacon-api-client/src/types.rs @@ -11,7 +11,7 @@ use ethereum_consensus::{ Fork, }; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fmt, marker::PhantomData, str::FromStr}; +use std::{collections::HashMap, fmt, str::FromStr}; #[derive(Serialize, Deserialize)] pub struct VersionData { @@ -465,125 +465,16 @@ pub struct Value { pub meta: HashMap, } -#[derive(Debug, Serialize)] -pub struct VersionedValue { +#[derive(Debug, Serialize, Deserialize)] +#[serde(bound = "T: serde::Serialize + serde::de::DeserializeOwned")] +pub struct VersionedValue { pub version: Fork, pub data: T, + #[serde(flatten)] + #[serde(skip_serializing_if = "HashMap::is_empty")] pub meta: HashMap, } -impl<'de, T: serde::Serialize + serde::de::DeserializeOwned> serde::Deserialize<'de> - for VersionedValue -{ - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - #[derive(Debug)] - enum Field<'de> { - Version, - Data, - Meta(&'de str), - } - - impl<'de> serde::Deserialize<'de> for Field<'de> { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct FieldVisitor; - - impl<'de> serde::de::Visitor<'de> for FieldVisitor { - type Value = Field<'de>; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("some field name") - } - - fn visit_borrowed_str(self, v: &'de str) -> Result - where - E: serde::de::Error, - { - match v { - "version" => Ok(Field::Version), - "data" => Ok(Field::Data), - s => Ok(Field::Meta(s)), - } - } - } - deserializer.deserialize_identifier(FieldVisitor) - } - } - - struct Visitor(PhantomData); - - impl<'de, T: serde::Serialize + serde::de::DeserializeOwned> serde::de::Visitor<'de> - for Visitor - { - type Value = VersionedValue; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("struct VersionedValue") - } - - fn visit_map(self, mut map: A) -> Result - where - A: serde::de::MapAccess<'de>, - { - let mut version = None; - let mut version_str = None; - let mut data: Option = None; - let mut meta = HashMap::default(); - while let Some(key) = map.next_key()? { - match key { - Field::Version => { - if version.is_some() { - return Err(serde::de::Error::duplicate_field("version")) - } - let version_value: serde_json::Value = map.next_value()?; - let fork: Fork = serde_json::from_value(version_value.clone()) - .map_err(serde::de::Error::custom)?; - version = Some(fork); - match version_value { - serde_json::Value::String(inner) => { - version_str = Some(inner); - } - other => { - return Err(serde::de::Error::custom(format!( - "expected JSON string, but found value {other}" - ))) - } - }; - } - Field::Data => { - if data.is_some() { - return Err(serde::de::Error::duplicate_field("data")) - } - data = Some(map.next_value()?); - } - Field::Meta(name) => { - let next_value: serde_json::Value = map.next_value()?; - meta.insert(name.to_string(), next_value); - } - } - } - let version = version.ok_or_else(|| serde::de::Error::missing_field("version"))?; - let data = data.ok_or_else(|| serde::de::Error::missing_field("data"))?; - let data_with_version = serde_json::json!({ - "version": version_str, - "data": data, - }); - let data: T = - serde_json::from_value(data_with_version).map_err(serde::de::Error::custom)?; - Ok(VersionedValue { version, data, meta }) - } - } - - const FIELDS: &[&str] = &["version", "data", "meta"]; - deserializer.deserialize_struct("VersionedValue", FIELDS, Visitor(PhantomData)) - } -} - #[derive(Serialize, Deserialize, Debug)] #[serde(bound = "T: Serialize + serde::de::DeserializeOwned")] #[serde(untagged)] diff --git a/ethereum-consensus/Cargo.toml b/ethereum-consensus/Cargo.toml index 5987fccb2..7eb29d0c5 100644 --- a/ethereum-consensus/Cargo.toml +++ b/ethereum-consensus/Cargo.toml @@ -28,7 +28,7 @@ ec = [ ] [dependencies] -ssz_rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "51f3932d1578a62f856c19175482056912de5f3e" } +ssz_rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "c00a4659b9d1980d410c487a88e983cf2506c928" } blst = "0.3.11" rand = "0.8.4" thiserror = "1.0.30" diff --git a/ethereum-consensus/examples/serde.rs b/ethereum-consensus/examples/serde.rs index b34ef2ac3..d76b7defb 100644 --- a/ethereum-consensus/examples/serde.rs +++ b/ethereum-consensus/examples/serde.rs @@ -7,6 +7,7 @@ use ethereum_consensus::{ Attestation, AttesterSlashing, BeaconState, Deposit, PendingAttestation, ProposerSlashing, SignedBeaconBlock, SignedVoluntaryExit, }, + types::mainnet as types, }; fn main() { @@ -37,4 +38,10 @@ fn main() { let header_json = serde_json::to_string(&header).unwrap(); println!("{}", &header_json); let _: ExecutionPayloadHeader = serde_json::from_str(&header_json).unwrap(); + + let header = types::ExecutionPayloadHeader::Bellatrix(header); + let header_json = serde_json::to_string_pretty(&header).unwrap(); + println!("{header_json}"); + let recovered_header = serde_json::from_str(&header_json).unwrap(); + assert_eq!(header, recovered_header); } diff --git a/ethereum-consensus/src/altair/spec/mod.rs b/ethereum-consensus/src/altair/spec/mod.rs index f9fefe661..c1c821bb2 100644 --- a/ethereum-consensus/src/altair/spec/mod.rs +++ b/ethereum-consensus/src/altair/spec/mod.rs @@ -58,7 +58,7 @@ pub use crate::{ state_transition::{Context, Result, Validation}, }; use crate::{ - crypto::{fast_aggregate_verify, hash, verify_signature}, + crypto::{fast_aggregate_verify, hash}, ssz::prelude::*, }; use std::{cmp, collections::HashSet}; diff --git a/ethereum-consensus/src/bellatrix/spec/mod.rs b/ethereum-consensus/src/bellatrix/spec/mod.rs index 9f86b5cc0..f72b0fc6f 100644 --- a/ethereum-consensus/src/bellatrix/spec/mod.rs +++ b/ethereum-consensus/src/bellatrix/spec/mod.rs @@ -59,10 +59,7 @@ pub use crate::{ state_transition::{Context, Result, Validation}, }; use crate::{ - crypto::{ - eth_aggregate_public_keys, eth_fast_aggregate_verify, fast_aggregate_verify, hash, - verify_signature, - }, + crypto::{eth_aggregate_public_keys, eth_fast_aggregate_verify, fast_aggregate_verify, hash}, ssz::prelude::*, }; use integer_sqrt::IntegerSquareRoot; diff --git a/ethereum-consensus/src/capella/spec/mod.rs b/ethereum-consensus/src/capella/spec/mod.rs index 4a9efe059..c15c91ca5 100644 --- a/ethereum-consensus/src/capella/spec/mod.rs +++ b/ethereum-consensus/src/capella/spec/mod.rs @@ -63,10 +63,7 @@ pub use crate::{ state_transition::{Context, Result, Validation}, }; use crate::{ - crypto::{ - eth_aggregate_public_keys, eth_fast_aggregate_verify, fast_aggregate_verify, hash, - verify_signature, - }, + crypto::{eth_aggregate_public_keys, eth_fast_aggregate_verify, fast_aggregate_verify, hash}, ssz::prelude::*, }; use integer_sqrt::IntegerSquareRoot; diff --git a/ethereum-consensus/src/deneb/spec/mod.rs b/ethereum-consensus/src/deneb/spec/mod.rs index 8fe0f9f76..4fa2b019a 100644 --- a/ethereum-consensus/src/deneb/spec/mod.rs +++ b/ethereum-consensus/src/deneb/spec/mod.rs @@ -69,10 +69,7 @@ pub use crate::{ state_transition::{Context, Result, Validation}, }; use crate::{ - crypto::{ - eth_aggregate_public_keys, eth_fast_aggregate_verify, fast_aggregate_verify, hash, - verify_signature, - }, + crypto::{eth_aggregate_public_keys, eth_fast_aggregate_verify, fast_aggregate_verify, hash}, ssz::prelude::*, }; use integer_sqrt::IntegerSquareRoot; diff --git a/ethereum-consensus/src/signing.rs b/ethereum-consensus/src/signing.rs index 17476a2cd..f9bb0285a 100644 --- a/ethereum-consensus/src/signing.rs +++ b/ethereum-consensus/src/signing.rs @@ -1,5 +1,5 @@ use crate::{ - crypto::{verify_signature, SecretKey}, + crypto::{self, SecretKey}, primitives::{BlsPublicKey, BlsSignature, Domain, Root}, ssz::prelude::*, Error, @@ -11,7 +11,7 @@ pub struct SigningData { pub domain: Domain, } -pub fn compute_signing_root( +pub fn compute_signing_root( ssz_object: &mut T, domain: Domain, ) -> Result { @@ -21,7 +21,7 @@ pub fn compute_signing_root( s.hash_tree_root().map_err(Error::Merkleization) } -pub fn sign_with_domain( +pub fn sign_with_domain( data: &mut T, signing_key: &SecretKey, domain: Domain, @@ -30,12 +30,25 @@ pub fn sign_with_domain( Ok(signing_key.sign(signing_root.as_ref())) } -pub fn verify_signed_data( +pub fn verify_signed_data( data: &mut T, signature: &BlsSignature, public_key: &BlsPublicKey, domain: Domain, ) -> Result<(), Error> { let signing_root = compute_signing_root(data, domain)?; - verify_signature(public_key, signing_root.as_ref(), signature).map_err(Into::into) + crypto::verify_signature(public_key, signing_root.as_ref(), signature).map_err(Into::into) +} + +// This function wraps the inner implementation defined in `crate::crypto` but presents a bit nicer +// interface to users external to this crate. +// NOTE: `verify_signed_data` serves a similar purpose but asking for a `&mut T` there +// means that any message containing its public key (a common pattern in ethereum types) +// needs to pass in a (ref to a) `clone` of the public key inside the message type. +pub fn verify_signature( + public_key: &BlsPublicKey, + signing_root: &[u8], + signature: &BlsSignature, +) -> Result<(), Error> { + crypto::verify_signature(public_key, signing_root, signature).map_err(Into::into) } diff --git a/ethereum-consensus/src/types/beacon_block.rs b/ethereum-consensus/src/types/beacon_block.rs index 30ab3bd8c..e38fe06ff 100644 --- a/ethereum-consensus/src/types/beacon_block.rs +++ b/ethereum-consensus/src/types/beacon_block.rs @@ -8,10 +8,10 @@ use crate::{ primitives::{Root, Slot, ValidatorIndex}, ssz::prelude::*, types::beacon_block_body::{BeaconBlockBodyRef, BeaconBlockBodyRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum BeaconBlock< const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, @@ -345,6 +345,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn slot(&self) -> &Slot { match self { Self::Phase0(inner) => &inner.slot, @@ -471,6 +480,7 @@ impl< } } impl< + 'de, const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, const MAX_ATTESTER_SLASHINGS: usize, @@ -485,7 +495,7 @@ impl< const MAX_WITHDRAWALS_PER_PAYLOAD: usize, const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, - > serde::Serialize + > serde::Deserialize<'de> for BeaconBlock< MAX_PROPOSER_SLASHINGS, MAX_VALIDATORS_PER_COMMITTEE, @@ -503,17 +513,27 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Phase0(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Altair(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Altair(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Phase0(inner)) + } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -747,6 +767,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn slot(&self) -> &Slot { match self { Self::Phase0(inner) => &inner.slot, @@ -1142,7 +1171,8 @@ impl< Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum BeaconBlockRefMut< 'a, const MAX_PROPOSER_SLASHINGS: usize, @@ -1267,6 +1297,23 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { + pub fn phase0( + &self, + ) -> Option< + &phase0::BeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + >, + > { + match self { + Self::Phase0(inner) => Some(inner), + _ => None, + } + } pub fn phase0_mut( &mut self, ) -> Option< @@ -1284,6 +1331,24 @@ impl< _ => None, } } + pub fn altair( + &self, + ) -> Option< + &altair::BeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + >, + > { + match self { + Self::Altair(inner) => Some(inner), + _ => None, + } + } pub fn altair_mut( &mut self, ) -> Option< @@ -1302,6 +1367,28 @@ impl< _ => None, } } + pub fn bellatrix( + &self, + ) -> Option< + &bellatrix::BeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + >, + > { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option< @@ -1324,6 +1411,30 @@ impl< _ => None, } } + pub fn capella( + &self, + ) -> Option< + &capella::BeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + >, + > { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option< @@ -1348,6 +1459,31 @@ impl< _ => None, } } + pub fn deneb( + &self, + ) -> Option< + &deneb::BeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + >, + > { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option< @@ -1373,6 +1509,24 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn slot(&self) -> &Slot { + match self { + Self::Phase0(inner) => &inner.slot, + Self::Altair(inner) => &inner.slot, + Self::Bellatrix(inner) => &inner.slot, + Self::Capella(inner) => &inner.slot, + Self::Deneb(inner) => &inner.slot, + } + } pub fn slot_mut(&mut self) -> &mut Slot { match self { Self::Phase0(inner) => &mut inner.slot, @@ -1382,6 +1536,15 @@ impl< Self::Deneb(inner) => &mut inner.slot, } } + pub fn proposer_index(&self) -> &ValidatorIndex { + match self { + Self::Phase0(inner) => &inner.proposer_index, + Self::Altair(inner) => &inner.proposer_index, + Self::Bellatrix(inner) => &inner.proposer_index, + Self::Capella(inner) => &inner.proposer_index, + Self::Deneb(inner) => &inner.proposer_index, + } + } pub fn proposer_index_mut(&mut self) -> &mut ValidatorIndex { match self { Self::Phase0(inner) => &mut inner.proposer_index, @@ -1391,6 +1554,15 @@ impl< Self::Deneb(inner) => &mut inner.proposer_index, } } + pub fn parent_root(&self) -> &Root { + match self { + Self::Phase0(inner) => &inner.parent_root, + Self::Altair(inner) => &inner.parent_root, + Self::Bellatrix(inner) => &inner.parent_root, + Self::Capella(inner) => &inner.parent_root, + Self::Deneb(inner) => &inner.parent_root, + } + } pub fn parent_root_mut(&mut self) -> &mut Root { match self { Self::Phase0(inner) => &mut inner.parent_root, @@ -1400,6 +1572,15 @@ impl< Self::Deneb(inner) => &mut inner.parent_root, } } + pub fn state_root(&self) -> &Root { + match self { + Self::Phase0(inner) => &inner.state_root, + Self::Altair(inner) => &inner.state_root, + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, + } + } pub fn state_root_mut(&mut self) -> &mut Root { match self { Self::Phase0(inner) => &mut inner.state_root, @@ -1409,6 +1590,32 @@ impl< Self::Deneb(inner) => &mut inner.state_root, } } + pub fn body( + &self, + ) -> BeaconBlockBodyRef< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + > { + match self { + Self::Phase0(inner) => From::from(&inner.body), + Self::Altair(inner) => From::from(&inner.body), + Self::Bellatrix(inner) => From::from(&inner.body), + Self::Capella(inner) => From::from(&inner.body), + Self::Deneb(inner) => From::from(&inner.body), + } + } pub fn body_mut( &mut self, ) -> BeaconBlockBodyRefMut< diff --git a/ethereum-consensus/src/types/beacon_block_body.rs b/ethereum-consensus/src/types/beacon_block_body.rs index d57113383..186e4afb0 100644 --- a/ethereum-consensus/src/types/beacon_block_body.rs +++ b/ethereum-consensus/src/types/beacon_block_body.rs @@ -11,10 +11,10 @@ use crate::{ primitives::{BlsSignature, Bytes32}, ssz::prelude::*, types::execution_payload::{ExecutionPayloadRef, ExecutionPayloadRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum BeaconBlockBody< const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, @@ -348,6 +348,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn randao_reveal(&self) -> &BlsSignature { match self { Self::Phase0(inner) => &inner.randao_reveal, @@ -604,6 +613,7 @@ impl< } } impl< + 'de, const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, const MAX_ATTESTER_SLASHINGS: usize, @@ -618,7 +628,7 @@ impl< const MAX_WITHDRAWALS_PER_PAYLOAD: usize, const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, - > serde::Serialize + > serde::Deserialize<'de> for BeaconBlockBody< MAX_PROPOSER_SLASHINGS, MAX_VALIDATORS_PER_COMMITTEE, @@ -636,17 +646,27 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Phase0(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Altair(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Altair(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Phase0(inner)) } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -880,6 +900,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn randao_reveal(&self) -> &BlsSignature { match self { Self::Phase0(inner) => &inner.randao_reveal, @@ -1339,7 +1368,8 @@ impl< Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum BeaconBlockBodyRefMut< 'a, const MAX_PROPOSER_SLASHINGS: usize, @@ -1464,6 +1494,23 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { + pub fn phase0( + &self, + ) -> Option< + &phase0::BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + >, + > { + match self { + Self::Phase0(inner) => Some(inner), + _ => None, + } + } pub fn phase0_mut( &mut self, ) -> Option< @@ -1481,6 +1528,24 @@ impl< _ => None, } } + pub fn altair( + &self, + ) -> Option< + &altair::BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + >, + > { + match self { + Self::Altair(inner) => Some(inner), + _ => None, + } + } pub fn altair_mut( &mut self, ) -> Option< @@ -1499,6 +1564,28 @@ impl< _ => None, } } + pub fn bellatrix( + &self, + ) -> Option< + &bellatrix::BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + >, + > { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option< @@ -1521,6 +1608,30 @@ impl< _ => None, } } + pub fn capella( + &self, + ) -> Option< + &capella::BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + >, + > { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option< @@ -1545,6 +1656,31 @@ impl< _ => None, } } + pub fn deneb( + &self, + ) -> Option< + &deneb::BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + >, + > { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option< @@ -1570,6 +1706,24 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn randao_reveal(&self) -> &BlsSignature { + match self { + Self::Phase0(inner) => &inner.randao_reveal, + Self::Altair(inner) => &inner.randao_reveal, + Self::Bellatrix(inner) => &inner.randao_reveal, + Self::Capella(inner) => &inner.randao_reveal, + Self::Deneb(inner) => &inner.randao_reveal, + } + } pub fn randao_reveal_mut(&mut self) -> &mut BlsSignature { match self { Self::Phase0(inner) => &mut inner.randao_reveal, @@ -1579,6 +1733,15 @@ impl< Self::Deneb(inner) => &mut inner.randao_reveal, } } + pub fn eth1_data(&self) -> &Eth1Data { + match self { + Self::Phase0(inner) => &inner.eth1_data, + Self::Altair(inner) => &inner.eth1_data, + Self::Bellatrix(inner) => &inner.eth1_data, + Self::Capella(inner) => &inner.eth1_data, + Self::Deneb(inner) => &inner.eth1_data, + } + } pub fn eth1_data_mut(&mut self) -> &mut Eth1Data { match self { Self::Phase0(inner) => &mut inner.eth1_data, @@ -1588,6 +1751,15 @@ impl< Self::Deneb(inner) => &mut inner.eth1_data, } } + pub fn graffiti(&self) -> &Bytes32 { + match self { + Self::Phase0(inner) => &inner.graffiti, + Self::Altair(inner) => &inner.graffiti, + Self::Bellatrix(inner) => &inner.graffiti, + Self::Capella(inner) => &inner.graffiti, + Self::Deneb(inner) => &inner.graffiti, + } + } pub fn graffiti_mut(&mut self) -> &mut Bytes32 { match self { Self::Phase0(inner) => &mut inner.graffiti, @@ -1597,6 +1769,15 @@ impl< Self::Deneb(inner) => &mut inner.graffiti, } } + pub fn proposer_slashings(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.proposer_slashings, + Self::Altair(inner) => &inner.proposer_slashings, + Self::Bellatrix(inner) => &inner.proposer_slashings, + Self::Capella(inner) => &inner.proposer_slashings, + Self::Deneb(inner) => &inner.proposer_slashings, + } + } pub fn proposer_slashings_mut( &mut self, ) -> &mut List { @@ -1608,6 +1789,17 @@ impl< Self::Deneb(inner) => &mut inner.proposer_slashings, } } + pub fn attester_slashings( + &self, + ) -> &List, MAX_ATTESTER_SLASHINGS> { + match self { + Self::Phase0(inner) => &inner.attester_slashings, + Self::Altair(inner) => &inner.attester_slashings, + Self::Bellatrix(inner) => &inner.attester_slashings, + Self::Capella(inner) => &inner.attester_slashings, + Self::Deneb(inner) => &inner.attester_slashings, + } + } pub fn attester_slashings_mut( &mut self, ) -> &mut List, MAX_ATTESTER_SLASHINGS> { @@ -1619,6 +1811,17 @@ impl< Self::Deneb(inner) => &mut inner.attester_slashings, } } + pub fn attestations( + &self, + ) -> &List, MAX_ATTESTATIONS> { + match self { + Self::Phase0(inner) => &inner.attestations, + Self::Altair(inner) => &inner.attestations, + Self::Bellatrix(inner) => &inner.attestations, + Self::Capella(inner) => &inner.attestations, + Self::Deneb(inner) => &inner.attestations, + } + } pub fn attestations_mut( &mut self, ) -> &mut List, MAX_ATTESTATIONS> { @@ -1630,6 +1833,15 @@ impl< Self::Deneb(inner) => &mut inner.attestations, } } + pub fn deposits(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.deposits, + Self::Altair(inner) => &inner.deposits, + Self::Bellatrix(inner) => &inner.deposits, + Self::Capella(inner) => &inner.deposits, + Self::Deneb(inner) => &inner.deposits, + } + } pub fn deposits_mut(&mut self) -> &mut List { match self { Self::Phase0(inner) => &mut inner.deposits, @@ -1639,6 +1851,15 @@ impl< Self::Deneb(inner) => &mut inner.deposits, } } + pub fn voluntary_exits(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.voluntary_exits, + Self::Altair(inner) => &inner.voluntary_exits, + Self::Bellatrix(inner) => &inner.voluntary_exits, + Self::Capella(inner) => &inner.voluntary_exits, + Self::Deneb(inner) => &inner.voluntary_exits, + } + } pub fn voluntary_exits_mut(&mut self) -> &mut List { match self { Self::Phase0(inner) => &mut inner.voluntary_exits, @@ -1648,6 +1869,15 @@ impl< Self::Deneb(inner) => &mut inner.voluntary_exits, } } + pub fn sync_aggregate(&self) -> Option<&SyncAggregate> { + match self { + Self::Phase0(_) => None, + Self::Altair(inner) => Some(&inner.sync_aggregate), + Self::Bellatrix(inner) => Some(&inner.sync_aggregate), + Self::Capella(inner) => Some(&inner.sync_aggregate), + Self::Deneb(inner) => Some(&inner.sync_aggregate), + } + } pub fn sync_aggregate_mut(&mut self) -> Option<&mut SyncAggregate> { match self { Self::Phase0(_) => None, @@ -1657,6 +1887,25 @@ impl< Self::Deneb(inner) => Some(&mut inner.sync_aggregate), } } + pub fn execution_payload( + &self, + ) -> Option< + ExecutionPayloadRef< + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + >, + > { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(inner) => Some(From::from(&inner.execution_payload)), + Self::Capella(inner) => Some(From::from(&inner.execution_payload)), + Self::Deneb(inner) => Some(From::from(&inner.execution_payload)), + } + } pub fn execution_payload_mut( &mut self, ) -> Option< @@ -1676,6 +1925,17 @@ impl< Self::Deneb(inner) => Some(From::from(&mut inner.execution_payload)), } } + pub fn bls_to_execution_changes( + &self, + ) -> Option<&List> { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.bls_to_execution_changes), + Self::Deneb(inner) => Some(&inner.bls_to_execution_changes), + } + } pub fn bls_to_execution_changes_mut( &mut self, ) -> Option<&mut List> { @@ -1687,6 +1947,17 @@ impl< Self::Deneb(inner) => Some(&mut inner.bls_to_execution_changes), } } + pub fn blob_kzg_commitments( + &self, + ) -> Option<&List> { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(inner) => Some(&inner.blob_kzg_commitments), + } + } pub fn blob_kzg_commitments_mut( &mut self, ) -> Option<&mut List> { diff --git a/ethereum-consensus/src/types/beacon_state.rs b/ethereum-consensus/src/types/beacon_state.rs index 34275bd77..b4c94cba4 100644 --- a/ethereum-consensus/src/types/beacon_state.rs +++ b/ethereum-consensus/src/types/beacon_state.rs @@ -14,10 +14,10 @@ use crate::{ primitives::{Bytes32, Gwei, ParticipationFlags, Root, Slot, ValidatorIndex, WithdrawalIndex}, ssz::prelude::*, types::execution_payload_header::{ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum BeaconState< const SLOTS_PER_HISTORICAL_ROOT: usize, const HISTORICAL_ROOTS_LIMIT: usize, @@ -327,6 +327,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn genesis_time(&self) -> &u64 { match self { Self::Phase0(inner) => &inner.genesis_time, @@ -899,6 +908,7 @@ impl< } } impl< + 'de, const SLOTS_PER_HISTORICAL_ROOT: usize, const HISTORICAL_ROOTS_LIMIT: usize, const ETH1_DATA_VOTES_BOUND: usize, @@ -910,7 +920,7 @@ impl< const SYNC_COMMITTEE_SIZE: usize, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize, - > serde::Serialize + > serde::Deserialize<'de> for BeaconState< SLOTS_PER_HISTORICAL_ROOT, HISTORICAL_ROOTS_LIMIT, @@ -925,17 +935,27 @@ impl< MAX_EXTRA_DATA_BYTES, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Phase0(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Altair(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Altair(inner)) } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Phase0(inner)) + } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -1150,6 +1170,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn genesis_time(&self) -> &u64 { match self { Self::Phase0(inner) => &inner.genesis_time, @@ -1725,7 +1754,8 @@ impl< Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum BeaconStateRefMut< 'a, const SLOTS_PER_HISTORICAL_ROOT: usize, @@ -1836,6 +1866,25 @@ impl< MAX_EXTRA_DATA_BYTES, > { + pub fn phase0( + &self, + ) -> Option< + &phase0::BeaconState< + SLOTS_PER_HISTORICAL_ROOT, + HISTORICAL_ROOTS_LIMIT, + ETH1_DATA_VOTES_BOUND, + VALIDATOR_REGISTRY_LIMIT, + EPOCHS_PER_HISTORICAL_VECTOR, + EPOCHS_PER_SLASHINGS_VECTOR, + MAX_VALIDATORS_PER_COMMITTEE, + PENDING_ATTESTATIONS_BOUND, + >, + > { + match self { + Self::Phase0(inner) => Some(inner), + _ => None, + } + } pub fn phase0_mut( &mut self, ) -> Option< @@ -1855,6 +1904,25 @@ impl< _ => None, } } + pub fn altair( + &self, + ) -> Option< + &altair::BeaconState< + SLOTS_PER_HISTORICAL_ROOT, + HISTORICAL_ROOTS_LIMIT, + ETH1_DATA_VOTES_BOUND, + VALIDATOR_REGISTRY_LIMIT, + EPOCHS_PER_HISTORICAL_VECTOR, + EPOCHS_PER_SLASHINGS_VECTOR, + MAX_VALIDATORS_PER_COMMITTEE, + SYNC_COMMITTEE_SIZE, + >, + > { + match self { + Self::Altair(inner) => Some(inner), + _ => None, + } + } pub fn altair_mut( &mut self, ) -> Option< @@ -1874,6 +1942,27 @@ impl< _ => None, } } + pub fn bellatrix( + &self, + ) -> Option< + &bellatrix::BeaconState< + SLOTS_PER_HISTORICAL_ROOT, + HISTORICAL_ROOTS_LIMIT, + ETH1_DATA_VOTES_BOUND, + VALIDATOR_REGISTRY_LIMIT, + EPOCHS_PER_HISTORICAL_VECTOR, + EPOCHS_PER_SLASHINGS_VECTOR, + MAX_VALIDATORS_PER_COMMITTEE, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >, + > { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option< @@ -1895,6 +1984,27 @@ impl< _ => None, } } + pub fn capella( + &self, + ) -> Option< + &capella::BeaconState< + SLOTS_PER_HISTORICAL_ROOT, + HISTORICAL_ROOTS_LIMIT, + ETH1_DATA_VOTES_BOUND, + VALIDATOR_REGISTRY_LIMIT, + EPOCHS_PER_HISTORICAL_VECTOR, + EPOCHS_PER_SLASHINGS_VECTOR, + MAX_VALIDATORS_PER_COMMITTEE, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >, + > { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option< @@ -1916,6 +2026,27 @@ impl< _ => None, } } + pub fn deneb( + &self, + ) -> Option< + &deneb::BeaconState< + SLOTS_PER_HISTORICAL_ROOT, + HISTORICAL_ROOTS_LIMIT, + ETH1_DATA_VOTES_BOUND, + VALIDATOR_REGISTRY_LIMIT, + EPOCHS_PER_HISTORICAL_VECTOR, + EPOCHS_PER_SLASHINGS_VECTOR, + MAX_VALIDATORS_PER_COMMITTEE, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >, + > { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option< @@ -1937,6 +2068,24 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn genesis_time(&self) -> &u64 { + match self { + Self::Phase0(inner) => &inner.genesis_time, + Self::Altair(inner) => &inner.genesis_time, + Self::Bellatrix(inner) => &inner.genesis_time, + Self::Capella(inner) => &inner.genesis_time, + Self::Deneb(inner) => &inner.genesis_time, + } + } pub fn genesis_time_mut(&mut self) -> &mut u64 { match self { Self::Phase0(inner) => &mut inner.genesis_time, @@ -1946,6 +2095,15 @@ impl< Self::Deneb(inner) => &mut inner.genesis_time, } } + pub fn genesis_validators_root(&self) -> &Root { + match self { + Self::Phase0(inner) => &inner.genesis_validators_root, + Self::Altair(inner) => &inner.genesis_validators_root, + Self::Bellatrix(inner) => &inner.genesis_validators_root, + Self::Capella(inner) => &inner.genesis_validators_root, + Self::Deneb(inner) => &inner.genesis_validators_root, + } + } pub fn genesis_validators_root_mut(&mut self) -> &mut Root { match self { Self::Phase0(inner) => &mut inner.genesis_validators_root, @@ -1955,6 +2113,15 @@ impl< Self::Deneb(inner) => &mut inner.genesis_validators_root, } } + pub fn slot(&self) -> &Slot { + match self { + Self::Phase0(inner) => &inner.slot, + Self::Altair(inner) => &inner.slot, + Self::Bellatrix(inner) => &inner.slot, + Self::Capella(inner) => &inner.slot, + Self::Deneb(inner) => &inner.slot, + } + } pub fn slot_mut(&mut self) -> &mut Slot { match self { Self::Phase0(inner) => &mut inner.slot, @@ -1964,6 +2131,15 @@ impl< Self::Deneb(inner) => &mut inner.slot, } } + pub fn fork(&self) -> &Fork { + match self { + Self::Phase0(inner) => &inner.fork, + Self::Altair(inner) => &inner.fork, + Self::Bellatrix(inner) => &inner.fork, + Self::Capella(inner) => &inner.fork, + Self::Deneb(inner) => &inner.fork, + } + } pub fn fork_mut(&mut self) -> &mut Fork { match self { Self::Phase0(inner) => &mut inner.fork, @@ -1973,6 +2149,15 @@ impl< Self::Deneb(inner) => &mut inner.fork, } } + pub fn latest_block_header(&self) -> &BeaconBlockHeader { + match self { + Self::Phase0(inner) => &inner.latest_block_header, + Self::Altair(inner) => &inner.latest_block_header, + Self::Bellatrix(inner) => &inner.latest_block_header, + Self::Capella(inner) => &inner.latest_block_header, + Self::Deneb(inner) => &inner.latest_block_header, + } + } pub fn latest_block_header_mut(&mut self) -> &mut BeaconBlockHeader { match self { Self::Phase0(inner) => &mut inner.latest_block_header, @@ -1982,6 +2167,15 @@ impl< Self::Deneb(inner) => &mut inner.latest_block_header, } } + pub fn block_roots(&self) -> &Vector { + match self { + Self::Phase0(inner) => &inner.block_roots, + Self::Altair(inner) => &inner.block_roots, + Self::Bellatrix(inner) => &inner.block_roots, + Self::Capella(inner) => &inner.block_roots, + Self::Deneb(inner) => &inner.block_roots, + } + } pub fn block_roots_mut(&mut self) -> &mut Vector { match self { Self::Phase0(inner) => &mut inner.block_roots, @@ -1991,6 +2185,15 @@ impl< Self::Deneb(inner) => &mut inner.block_roots, } } + pub fn state_roots(&self) -> &Vector { + match self { + Self::Phase0(inner) => &inner.state_roots, + Self::Altair(inner) => &inner.state_roots, + Self::Bellatrix(inner) => &inner.state_roots, + Self::Capella(inner) => &inner.state_roots, + Self::Deneb(inner) => &inner.state_roots, + } + } pub fn state_roots_mut(&mut self) -> &mut Vector { match self { Self::Phase0(inner) => &mut inner.state_roots, @@ -2000,6 +2203,15 @@ impl< Self::Deneb(inner) => &mut inner.state_roots, } } + pub fn historical_roots(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.historical_roots, + Self::Altair(inner) => &inner.historical_roots, + Self::Bellatrix(inner) => &inner.historical_roots, + Self::Capella(inner) => &inner.historical_roots, + Self::Deneb(inner) => &inner.historical_roots, + } + } pub fn historical_roots_mut(&mut self) -> &mut List { match self { Self::Phase0(inner) => &mut inner.historical_roots, @@ -2009,6 +2221,15 @@ impl< Self::Deneb(inner) => &mut inner.historical_roots, } } + pub fn eth1_data(&self) -> &Eth1Data { + match self { + Self::Phase0(inner) => &inner.eth1_data, + Self::Altair(inner) => &inner.eth1_data, + Self::Bellatrix(inner) => &inner.eth1_data, + Self::Capella(inner) => &inner.eth1_data, + Self::Deneb(inner) => &inner.eth1_data, + } + } pub fn eth1_data_mut(&mut self) -> &mut Eth1Data { match self { Self::Phase0(inner) => &mut inner.eth1_data, @@ -2018,6 +2239,15 @@ impl< Self::Deneb(inner) => &mut inner.eth1_data, } } + pub fn eth1_data_votes(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.eth1_data_votes, + Self::Altair(inner) => &inner.eth1_data_votes, + Self::Bellatrix(inner) => &inner.eth1_data_votes, + Self::Capella(inner) => &inner.eth1_data_votes, + Self::Deneb(inner) => &inner.eth1_data_votes, + } + } pub fn eth1_data_votes_mut(&mut self) -> &mut List { match self { Self::Phase0(inner) => &mut inner.eth1_data_votes, @@ -2027,6 +2257,15 @@ impl< Self::Deneb(inner) => &mut inner.eth1_data_votes, } } + pub fn eth1_deposit_index(&self) -> &u64 { + match self { + Self::Phase0(inner) => &inner.eth1_deposit_index, + Self::Altair(inner) => &inner.eth1_deposit_index, + Self::Bellatrix(inner) => &inner.eth1_deposit_index, + Self::Capella(inner) => &inner.eth1_deposit_index, + Self::Deneb(inner) => &inner.eth1_deposit_index, + } + } pub fn eth1_deposit_index_mut(&mut self) -> &mut u64 { match self { Self::Phase0(inner) => &mut inner.eth1_deposit_index, @@ -2036,6 +2275,15 @@ impl< Self::Deneb(inner) => &mut inner.eth1_deposit_index, } } + pub fn validators(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.validators, + Self::Altair(inner) => &inner.validators, + Self::Bellatrix(inner) => &inner.validators, + Self::Capella(inner) => &inner.validators, + Self::Deneb(inner) => &inner.validators, + } + } pub fn validators_mut(&mut self) -> &mut List { match self { Self::Phase0(inner) => &mut inner.validators, @@ -2045,6 +2293,15 @@ impl< Self::Deneb(inner) => &mut inner.validators, } } + pub fn balances(&self) -> &List { + match self { + Self::Phase0(inner) => &inner.balances, + Self::Altair(inner) => &inner.balances, + Self::Bellatrix(inner) => &inner.balances, + Self::Capella(inner) => &inner.balances, + Self::Deneb(inner) => &inner.balances, + } + } pub fn balances_mut(&mut self) -> &mut List { match self { Self::Phase0(inner) => &mut inner.balances, @@ -2054,6 +2311,15 @@ impl< Self::Deneb(inner) => &mut inner.balances, } } + pub fn randao_mixes(&self) -> &Vector { + match self { + Self::Phase0(inner) => &inner.randao_mixes, + Self::Altair(inner) => &inner.randao_mixes, + Self::Bellatrix(inner) => &inner.randao_mixes, + Self::Capella(inner) => &inner.randao_mixes, + Self::Deneb(inner) => &inner.randao_mixes, + } + } pub fn randao_mixes_mut(&mut self) -> &mut Vector { match self { Self::Phase0(inner) => &mut inner.randao_mixes, @@ -2063,6 +2329,15 @@ impl< Self::Deneb(inner) => &mut inner.randao_mixes, } } + pub fn slashings(&self) -> &Vector { + match self { + Self::Phase0(inner) => &inner.slashings, + Self::Altair(inner) => &inner.slashings, + Self::Bellatrix(inner) => &inner.slashings, + Self::Capella(inner) => &inner.slashings, + Self::Deneb(inner) => &inner.slashings, + } + } pub fn slashings_mut(&mut self) -> &mut Vector { match self { Self::Phase0(inner) => &mut inner.slashings, @@ -2072,6 +2347,18 @@ impl< Self::Deneb(inner) => &mut inner.slashings, } } + pub fn previous_epoch_attestations( + &self, + ) -> Option<&List, PENDING_ATTESTATIONS_BOUND>> + { + match self { + Self::Phase0(inner) => Some(&inner.previous_epoch_attestations), + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(_) => None, + } + } pub fn previous_epoch_attestations_mut( &mut self, ) -> Option< @@ -2085,6 +2372,18 @@ impl< Self::Deneb(_) => None, } } + pub fn current_epoch_attestations( + &self, + ) -> Option<&List, PENDING_ATTESTATIONS_BOUND>> + { + match self { + Self::Phase0(inner) => Some(&inner.current_epoch_attestations), + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(_) => None, + } + } pub fn current_epoch_attestations_mut( &mut self, ) -> Option< @@ -2098,6 +2397,15 @@ impl< Self::Deneb(_) => None, } } + pub fn justification_bits(&self) -> &Bitvector { + match self { + Self::Phase0(inner) => &inner.justification_bits, + Self::Altair(inner) => &inner.justification_bits, + Self::Bellatrix(inner) => &inner.justification_bits, + Self::Capella(inner) => &inner.justification_bits, + Self::Deneb(inner) => &inner.justification_bits, + } + } pub fn justification_bits_mut(&mut self) -> &mut Bitvector { match self { Self::Phase0(inner) => &mut inner.justification_bits, @@ -2107,6 +2415,15 @@ impl< Self::Deneb(inner) => &mut inner.justification_bits, } } + pub fn previous_justified_checkpoint(&self) -> &Checkpoint { + match self { + Self::Phase0(inner) => &inner.previous_justified_checkpoint, + Self::Altair(inner) => &inner.previous_justified_checkpoint, + Self::Bellatrix(inner) => &inner.previous_justified_checkpoint, + Self::Capella(inner) => &inner.previous_justified_checkpoint, + Self::Deneb(inner) => &inner.previous_justified_checkpoint, + } + } pub fn previous_justified_checkpoint_mut(&mut self) -> &mut Checkpoint { match self { Self::Phase0(inner) => &mut inner.previous_justified_checkpoint, @@ -2116,6 +2433,15 @@ impl< Self::Deneb(inner) => &mut inner.previous_justified_checkpoint, } } + pub fn current_justified_checkpoint(&self) -> &Checkpoint { + match self { + Self::Phase0(inner) => &inner.current_justified_checkpoint, + Self::Altair(inner) => &inner.current_justified_checkpoint, + Self::Bellatrix(inner) => &inner.current_justified_checkpoint, + Self::Capella(inner) => &inner.current_justified_checkpoint, + Self::Deneb(inner) => &inner.current_justified_checkpoint, + } + } pub fn current_justified_checkpoint_mut(&mut self) -> &mut Checkpoint { match self { Self::Phase0(inner) => &mut inner.current_justified_checkpoint, @@ -2125,6 +2451,15 @@ impl< Self::Deneb(inner) => &mut inner.current_justified_checkpoint, } } + pub fn finalized_checkpoint(&self) -> &Checkpoint { + match self { + Self::Phase0(inner) => &inner.finalized_checkpoint, + Self::Altair(inner) => &inner.finalized_checkpoint, + Self::Bellatrix(inner) => &inner.finalized_checkpoint, + Self::Capella(inner) => &inner.finalized_checkpoint, + Self::Deneb(inner) => &inner.finalized_checkpoint, + } + } pub fn finalized_checkpoint_mut(&mut self) -> &mut Checkpoint { match self { Self::Phase0(inner) => &mut inner.finalized_checkpoint, @@ -2134,6 +2469,17 @@ impl< Self::Deneb(inner) => &mut inner.finalized_checkpoint, } } + pub fn previous_epoch_participation( + &self, + ) -> Option<&List> { + match self { + Self::Phase0(_) => None, + Self::Altair(inner) => Some(&inner.previous_epoch_participation), + Self::Bellatrix(inner) => Some(&inner.previous_epoch_participation), + Self::Capella(inner) => Some(&inner.previous_epoch_participation), + Self::Deneb(inner) => Some(&inner.previous_epoch_participation), + } + } pub fn previous_epoch_participation_mut( &mut self, ) -> Option<&mut List> { @@ -2145,6 +2491,17 @@ impl< Self::Deneb(inner) => Some(&mut inner.previous_epoch_participation), } } + pub fn current_epoch_participation( + &self, + ) -> Option<&List> { + match self { + Self::Phase0(_) => None, + Self::Altair(inner) => Some(&inner.current_epoch_participation), + Self::Bellatrix(inner) => Some(&inner.current_epoch_participation), + Self::Capella(inner) => Some(&inner.current_epoch_participation), + Self::Deneb(inner) => Some(&inner.current_epoch_participation), + } + } pub fn current_epoch_participation_mut( &mut self, ) -> Option<&mut List> { @@ -2156,6 +2513,15 @@ impl< Self::Deneb(inner) => Some(&mut inner.current_epoch_participation), } } + pub fn inactivity_scores(&self) -> Option<&List> { + match self { + Self::Phase0(_) => None, + Self::Altair(inner) => Some(&inner.inactivity_scores), + Self::Bellatrix(inner) => Some(&inner.inactivity_scores), + Self::Capella(inner) => Some(&inner.inactivity_scores), + Self::Deneb(inner) => Some(&inner.inactivity_scores), + } + } pub fn inactivity_scores_mut(&mut self) -> Option<&mut List> { match self { Self::Phase0(_) => None, @@ -2165,6 +2531,15 @@ impl< Self::Deneb(inner) => Some(&mut inner.inactivity_scores), } } + pub fn current_sync_committee(&self) -> Option<&SyncCommittee> { + match self { + Self::Phase0(_) => None, + Self::Altair(inner) => Some(&inner.current_sync_committee), + Self::Bellatrix(inner) => Some(&inner.current_sync_committee), + Self::Capella(inner) => Some(&inner.current_sync_committee), + Self::Deneb(inner) => Some(&inner.current_sync_committee), + } + } pub fn current_sync_committee_mut( &mut self, ) -> Option<&mut SyncCommittee> { @@ -2176,6 +2551,15 @@ impl< Self::Deneb(inner) => Some(&mut inner.current_sync_committee), } } + pub fn next_sync_committee(&self) -> Option<&SyncCommittee> { + match self { + Self::Phase0(_) => None, + Self::Altair(inner) => Some(&inner.next_sync_committee), + Self::Bellatrix(inner) => Some(&inner.next_sync_committee), + Self::Capella(inner) => Some(&inner.next_sync_committee), + Self::Deneb(inner) => Some(&inner.next_sync_committee), + } + } pub fn next_sync_committee_mut(&mut self) -> Option<&mut SyncCommittee> { match self { Self::Phase0(_) => None, @@ -2185,6 +2569,17 @@ impl< Self::Deneb(inner) => Some(&mut inner.next_sync_committee), } } + pub fn latest_execution_payload_header( + &self, + ) -> Option> { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(inner) => Some(From::from(&inner.latest_execution_payload_header)), + Self::Capella(inner) => Some(From::from(&inner.latest_execution_payload_header)), + Self::Deneb(inner) => Some(From::from(&inner.latest_execution_payload_header)), + } + } pub fn latest_execution_payload_header_mut( &mut self, ) -> Option> { @@ -2196,6 +2591,15 @@ impl< Self::Deneb(inner) => Some(From::from(&mut inner.latest_execution_payload_header)), } } + pub fn next_withdrawal_index(&self) -> Option<&WithdrawalIndex> { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.next_withdrawal_index), + Self::Deneb(inner) => Some(&inner.next_withdrawal_index), + } + } pub fn next_withdrawal_index_mut(&mut self) -> Option<&mut WithdrawalIndex> { match self { Self::Phase0(_) => None, @@ -2205,6 +2609,15 @@ impl< Self::Deneb(inner) => Some(&mut inner.next_withdrawal_index), } } + pub fn next_withdrawal_validator_index(&self) -> Option<&ValidatorIndex> { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.next_withdrawal_validator_index), + Self::Deneb(inner) => Some(&inner.next_withdrawal_validator_index), + } + } pub fn next_withdrawal_validator_index_mut(&mut self) -> Option<&mut ValidatorIndex> { match self { Self::Phase0(_) => None, @@ -2214,6 +2627,15 @@ impl< Self::Deneb(inner) => Some(&mut inner.next_withdrawal_validator_index), } } + pub fn historical_summaries(&self) -> Option<&List> { + match self { + Self::Phase0(_) => None, + Self::Altair(_) => None, + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.historical_summaries), + Self::Deneb(inner) => Some(&inner.historical_summaries), + } + } pub fn historical_summaries_mut( &mut self, ) -> Option<&mut List> { diff --git a/ethereum-consensus/src/types/blinded_beacon_block.rs b/ethereum-consensus/src/types/blinded_beacon_block.rs index 7a205332e..202a910fa 100644 --- a/ethereum-consensus/src/types/blinded_beacon_block.rs +++ b/ethereum-consensus/src/types/blinded_beacon_block.rs @@ -6,10 +6,10 @@ use crate::{ primitives::{Root, Slot, ValidatorIndex}, ssz::prelude::*, types::blinded_beacon_block_body::{BlindedBeaconBlockBodyRef, BlindedBeaconBlockBodyRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum BlindedBeaconBlock< const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, @@ -219,110 +219,114 @@ impl< _ => None, } } - pub fn slot(&self) -> Option<&Slot> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.slot), - Self::Capella(inner) => Some(&inner.slot), - Self::Deneb(inner) => Some(&inner.slot), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn slot_mut(&mut self) -> Option<&mut Slot> { + pub fn slot(&self) -> &Slot { match self { - Self::Bellatrix(inner) => Some(&mut inner.slot), - Self::Capella(inner) => Some(&mut inner.slot), - Self::Deneb(inner) => Some(&mut inner.slot), + Self::Bellatrix(inner) => &inner.slot, + Self::Capella(inner) => &inner.slot, + Self::Deneb(inner) => &inner.slot, } } - pub fn proposer_index(&self) -> Option<&ValidatorIndex> { + pub fn slot_mut(&mut self) -> &mut Slot { match self { - Self::Bellatrix(inner) => Some(&inner.proposer_index), - Self::Capella(inner) => Some(&inner.proposer_index), - Self::Deneb(inner) => Some(&inner.proposer_index), + Self::Bellatrix(inner) => &mut inner.slot, + Self::Capella(inner) => &mut inner.slot, + Self::Deneb(inner) => &mut inner.slot, } } - pub fn proposer_index_mut(&mut self) -> Option<&mut ValidatorIndex> { + pub fn proposer_index(&self) -> &ValidatorIndex { match self { - Self::Bellatrix(inner) => Some(&mut inner.proposer_index), - Self::Capella(inner) => Some(&mut inner.proposer_index), - Self::Deneb(inner) => Some(&mut inner.proposer_index), + Self::Bellatrix(inner) => &inner.proposer_index, + Self::Capella(inner) => &inner.proposer_index, + Self::Deneb(inner) => &inner.proposer_index, } } - pub fn parent_root(&self) -> Option<&Root> { + pub fn proposer_index_mut(&mut self) -> &mut ValidatorIndex { match self { - Self::Bellatrix(inner) => Some(&inner.parent_root), - Self::Capella(inner) => Some(&inner.parent_root), - Self::Deneb(inner) => Some(&inner.parent_root), + Self::Bellatrix(inner) => &mut inner.proposer_index, + Self::Capella(inner) => &mut inner.proposer_index, + Self::Deneb(inner) => &mut inner.proposer_index, } } - pub fn parent_root_mut(&mut self) -> Option<&mut Root> { + pub fn parent_root(&self) -> &Root { match self { - Self::Bellatrix(inner) => Some(&mut inner.parent_root), - Self::Capella(inner) => Some(&mut inner.parent_root), - Self::Deneb(inner) => Some(&mut inner.parent_root), + Self::Bellatrix(inner) => &inner.parent_root, + Self::Capella(inner) => &inner.parent_root, + Self::Deneb(inner) => &inner.parent_root, } } - pub fn state_root(&self) -> Option<&Root> { + pub fn parent_root_mut(&mut self) -> &mut Root { match self { - Self::Bellatrix(inner) => Some(&inner.state_root), - Self::Capella(inner) => Some(&inner.state_root), - Self::Deneb(inner) => Some(&inner.state_root), + Self::Bellatrix(inner) => &mut inner.parent_root, + Self::Capella(inner) => &mut inner.parent_root, + Self::Deneb(inner) => &mut inner.parent_root, } } - pub fn state_root_mut(&mut self) -> Option<&mut Root> { + pub fn state_root(&self) -> &Root { match self { - Self::Bellatrix(inner) => Some(&mut inner.state_root), - Self::Capella(inner) => Some(&mut inner.state_root), - Self::Deneb(inner) => Some(&mut inner.state_root), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, + } + } + pub fn state_root_mut(&mut self) -> &mut Root { + match self { + Self::Bellatrix(inner) => &mut inner.state_root, + Self::Capella(inner) => &mut inner.state_root, + Self::Deneb(inner) => &mut inner.state_root, } } pub fn body( &self, - ) -> Option< - BlindedBeaconBlockBodyRef< - MAX_PROPOSER_SLASHINGS, - MAX_VALIDATORS_PER_COMMITTEE, - MAX_ATTESTER_SLASHINGS, - MAX_ATTESTATIONS, - MAX_DEPOSITS, - MAX_VOLUNTARY_EXITS, - SYNC_COMMITTEE_SIZE, - BYTES_PER_LOGS_BLOOM, - MAX_EXTRA_DATA_BYTES, - MAX_BLS_TO_EXECUTION_CHANGES, - MAX_BLOB_COMMITMENTS_PER_BLOCK, - >, + ) -> BlindedBeaconBlockBodyRef< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, > { match self { - Self::Bellatrix(inner) => Some(From::from(&inner.body)), - Self::Capella(inner) => Some(From::from(&inner.body)), - Self::Deneb(inner) => Some(From::from(&inner.body)), + Self::Bellatrix(inner) => From::from(&inner.body), + Self::Capella(inner) => From::from(&inner.body), + Self::Deneb(inner) => From::from(&inner.body), } } pub fn body_mut( &mut self, - ) -> Option< - BlindedBeaconBlockBodyRefMut< - MAX_PROPOSER_SLASHINGS, - MAX_VALIDATORS_PER_COMMITTEE, - MAX_ATTESTER_SLASHINGS, - MAX_ATTESTATIONS, - MAX_DEPOSITS, - MAX_VOLUNTARY_EXITS, - SYNC_COMMITTEE_SIZE, - BYTES_PER_LOGS_BLOOM, - MAX_EXTRA_DATA_BYTES, - MAX_BLS_TO_EXECUTION_CHANGES, - MAX_BLOB_COMMITMENTS_PER_BLOCK, - >, + ) -> BlindedBeaconBlockBodyRefMut< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, > { match self { - Self::Bellatrix(inner) => Some(From::from(&mut inner.body)), - Self::Capella(inner) => Some(From::from(&mut inner.body)), - Self::Deneb(inner) => Some(From::from(&mut inner.body)), + Self::Bellatrix(inner) => From::from(&mut inner.body), + Self::Capella(inner) => From::from(&mut inner.body), + Self::Deneb(inner) => From::from(&mut inner.body), } } } impl< + 'de, const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, const MAX_ATTESTER_SLASHINGS: usize, @@ -334,7 +338,7 @@ impl< const MAX_EXTRA_DATA_BYTES: usize, const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, - > serde::Serialize + > serde::Deserialize<'de> for BlindedBeaconBlock< MAX_PROPOSER_SLASHINGS, MAX_VALIDATORS_PER_COMMITTEE, @@ -349,15 +353,21 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -510,55 +520,60 @@ impl< _ => None, } } - pub fn slot(&self) -> Option<&Slot> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.slot), - Self::Capella(inner) => Some(&inner.slot), - Self::Deneb(inner) => Some(&inner.slot), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn proposer_index(&self) -> Option<&ValidatorIndex> { + pub fn slot(&self) -> &Slot { match self { - Self::Bellatrix(inner) => Some(&inner.proposer_index), - Self::Capella(inner) => Some(&inner.proposer_index), - Self::Deneb(inner) => Some(&inner.proposer_index), + Self::Bellatrix(inner) => &inner.slot, + Self::Capella(inner) => &inner.slot, + Self::Deneb(inner) => &inner.slot, } } - pub fn parent_root(&self) -> Option<&Root> { + pub fn proposer_index(&self) -> &ValidatorIndex { match self { - Self::Bellatrix(inner) => Some(&inner.parent_root), - Self::Capella(inner) => Some(&inner.parent_root), - Self::Deneb(inner) => Some(&inner.parent_root), + Self::Bellatrix(inner) => &inner.proposer_index, + Self::Capella(inner) => &inner.proposer_index, + Self::Deneb(inner) => &inner.proposer_index, } } - pub fn state_root(&self) -> Option<&Root> { + pub fn parent_root(&self) -> &Root { match self { - Self::Bellatrix(inner) => Some(&inner.state_root), - Self::Capella(inner) => Some(&inner.state_root), - Self::Deneb(inner) => Some(&inner.state_root), + Self::Bellatrix(inner) => &inner.parent_root, + Self::Capella(inner) => &inner.parent_root, + Self::Deneb(inner) => &inner.parent_root, + } + } + pub fn state_root(&self) -> &Root { + match self { + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } pub fn body( &self, - ) -> Option< - BlindedBeaconBlockBodyRef< - MAX_PROPOSER_SLASHINGS, - MAX_VALIDATORS_PER_COMMITTEE, - MAX_ATTESTER_SLASHINGS, - MAX_ATTESTATIONS, - MAX_DEPOSITS, - MAX_VOLUNTARY_EXITS, - SYNC_COMMITTEE_SIZE, - BYTES_PER_LOGS_BLOOM, - MAX_EXTRA_DATA_BYTES, - MAX_BLS_TO_EXECUTION_CHANGES, - MAX_BLOB_COMMITMENTS_PER_BLOCK, - >, + ) -> BlindedBeaconBlockBodyRef< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, > { match self { - Self::Bellatrix(inner) => Some(From::from(&inner.body)), - Self::Capella(inner) => Some(From::from(&inner.body)), - Self::Deneb(inner) => Some(From::from(&inner.body)), + Self::Bellatrix(inner) => From::from(&inner.body), + Self::Capella(inner) => From::from(&inner.body), + Self::Deneb(inner) => From::from(&inner.body), } } } @@ -742,7 +757,8 @@ impl< Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum BlindedBeaconBlockRefMut< 'a, const MAX_PROPOSER_SLASHINGS: usize, @@ -829,6 +845,26 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { + pub fn bellatrix( + &self, + ) -> Option< + &bellatrix::BlindedBeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >, + > { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option< @@ -849,6 +885,27 @@ impl< _ => None, } } + pub fn capella( + &self, + ) -> Option< + &capella::BlindedBeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + >, + > { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option< @@ -870,6 +927,28 @@ impl< _ => None, } } + pub fn deneb( + &self, + ) -> Option< + &deneb::BlindedBeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + >, + > { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option< @@ -892,55 +971,109 @@ impl< _ => None, } } - pub fn slot_mut(&mut self) -> Option<&mut Slot> { + pub fn version(&self) -> Version { + match self { + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn slot(&self) -> &Slot { + match self { + Self::Bellatrix(inner) => &inner.slot, + Self::Capella(inner) => &inner.slot, + Self::Deneb(inner) => &inner.slot, + } + } + pub fn slot_mut(&mut self) -> &mut Slot { match self { - Self::Bellatrix(inner) => Some(&mut inner.slot), - Self::Capella(inner) => Some(&mut inner.slot), - Self::Deneb(inner) => Some(&mut inner.slot), + Self::Bellatrix(inner) => &mut inner.slot, + Self::Capella(inner) => &mut inner.slot, + Self::Deneb(inner) => &mut inner.slot, } } - pub fn proposer_index_mut(&mut self) -> Option<&mut ValidatorIndex> { + pub fn proposer_index(&self) -> &ValidatorIndex { match self { - Self::Bellatrix(inner) => Some(&mut inner.proposer_index), - Self::Capella(inner) => Some(&mut inner.proposer_index), - Self::Deneb(inner) => Some(&mut inner.proposer_index), + Self::Bellatrix(inner) => &inner.proposer_index, + Self::Capella(inner) => &inner.proposer_index, + Self::Deneb(inner) => &inner.proposer_index, } } - pub fn parent_root_mut(&mut self) -> Option<&mut Root> { + pub fn proposer_index_mut(&mut self) -> &mut ValidatorIndex { match self { - Self::Bellatrix(inner) => Some(&mut inner.parent_root), - Self::Capella(inner) => Some(&mut inner.parent_root), - Self::Deneb(inner) => Some(&mut inner.parent_root), + Self::Bellatrix(inner) => &mut inner.proposer_index, + Self::Capella(inner) => &mut inner.proposer_index, + Self::Deneb(inner) => &mut inner.proposer_index, } } - pub fn state_root_mut(&mut self) -> Option<&mut Root> { + pub fn parent_root(&self) -> &Root { match self { - Self::Bellatrix(inner) => Some(&mut inner.state_root), - Self::Capella(inner) => Some(&mut inner.state_root), - Self::Deneb(inner) => Some(&mut inner.state_root), + Self::Bellatrix(inner) => &inner.parent_root, + Self::Capella(inner) => &inner.parent_root, + Self::Deneb(inner) => &inner.parent_root, + } + } + pub fn parent_root_mut(&mut self) -> &mut Root { + match self { + Self::Bellatrix(inner) => &mut inner.parent_root, + Self::Capella(inner) => &mut inner.parent_root, + Self::Deneb(inner) => &mut inner.parent_root, + } + } + pub fn state_root(&self) -> &Root { + match self { + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, + } + } + pub fn state_root_mut(&mut self) -> &mut Root { + match self { + Self::Bellatrix(inner) => &mut inner.state_root, + Self::Capella(inner) => &mut inner.state_root, + Self::Deneb(inner) => &mut inner.state_root, + } + } + pub fn body( + &self, + ) -> BlindedBeaconBlockBodyRef< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + > { + match self { + Self::Bellatrix(inner) => From::from(&inner.body), + Self::Capella(inner) => From::from(&inner.body), + Self::Deneb(inner) => From::from(&inner.body), } } pub fn body_mut( &mut self, - ) -> Option< - BlindedBeaconBlockBodyRefMut< - MAX_PROPOSER_SLASHINGS, - MAX_VALIDATORS_PER_COMMITTEE, - MAX_ATTESTER_SLASHINGS, - MAX_ATTESTATIONS, - MAX_DEPOSITS, - MAX_VOLUNTARY_EXITS, - SYNC_COMMITTEE_SIZE, - BYTES_PER_LOGS_BLOOM, - MAX_EXTRA_DATA_BYTES, - MAX_BLS_TO_EXECUTION_CHANGES, - MAX_BLOB_COMMITMENTS_PER_BLOCK, - >, + ) -> BlindedBeaconBlockBodyRefMut< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, > { match self { - Self::Bellatrix(inner) => Some(From::from(&mut inner.body)), - Self::Capella(inner) => Some(From::from(&mut inner.body)), - Self::Deneb(inner) => Some(From::from(&mut inner.body)), + Self::Bellatrix(inner) => From::from(&mut inner.body), + Self::Capella(inner) => From::from(&mut inner.body), + Self::Deneb(inner) => From::from(&mut inner.body), } } } diff --git a/ethereum-consensus/src/types/blinded_beacon_block_body.rs b/ethereum-consensus/src/types/blinded_beacon_block_body.rs index 37ff5972b..193326052 100644 --- a/ethereum-consensus/src/types/blinded_beacon_block_body.rs +++ b/ethereum-consensus/src/types/blinded_beacon_block_body.rs @@ -10,10 +10,10 @@ use crate::{ primitives::{BlsSignature, Bytes32}, ssz::prelude::*, types::execution_payload_header::{ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum BlindedBeaconBlockBody< const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, @@ -223,161 +223,165 @@ impl< _ => None, } } - pub fn randao_reveal(&self) -> Option<&BlsSignature> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.randao_reveal), - Self::Capella(inner) => Some(&inner.randao_reveal), - Self::Deneb(inner) => Some(&inner.randao_reveal), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn randao_reveal_mut(&mut self) -> Option<&mut BlsSignature> { + pub fn randao_reveal(&self) -> &BlsSignature { match self { - Self::Bellatrix(inner) => Some(&mut inner.randao_reveal), - Self::Capella(inner) => Some(&mut inner.randao_reveal), - Self::Deneb(inner) => Some(&mut inner.randao_reveal), + Self::Bellatrix(inner) => &inner.randao_reveal, + Self::Capella(inner) => &inner.randao_reveal, + Self::Deneb(inner) => &inner.randao_reveal, } } - pub fn eth1_data(&self) -> Option<&Eth1Data> { + pub fn randao_reveal_mut(&mut self) -> &mut BlsSignature { match self { - Self::Bellatrix(inner) => Some(&inner.eth1_data), - Self::Capella(inner) => Some(&inner.eth1_data), - Self::Deneb(inner) => Some(&inner.eth1_data), + Self::Bellatrix(inner) => &mut inner.randao_reveal, + Self::Capella(inner) => &mut inner.randao_reveal, + Self::Deneb(inner) => &mut inner.randao_reveal, } } - pub fn eth1_data_mut(&mut self) -> Option<&mut Eth1Data> { + pub fn eth1_data(&self) -> &Eth1Data { match self { - Self::Bellatrix(inner) => Some(&mut inner.eth1_data), - Self::Capella(inner) => Some(&mut inner.eth1_data), - Self::Deneb(inner) => Some(&mut inner.eth1_data), + Self::Bellatrix(inner) => &inner.eth1_data, + Self::Capella(inner) => &inner.eth1_data, + Self::Deneb(inner) => &inner.eth1_data, } } - pub fn graffiti(&self) -> Option<&Bytes32> { + pub fn eth1_data_mut(&mut self) -> &mut Eth1Data { match self { - Self::Bellatrix(inner) => Some(&inner.graffiti), - Self::Capella(inner) => Some(&inner.graffiti), - Self::Deneb(inner) => Some(&inner.graffiti), + Self::Bellatrix(inner) => &mut inner.eth1_data, + Self::Capella(inner) => &mut inner.eth1_data, + Self::Deneb(inner) => &mut inner.eth1_data, } } - pub fn graffiti_mut(&mut self) -> Option<&mut Bytes32> { + pub fn graffiti(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.graffiti), - Self::Capella(inner) => Some(&mut inner.graffiti), - Self::Deneb(inner) => Some(&mut inner.graffiti), + Self::Bellatrix(inner) => &inner.graffiti, + Self::Capella(inner) => &inner.graffiti, + Self::Deneb(inner) => &inner.graffiti, } } - pub fn proposer_slashings(&self) -> Option<&List> { + pub fn graffiti_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.proposer_slashings), - Self::Capella(inner) => Some(&inner.proposer_slashings), - Self::Deneb(inner) => Some(&inner.proposer_slashings), + Self::Bellatrix(inner) => &mut inner.graffiti, + Self::Capella(inner) => &mut inner.graffiti, + Self::Deneb(inner) => &mut inner.graffiti, + } + } + pub fn proposer_slashings(&self) -> &List { + match self { + Self::Bellatrix(inner) => &inner.proposer_slashings, + Self::Capella(inner) => &inner.proposer_slashings, + Self::Deneb(inner) => &inner.proposer_slashings, } } pub fn proposer_slashings_mut( &mut self, - ) -> Option<&mut List> { + ) -> &mut List { match self { - Self::Bellatrix(inner) => Some(&mut inner.proposer_slashings), - Self::Capella(inner) => Some(&mut inner.proposer_slashings), - Self::Deneb(inner) => Some(&mut inner.proposer_slashings), + Self::Bellatrix(inner) => &mut inner.proposer_slashings, + Self::Capella(inner) => &mut inner.proposer_slashings, + Self::Deneb(inner) => &mut inner.proposer_slashings, } } pub fn attester_slashings( &self, - ) -> Option<&List, MAX_ATTESTER_SLASHINGS>> { + ) -> &List, MAX_ATTESTER_SLASHINGS> { match self { - Self::Bellatrix(inner) => Some(&inner.attester_slashings), - Self::Capella(inner) => Some(&inner.attester_slashings), - Self::Deneb(inner) => Some(&inner.attester_slashings), + Self::Bellatrix(inner) => &inner.attester_slashings, + Self::Capella(inner) => &inner.attester_slashings, + Self::Deneb(inner) => &inner.attester_slashings, } } pub fn attester_slashings_mut( &mut self, - ) -> Option<&mut List, MAX_ATTESTER_SLASHINGS>> - { + ) -> &mut List, MAX_ATTESTER_SLASHINGS> { match self { - Self::Bellatrix(inner) => Some(&mut inner.attester_slashings), - Self::Capella(inner) => Some(&mut inner.attester_slashings), - Self::Deneb(inner) => Some(&mut inner.attester_slashings), + Self::Bellatrix(inner) => &mut inner.attester_slashings, + Self::Capella(inner) => &mut inner.attester_slashings, + Self::Deneb(inner) => &mut inner.attester_slashings, } } pub fn attestations( &self, - ) -> Option<&List, MAX_ATTESTATIONS>> { + ) -> &List, MAX_ATTESTATIONS> { match self { - Self::Bellatrix(inner) => Some(&inner.attestations), - Self::Capella(inner) => Some(&inner.attestations), - Self::Deneb(inner) => Some(&inner.attestations), + Self::Bellatrix(inner) => &inner.attestations, + Self::Capella(inner) => &inner.attestations, + Self::Deneb(inner) => &inner.attestations, } } pub fn attestations_mut( &mut self, - ) -> Option<&mut List, MAX_ATTESTATIONS>> { + ) -> &mut List, MAX_ATTESTATIONS> { match self { - Self::Bellatrix(inner) => Some(&mut inner.attestations), - Self::Capella(inner) => Some(&mut inner.attestations), - Self::Deneb(inner) => Some(&mut inner.attestations), + Self::Bellatrix(inner) => &mut inner.attestations, + Self::Capella(inner) => &mut inner.attestations, + Self::Deneb(inner) => &mut inner.attestations, } } - pub fn deposits(&self) -> Option<&List> { + pub fn deposits(&self) -> &List { match self { - Self::Bellatrix(inner) => Some(&inner.deposits), - Self::Capella(inner) => Some(&inner.deposits), - Self::Deneb(inner) => Some(&inner.deposits), + Self::Bellatrix(inner) => &inner.deposits, + Self::Capella(inner) => &inner.deposits, + Self::Deneb(inner) => &inner.deposits, } } - pub fn deposits_mut(&mut self) -> Option<&mut List> { + pub fn deposits_mut(&mut self) -> &mut List { match self { - Self::Bellatrix(inner) => Some(&mut inner.deposits), - Self::Capella(inner) => Some(&mut inner.deposits), - Self::Deneb(inner) => Some(&mut inner.deposits), + Self::Bellatrix(inner) => &mut inner.deposits, + Self::Capella(inner) => &mut inner.deposits, + Self::Deneb(inner) => &mut inner.deposits, } } - pub fn voluntary_exits(&self) -> Option<&List> { + pub fn voluntary_exits(&self) -> &List { match self { - Self::Bellatrix(inner) => Some(&inner.voluntary_exits), - Self::Capella(inner) => Some(&inner.voluntary_exits), - Self::Deneb(inner) => Some(&inner.voluntary_exits), + Self::Bellatrix(inner) => &inner.voluntary_exits, + Self::Capella(inner) => &inner.voluntary_exits, + Self::Deneb(inner) => &inner.voluntary_exits, } } - pub fn voluntary_exits_mut( - &mut self, - ) -> Option<&mut List> { + pub fn voluntary_exits_mut(&mut self) -> &mut List { match self { - Self::Bellatrix(inner) => Some(&mut inner.voluntary_exits), - Self::Capella(inner) => Some(&mut inner.voluntary_exits), - Self::Deneb(inner) => Some(&mut inner.voluntary_exits), + Self::Bellatrix(inner) => &mut inner.voluntary_exits, + Self::Capella(inner) => &mut inner.voluntary_exits, + Self::Deneb(inner) => &mut inner.voluntary_exits, } } - pub fn sync_aggregate(&self) -> Option<&SyncAggregate> { + pub fn sync_aggregate(&self) -> &SyncAggregate { match self { - Self::Bellatrix(inner) => Some(&inner.sync_aggregate), - Self::Capella(inner) => Some(&inner.sync_aggregate), - Self::Deneb(inner) => Some(&inner.sync_aggregate), + Self::Bellatrix(inner) => &inner.sync_aggregate, + Self::Capella(inner) => &inner.sync_aggregate, + Self::Deneb(inner) => &inner.sync_aggregate, } } - pub fn sync_aggregate_mut(&mut self) -> Option<&mut SyncAggregate> { + pub fn sync_aggregate_mut(&mut self) -> &mut SyncAggregate { match self { - Self::Bellatrix(inner) => Some(&mut inner.sync_aggregate), - Self::Capella(inner) => Some(&mut inner.sync_aggregate), - Self::Deneb(inner) => Some(&mut inner.sync_aggregate), + Self::Bellatrix(inner) => &mut inner.sync_aggregate, + Self::Capella(inner) => &mut inner.sync_aggregate, + Self::Deneb(inner) => &mut inner.sync_aggregate, } } pub fn execution_payload_header( &self, - ) -> Option> { + ) -> ExecutionPayloadHeaderRef { match self { - Self::Bellatrix(inner) => Some(From::from(&inner.execution_payload_header)), - Self::Capella(inner) => Some(From::from(&inner.execution_payload_header)), - Self::Deneb(inner) => Some(From::from(&inner.execution_payload_header)), + Self::Bellatrix(inner) => From::from(&inner.execution_payload_header), + Self::Capella(inner) => From::from(&inner.execution_payload_header), + Self::Deneb(inner) => From::from(&inner.execution_payload_header), } } pub fn execution_payload_header_mut( &mut self, - ) -> Option> { + ) -> ExecutionPayloadHeaderRefMut { match self { - Self::Bellatrix(inner) => Some(From::from(&mut inner.execution_payload_header)), - Self::Capella(inner) => Some(From::from(&mut inner.execution_payload_header)), - Self::Deneb(inner) => Some(From::from(&mut inner.execution_payload_header)), + Self::Bellatrix(inner) => From::from(&mut inner.execution_payload_header), + Self::Capella(inner) => From::from(&mut inner.execution_payload_header), + Self::Deneb(inner) => From::from(&mut inner.execution_payload_header), } } pub fn bls_to_execution_changes( @@ -418,6 +422,7 @@ impl< } } impl< + 'de, const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, const MAX_ATTESTER_SLASHINGS: usize, @@ -429,7 +434,7 @@ impl< const MAX_EXTRA_DATA_BYTES: usize, const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, - > serde::Serialize + > serde::Deserialize<'de> for BlindedBeaconBlockBody< MAX_PROPOSER_SLASHINGS, MAX_VALIDATORS_PER_COMMITTEE, @@ -444,15 +449,21 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -605,80 +616,87 @@ impl< _ => None, } } - pub fn randao_reveal(&self) -> Option<&BlsSignature> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.randao_reveal), - Self::Capella(inner) => Some(&inner.randao_reveal), - Self::Deneb(inner) => Some(&inner.randao_reveal), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn eth1_data(&self) -> Option<&Eth1Data> { + pub fn randao_reveal(&self) -> &BlsSignature { match self { - Self::Bellatrix(inner) => Some(&inner.eth1_data), - Self::Capella(inner) => Some(&inner.eth1_data), - Self::Deneb(inner) => Some(&inner.eth1_data), + Self::Bellatrix(inner) => &inner.randao_reveal, + Self::Capella(inner) => &inner.randao_reveal, + Self::Deneb(inner) => &inner.randao_reveal, } } - pub fn graffiti(&self) -> Option<&Bytes32> { + pub fn eth1_data(&self) -> &Eth1Data { match self { - Self::Bellatrix(inner) => Some(&inner.graffiti), - Self::Capella(inner) => Some(&inner.graffiti), - Self::Deneb(inner) => Some(&inner.graffiti), + Self::Bellatrix(inner) => &inner.eth1_data, + Self::Capella(inner) => &inner.eth1_data, + Self::Deneb(inner) => &inner.eth1_data, } } - pub fn proposer_slashings(&self) -> Option<&List> { + pub fn graffiti(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.proposer_slashings), - Self::Capella(inner) => Some(&inner.proposer_slashings), - Self::Deneb(inner) => Some(&inner.proposer_slashings), + Self::Bellatrix(inner) => &inner.graffiti, + Self::Capella(inner) => &inner.graffiti, + Self::Deneb(inner) => &inner.graffiti, + } + } + pub fn proposer_slashings(&self) -> &List { + match self { + Self::Bellatrix(inner) => &inner.proposer_slashings, + Self::Capella(inner) => &inner.proposer_slashings, + Self::Deneb(inner) => &inner.proposer_slashings, } } pub fn attester_slashings( &self, - ) -> Option<&List, MAX_ATTESTER_SLASHINGS>> { + ) -> &List, MAX_ATTESTER_SLASHINGS> { match self { - Self::Bellatrix(inner) => Some(&inner.attester_slashings), - Self::Capella(inner) => Some(&inner.attester_slashings), - Self::Deneb(inner) => Some(&inner.attester_slashings), + Self::Bellatrix(inner) => &inner.attester_slashings, + Self::Capella(inner) => &inner.attester_slashings, + Self::Deneb(inner) => &inner.attester_slashings, } } pub fn attestations( &self, - ) -> Option<&List, MAX_ATTESTATIONS>> { + ) -> &List, MAX_ATTESTATIONS> { match self { - Self::Bellatrix(inner) => Some(&inner.attestations), - Self::Capella(inner) => Some(&inner.attestations), - Self::Deneb(inner) => Some(&inner.attestations), + Self::Bellatrix(inner) => &inner.attestations, + Self::Capella(inner) => &inner.attestations, + Self::Deneb(inner) => &inner.attestations, } } - pub fn deposits(&self) -> Option<&List> { + pub fn deposits(&self) -> &List { match self { - Self::Bellatrix(inner) => Some(&inner.deposits), - Self::Capella(inner) => Some(&inner.deposits), - Self::Deneb(inner) => Some(&inner.deposits), + Self::Bellatrix(inner) => &inner.deposits, + Self::Capella(inner) => &inner.deposits, + Self::Deneb(inner) => &inner.deposits, } } - pub fn voluntary_exits(&self) -> Option<&List> { + pub fn voluntary_exits(&self) -> &List { match self { - Self::Bellatrix(inner) => Some(&inner.voluntary_exits), - Self::Capella(inner) => Some(&inner.voluntary_exits), - Self::Deneb(inner) => Some(&inner.voluntary_exits), + Self::Bellatrix(inner) => &inner.voluntary_exits, + Self::Capella(inner) => &inner.voluntary_exits, + Self::Deneb(inner) => &inner.voluntary_exits, } } - pub fn sync_aggregate(&self) -> Option<&SyncAggregate> { + pub fn sync_aggregate(&self) -> &SyncAggregate { match self { - Self::Bellatrix(inner) => Some(&inner.sync_aggregate), - Self::Capella(inner) => Some(&inner.sync_aggregate), - Self::Deneb(inner) => Some(&inner.sync_aggregate), + Self::Bellatrix(inner) => &inner.sync_aggregate, + Self::Capella(inner) => &inner.sync_aggregate, + Self::Deneb(inner) => &inner.sync_aggregate, } } pub fn execution_payload_header( &self, - ) -> Option> { + ) -> ExecutionPayloadHeaderRef { match self { - Self::Bellatrix(inner) => Some(From::from(&inner.execution_payload_header)), - Self::Capella(inner) => Some(From::from(&inner.execution_payload_header)), - Self::Deneb(inner) => Some(From::from(&inner.execution_payload_header)), + Self::Bellatrix(inner) => From::from(&inner.execution_payload_header), + Self::Capella(inner) => From::from(&inner.execution_payload_header), + Self::Deneb(inner) => From::from(&inner.execution_payload_header), } } pub fn bls_to_execution_changes( @@ -880,7 +898,8 @@ impl< Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum BlindedBeaconBlockBodyRefMut< 'a, const MAX_PROPOSER_SLASHINGS: usize, @@ -967,6 +986,26 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { + pub fn bellatrix( + &self, + ) -> Option< + &bellatrix::BlindedBeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >, + > { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option< @@ -987,6 +1026,27 @@ impl< _ => None, } } + pub fn capella( + &self, + ) -> Option< + &capella::BlindedBeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + >, + > { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option< @@ -1008,6 +1068,28 @@ impl< _ => None, } } + pub fn deneb( + &self, + ) -> Option< + &deneb::BlindedBeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + >, + > { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option< @@ -1030,85 +1112,174 @@ impl< _ => None, } } - pub fn randao_reveal_mut(&mut self) -> Option<&mut BlsSignature> { + pub fn version(&self) -> Version { + match self { + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn randao_reveal(&self) -> &BlsSignature { + match self { + Self::Bellatrix(inner) => &inner.randao_reveal, + Self::Capella(inner) => &inner.randao_reveal, + Self::Deneb(inner) => &inner.randao_reveal, + } + } + pub fn randao_reveal_mut(&mut self) -> &mut BlsSignature { + match self { + Self::Bellatrix(inner) => &mut inner.randao_reveal, + Self::Capella(inner) => &mut inner.randao_reveal, + Self::Deneb(inner) => &mut inner.randao_reveal, + } + } + pub fn eth1_data(&self) -> &Eth1Data { match self { - Self::Bellatrix(inner) => Some(&mut inner.randao_reveal), - Self::Capella(inner) => Some(&mut inner.randao_reveal), - Self::Deneb(inner) => Some(&mut inner.randao_reveal), + Self::Bellatrix(inner) => &inner.eth1_data, + Self::Capella(inner) => &inner.eth1_data, + Self::Deneb(inner) => &inner.eth1_data, } } - pub fn eth1_data_mut(&mut self) -> Option<&mut Eth1Data> { + pub fn eth1_data_mut(&mut self) -> &mut Eth1Data { match self { - Self::Bellatrix(inner) => Some(&mut inner.eth1_data), - Self::Capella(inner) => Some(&mut inner.eth1_data), - Self::Deneb(inner) => Some(&mut inner.eth1_data), + Self::Bellatrix(inner) => &mut inner.eth1_data, + Self::Capella(inner) => &mut inner.eth1_data, + Self::Deneb(inner) => &mut inner.eth1_data, } } - pub fn graffiti_mut(&mut self) -> Option<&mut Bytes32> { + pub fn graffiti(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.graffiti), - Self::Capella(inner) => Some(&mut inner.graffiti), - Self::Deneb(inner) => Some(&mut inner.graffiti), + Self::Bellatrix(inner) => &inner.graffiti, + Self::Capella(inner) => &inner.graffiti, + Self::Deneb(inner) => &inner.graffiti, + } + } + pub fn graffiti_mut(&mut self) -> &mut Bytes32 { + match self { + Self::Bellatrix(inner) => &mut inner.graffiti, + Self::Capella(inner) => &mut inner.graffiti, + Self::Deneb(inner) => &mut inner.graffiti, + } + } + pub fn proposer_slashings(&self) -> &List { + match self { + Self::Bellatrix(inner) => &inner.proposer_slashings, + Self::Capella(inner) => &inner.proposer_slashings, + Self::Deneb(inner) => &inner.proposer_slashings, } } pub fn proposer_slashings_mut( &mut self, - ) -> Option<&mut List> { + ) -> &mut List { match self { - Self::Bellatrix(inner) => Some(&mut inner.proposer_slashings), - Self::Capella(inner) => Some(&mut inner.proposer_slashings), - Self::Deneb(inner) => Some(&mut inner.proposer_slashings), + Self::Bellatrix(inner) => &mut inner.proposer_slashings, + Self::Capella(inner) => &mut inner.proposer_slashings, + Self::Deneb(inner) => &mut inner.proposer_slashings, + } + } + pub fn attester_slashings( + &self, + ) -> &List, MAX_ATTESTER_SLASHINGS> { + match self { + Self::Bellatrix(inner) => &inner.attester_slashings, + Self::Capella(inner) => &inner.attester_slashings, + Self::Deneb(inner) => &inner.attester_slashings, } } pub fn attester_slashings_mut( &mut self, - ) -> Option<&mut List, MAX_ATTESTER_SLASHINGS>> - { + ) -> &mut List, MAX_ATTESTER_SLASHINGS> { + match self { + Self::Bellatrix(inner) => &mut inner.attester_slashings, + Self::Capella(inner) => &mut inner.attester_slashings, + Self::Deneb(inner) => &mut inner.attester_slashings, + } + } + pub fn attestations( + &self, + ) -> &List, MAX_ATTESTATIONS> { match self { - Self::Bellatrix(inner) => Some(&mut inner.attester_slashings), - Self::Capella(inner) => Some(&mut inner.attester_slashings), - Self::Deneb(inner) => Some(&mut inner.attester_slashings), + Self::Bellatrix(inner) => &inner.attestations, + Self::Capella(inner) => &inner.attestations, + Self::Deneb(inner) => &inner.attestations, } } pub fn attestations_mut( &mut self, - ) -> Option<&mut List, MAX_ATTESTATIONS>> { + ) -> &mut List, MAX_ATTESTATIONS> { match self { - Self::Bellatrix(inner) => Some(&mut inner.attestations), - Self::Capella(inner) => Some(&mut inner.attestations), - Self::Deneb(inner) => Some(&mut inner.attestations), + Self::Bellatrix(inner) => &mut inner.attestations, + Self::Capella(inner) => &mut inner.attestations, + Self::Deneb(inner) => &mut inner.attestations, } } - pub fn deposits_mut(&mut self) -> Option<&mut List> { + pub fn deposits(&self) -> &List { match self { - Self::Bellatrix(inner) => Some(&mut inner.deposits), - Self::Capella(inner) => Some(&mut inner.deposits), - Self::Deneb(inner) => Some(&mut inner.deposits), + Self::Bellatrix(inner) => &inner.deposits, + Self::Capella(inner) => &inner.deposits, + Self::Deneb(inner) => &inner.deposits, } } - pub fn voluntary_exits_mut( - &mut self, - ) -> Option<&mut List> { + pub fn deposits_mut(&mut self) -> &mut List { match self { - Self::Bellatrix(inner) => Some(&mut inner.voluntary_exits), - Self::Capella(inner) => Some(&mut inner.voluntary_exits), - Self::Deneb(inner) => Some(&mut inner.voluntary_exits), + Self::Bellatrix(inner) => &mut inner.deposits, + Self::Capella(inner) => &mut inner.deposits, + Self::Deneb(inner) => &mut inner.deposits, } } - pub fn sync_aggregate_mut(&mut self) -> Option<&mut SyncAggregate> { + pub fn voluntary_exits(&self) -> &List { match self { - Self::Bellatrix(inner) => Some(&mut inner.sync_aggregate), - Self::Capella(inner) => Some(&mut inner.sync_aggregate), - Self::Deneb(inner) => Some(&mut inner.sync_aggregate), + Self::Bellatrix(inner) => &inner.voluntary_exits, + Self::Capella(inner) => &inner.voluntary_exits, + Self::Deneb(inner) => &inner.voluntary_exits, + } + } + pub fn voluntary_exits_mut(&mut self) -> &mut List { + match self { + Self::Bellatrix(inner) => &mut inner.voluntary_exits, + Self::Capella(inner) => &mut inner.voluntary_exits, + Self::Deneb(inner) => &mut inner.voluntary_exits, + } + } + pub fn sync_aggregate(&self) -> &SyncAggregate { + match self { + Self::Bellatrix(inner) => &inner.sync_aggregate, + Self::Capella(inner) => &inner.sync_aggregate, + Self::Deneb(inner) => &inner.sync_aggregate, + } + } + pub fn sync_aggregate_mut(&mut self) -> &mut SyncAggregate { + match self { + Self::Bellatrix(inner) => &mut inner.sync_aggregate, + Self::Capella(inner) => &mut inner.sync_aggregate, + Self::Deneb(inner) => &mut inner.sync_aggregate, + } + } + pub fn execution_payload_header( + &self, + ) -> ExecutionPayloadHeaderRef { + match self { + Self::Bellatrix(inner) => From::from(&inner.execution_payload_header), + Self::Capella(inner) => From::from(&inner.execution_payload_header), + Self::Deneb(inner) => From::from(&inner.execution_payload_header), } } pub fn execution_payload_header_mut( &mut self, - ) -> Option> { + ) -> ExecutionPayloadHeaderRefMut { match self { - Self::Bellatrix(inner) => Some(From::from(&mut inner.execution_payload_header)), - Self::Capella(inner) => Some(From::from(&mut inner.execution_payload_header)), - Self::Deneb(inner) => Some(From::from(&mut inner.execution_payload_header)), + Self::Bellatrix(inner) => From::from(&mut inner.execution_payload_header), + Self::Capella(inner) => From::from(&mut inner.execution_payload_header), + Self::Deneb(inner) => From::from(&mut inner.execution_payload_header), + } + } + pub fn bls_to_execution_changes( + &self, + ) -> Option<&List> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.bls_to_execution_changes), + Self::Deneb(inner) => Some(&inner.bls_to_execution_changes), } } pub fn bls_to_execution_changes_mut( @@ -1120,6 +1291,15 @@ impl< Self::Deneb(inner) => Some(&mut inner.bls_to_execution_changes), } } + pub fn blob_kzg_commitments( + &self, + ) -> Option<&List> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(inner) => Some(&inner.blob_kzg_commitments), + } + } pub fn blob_kzg_commitments_mut( &mut self, ) -> Option<&mut List> { diff --git a/ethereum-consensus/src/types/execution_payload.rs b/ethereum-consensus/src/types/execution_payload.rs index aa6f3cd5b..7a79295d2 100644 --- a/ethereum-consensus/src/types/execution_payload.rs +++ b/ethereum-consensus/src/types/execution_payload.rs @@ -5,10 +5,10 @@ use crate::{ deneb::execution_payload as deneb, primitives::{Bytes32, ExecutionAddress, Hash32}, ssz::prelude::*, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum ExecutionPayload< const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize, @@ -152,205 +152,211 @@ impl< _ => None, } } - pub fn parent_hash(&self) -> Option<&Hash32> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.parent_hash), - Self::Capella(inner) => Some(&inner.parent_hash), - Self::Deneb(inner) => Some(&inner.parent_hash), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn parent_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn parent_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.parent_hash), - Self::Capella(inner) => Some(&mut inner.parent_hash), - Self::Deneb(inner) => Some(&mut inner.parent_hash), + Self::Bellatrix(inner) => &inner.parent_hash, + Self::Capella(inner) => &inner.parent_hash, + Self::Deneb(inner) => &inner.parent_hash, } } - pub fn fee_recipient(&self) -> Option<&ExecutionAddress> { + pub fn parent_hash_mut(&mut self) -> &mut Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.fee_recipient), - Self::Capella(inner) => Some(&inner.fee_recipient), - Self::Deneb(inner) => Some(&inner.fee_recipient), + Self::Bellatrix(inner) => &mut inner.parent_hash, + Self::Capella(inner) => &mut inner.parent_hash, + Self::Deneb(inner) => &mut inner.parent_hash, } } - pub fn fee_recipient_mut(&mut self) -> Option<&mut ExecutionAddress> { + pub fn fee_recipient(&self) -> &ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&mut inner.fee_recipient), - Self::Capella(inner) => Some(&mut inner.fee_recipient), - Self::Deneb(inner) => Some(&mut inner.fee_recipient), + Self::Bellatrix(inner) => &inner.fee_recipient, + Self::Capella(inner) => &inner.fee_recipient, + Self::Deneb(inner) => &inner.fee_recipient, } } - pub fn state_root(&self) -> Option<&Bytes32> { + pub fn fee_recipient_mut(&mut self) -> &mut ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&inner.state_root), - Self::Capella(inner) => Some(&inner.state_root), - Self::Deneb(inner) => Some(&inner.state_root), + Self::Bellatrix(inner) => &mut inner.fee_recipient, + Self::Capella(inner) => &mut inner.fee_recipient, + Self::Deneb(inner) => &mut inner.fee_recipient, } } - pub fn state_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn state_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.state_root), - Self::Capella(inner) => Some(&mut inner.state_root), - Self::Deneb(inner) => Some(&mut inner.state_root), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } - pub fn receipts_root(&self) -> Option<&Bytes32> { + pub fn state_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.receipts_root), - Self::Capella(inner) => Some(&inner.receipts_root), - Self::Deneb(inner) => Some(&inner.receipts_root), + Self::Bellatrix(inner) => &mut inner.state_root, + Self::Capella(inner) => &mut inner.state_root, + Self::Deneb(inner) => &mut inner.state_root, } } - pub fn receipts_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn receipts_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.receipts_root), - Self::Capella(inner) => Some(&mut inner.receipts_root), - Self::Deneb(inner) => Some(&mut inner.receipts_root), + Self::Bellatrix(inner) => &inner.receipts_root, + Self::Capella(inner) => &inner.receipts_root, + Self::Deneb(inner) => &inner.receipts_root, } } - pub fn logs_bloom(&self) -> Option<&ByteVector> { + pub fn receipts_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.logs_bloom), - Self::Capella(inner) => Some(&inner.logs_bloom), - Self::Deneb(inner) => Some(&inner.logs_bloom), + Self::Bellatrix(inner) => &mut inner.receipts_root, + Self::Capella(inner) => &mut inner.receipts_root, + Self::Deneb(inner) => &mut inner.receipts_root, } } - pub fn logs_bloom_mut(&mut self) -> Option<&mut ByteVector> { + pub fn logs_bloom(&self) -> &ByteVector { match self { - Self::Bellatrix(inner) => Some(&mut inner.logs_bloom), - Self::Capella(inner) => Some(&mut inner.logs_bloom), - Self::Deneb(inner) => Some(&mut inner.logs_bloom), + Self::Bellatrix(inner) => &inner.logs_bloom, + Self::Capella(inner) => &inner.logs_bloom, + Self::Deneb(inner) => &inner.logs_bloom, } } - pub fn prev_randao(&self) -> Option<&Bytes32> { + pub fn logs_bloom_mut(&mut self) -> &mut ByteVector { match self { - Self::Bellatrix(inner) => Some(&inner.prev_randao), - Self::Capella(inner) => Some(&inner.prev_randao), - Self::Deneb(inner) => Some(&inner.prev_randao), + Self::Bellatrix(inner) => &mut inner.logs_bloom, + Self::Capella(inner) => &mut inner.logs_bloom, + Self::Deneb(inner) => &mut inner.logs_bloom, } } - pub fn prev_randao_mut(&mut self) -> Option<&mut Bytes32> { + pub fn prev_randao(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.prev_randao), - Self::Capella(inner) => Some(&mut inner.prev_randao), - Self::Deneb(inner) => Some(&mut inner.prev_randao), + Self::Bellatrix(inner) => &inner.prev_randao, + Self::Capella(inner) => &inner.prev_randao, + Self::Deneb(inner) => &inner.prev_randao, } } - pub fn block_number(&self) -> Option<&u64> { + pub fn prev_randao_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.block_number), - Self::Capella(inner) => Some(&inner.block_number), - Self::Deneb(inner) => Some(&inner.block_number), + Self::Bellatrix(inner) => &mut inner.prev_randao, + Self::Capella(inner) => &mut inner.prev_randao, + Self::Deneb(inner) => &mut inner.prev_randao, } } - pub fn block_number_mut(&mut self) -> Option<&mut u64> { + pub fn block_number(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_number), - Self::Capella(inner) => Some(&mut inner.block_number), - Self::Deneb(inner) => Some(&mut inner.block_number), + Self::Bellatrix(inner) => &inner.block_number, + Self::Capella(inner) => &inner.block_number, + Self::Deneb(inner) => &inner.block_number, } } - pub fn gas_limit(&self) -> Option<&u64> { + pub fn block_number_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_limit), - Self::Capella(inner) => Some(&inner.gas_limit), - Self::Deneb(inner) => Some(&inner.gas_limit), + Self::Bellatrix(inner) => &mut inner.block_number, + Self::Capella(inner) => &mut inner.block_number, + Self::Deneb(inner) => &mut inner.block_number, } } - pub fn gas_limit_mut(&mut self) -> Option<&mut u64> { + pub fn gas_limit(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_limit), - Self::Capella(inner) => Some(&mut inner.gas_limit), - Self::Deneb(inner) => Some(&mut inner.gas_limit), + Self::Bellatrix(inner) => &inner.gas_limit, + Self::Capella(inner) => &inner.gas_limit, + Self::Deneb(inner) => &inner.gas_limit, } } - pub fn gas_used(&self) -> Option<&u64> { + pub fn gas_limit_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_used), - Self::Capella(inner) => Some(&inner.gas_used), - Self::Deneb(inner) => Some(&inner.gas_used), + Self::Bellatrix(inner) => &mut inner.gas_limit, + Self::Capella(inner) => &mut inner.gas_limit, + Self::Deneb(inner) => &mut inner.gas_limit, } } - pub fn gas_used_mut(&mut self) -> Option<&mut u64> { + pub fn gas_used(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_used), - Self::Capella(inner) => Some(&mut inner.gas_used), - Self::Deneb(inner) => Some(&mut inner.gas_used), + Self::Bellatrix(inner) => &inner.gas_used, + Self::Capella(inner) => &inner.gas_used, + Self::Deneb(inner) => &inner.gas_used, } } - pub fn timestamp(&self) -> Option<&u64> { + pub fn gas_used_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.timestamp), - Self::Capella(inner) => Some(&inner.timestamp), - Self::Deneb(inner) => Some(&inner.timestamp), + Self::Bellatrix(inner) => &mut inner.gas_used, + Self::Capella(inner) => &mut inner.gas_used, + Self::Deneb(inner) => &mut inner.gas_used, } } - pub fn timestamp_mut(&mut self) -> Option<&mut u64> { + pub fn timestamp(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.timestamp), - Self::Capella(inner) => Some(&mut inner.timestamp), - Self::Deneb(inner) => Some(&mut inner.timestamp), + Self::Bellatrix(inner) => &inner.timestamp, + Self::Capella(inner) => &inner.timestamp, + Self::Deneb(inner) => &inner.timestamp, } } - pub fn extra_data(&self) -> Option<&ByteList> { + pub fn timestamp_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.extra_data), - Self::Capella(inner) => Some(&inner.extra_data), - Self::Deneb(inner) => Some(&inner.extra_data), + Self::Bellatrix(inner) => &mut inner.timestamp, + Self::Capella(inner) => &mut inner.timestamp, + Self::Deneb(inner) => &mut inner.timestamp, } } - pub fn extra_data_mut(&mut self) -> Option<&mut ByteList> { + pub fn extra_data(&self) -> &ByteList { match self { - Self::Bellatrix(inner) => Some(&mut inner.extra_data), - Self::Capella(inner) => Some(&mut inner.extra_data), - Self::Deneb(inner) => Some(&mut inner.extra_data), + Self::Bellatrix(inner) => &inner.extra_data, + Self::Capella(inner) => &inner.extra_data, + Self::Deneb(inner) => &inner.extra_data, } } - pub fn base_fee_per_gas(&self) -> Option<&U256> { + pub fn extra_data_mut(&mut self) -> &mut ByteList { match self { - Self::Bellatrix(inner) => Some(&inner.base_fee_per_gas), - Self::Capella(inner) => Some(&inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&inner.base_fee_per_gas), + Self::Bellatrix(inner) => &mut inner.extra_data, + Self::Capella(inner) => &mut inner.extra_data, + Self::Deneb(inner) => &mut inner.extra_data, } } - pub fn base_fee_per_gas_mut(&mut self) -> Option<&mut U256> { + pub fn base_fee_per_gas(&self) -> &U256 { match self { - Self::Bellatrix(inner) => Some(&mut inner.base_fee_per_gas), - Self::Capella(inner) => Some(&mut inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&mut inner.base_fee_per_gas), + Self::Bellatrix(inner) => &inner.base_fee_per_gas, + Self::Capella(inner) => &inner.base_fee_per_gas, + Self::Deneb(inner) => &inner.base_fee_per_gas, } } - pub fn block_hash(&self) -> Option<&Hash32> { + pub fn base_fee_per_gas_mut(&mut self) -> &mut U256 { match self { - Self::Bellatrix(inner) => Some(&inner.block_hash), - Self::Capella(inner) => Some(&inner.block_hash), - Self::Deneb(inner) => Some(&inner.block_hash), + Self::Bellatrix(inner) => &mut inner.base_fee_per_gas, + Self::Capella(inner) => &mut inner.base_fee_per_gas, + Self::Deneb(inner) => &mut inner.base_fee_per_gas, } } - pub fn block_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn block_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_hash), - Self::Capella(inner) => Some(&mut inner.block_hash), - Self::Deneb(inner) => Some(&mut inner.block_hash), + Self::Bellatrix(inner) => &inner.block_hash, + Self::Capella(inner) => &inner.block_hash, + Self::Deneb(inner) => &inner.block_hash, + } + } + pub fn block_hash_mut(&mut self) -> &mut Hash32 { + match self { + Self::Bellatrix(inner) => &mut inner.block_hash, + Self::Capella(inner) => &mut inner.block_hash, + Self::Deneb(inner) => &mut inner.block_hash, } } pub fn transactions( &self, - ) -> Option<&List, MAX_TRANSACTIONS_PER_PAYLOAD>> { + ) -> &List, MAX_TRANSACTIONS_PER_PAYLOAD> { match self { - Self::Bellatrix(inner) => Some(&inner.transactions), - Self::Capella(inner) => Some(&inner.transactions), - Self::Deneb(inner) => Some(&inner.transactions), + Self::Bellatrix(inner) => &inner.transactions, + Self::Capella(inner) => &inner.transactions, + Self::Deneb(inner) => &inner.transactions, } } pub fn transactions_mut( &mut self, - ) -> Option<&mut List, MAX_TRANSACTIONS_PER_PAYLOAD>> - { + ) -> &mut List, MAX_TRANSACTIONS_PER_PAYLOAD> { match self { - Self::Bellatrix(inner) => Some(&mut inner.transactions), - Self::Capella(inner) => Some(&mut inner.transactions), - Self::Deneb(inner) => Some(&mut inner.transactions), + Self::Bellatrix(inner) => &mut inner.transactions, + Self::Capella(inner) => &mut inner.transactions, + Self::Deneb(inner) => &mut inner.transactions, } } pub fn withdrawals(&self) -> Option<&List> { @@ -399,12 +405,13 @@ impl< } } impl< + 'de, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize, const MAX_BYTES_PER_TRANSACTION: usize, const MAX_TRANSACTIONS_PER_PAYLOAD: usize, const MAX_WITHDRAWALS_PER_PAYLOAD: usize, - > serde::Serialize + > serde::Deserialize<'de> for ExecutionPayload< BYTES_PER_LOGS_BLOOM, MAX_EXTRA_DATA_BYTES, @@ -413,15 +420,21 @@ impl< MAX_WITHDRAWALS_PER_PAYLOAD, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -524,104 +537,111 @@ impl< _ => None, } } - pub fn parent_hash(&self) -> Option<&Hash32> { + pub fn version(&self) -> Version { + match self { + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn parent_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.parent_hash), - Self::Capella(inner) => Some(&inner.parent_hash), - Self::Deneb(inner) => Some(&inner.parent_hash), + Self::Bellatrix(inner) => &inner.parent_hash, + Self::Capella(inner) => &inner.parent_hash, + Self::Deneb(inner) => &inner.parent_hash, } } - pub fn fee_recipient(&self) -> Option<&ExecutionAddress> { + pub fn fee_recipient(&self) -> &ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&inner.fee_recipient), - Self::Capella(inner) => Some(&inner.fee_recipient), - Self::Deneb(inner) => Some(&inner.fee_recipient), + Self::Bellatrix(inner) => &inner.fee_recipient, + Self::Capella(inner) => &inner.fee_recipient, + Self::Deneb(inner) => &inner.fee_recipient, } } - pub fn state_root(&self) -> Option<&Bytes32> { + pub fn state_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.state_root), - Self::Capella(inner) => Some(&inner.state_root), - Self::Deneb(inner) => Some(&inner.state_root), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } - pub fn receipts_root(&self) -> Option<&Bytes32> { + pub fn receipts_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.receipts_root), - Self::Capella(inner) => Some(&inner.receipts_root), - Self::Deneb(inner) => Some(&inner.receipts_root), + Self::Bellatrix(inner) => &inner.receipts_root, + Self::Capella(inner) => &inner.receipts_root, + Self::Deneb(inner) => &inner.receipts_root, } } - pub fn logs_bloom(&self) -> Option<&ByteVector> { + pub fn logs_bloom(&self) -> &ByteVector { match self { - Self::Bellatrix(inner) => Some(&inner.logs_bloom), - Self::Capella(inner) => Some(&inner.logs_bloom), - Self::Deneb(inner) => Some(&inner.logs_bloom), + Self::Bellatrix(inner) => &inner.logs_bloom, + Self::Capella(inner) => &inner.logs_bloom, + Self::Deneb(inner) => &inner.logs_bloom, } } - pub fn prev_randao(&self) -> Option<&Bytes32> { + pub fn prev_randao(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.prev_randao), - Self::Capella(inner) => Some(&inner.prev_randao), - Self::Deneb(inner) => Some(&inner.prev_randao), + Self::Bellatrix(inner) => &inner.prev_randao, + Self::Capella(inner) => &inner.prev_randao, + Self::Deneb(inner) => &inner.prev_randao, } } - pub fn block_number(&self) -> Option<&u64> { + pub fn block_number(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.block_number), - Self::Capella(inner) => Some(&inner.block_number), - Self::Deneb(inner) => Some(&inner.block_number), + Self::Bellatrix(inner) => &inner.block_number, + Self::Capella(inner) => &inner.block_number, + Self::Deneb(inner) => &inner.block_number, } } - pub fn gas_limit(&self) -> Option<&u64> { + pub fn gas_limit(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_limit), - Self::Capella(inner) => Some(&inner.gas_limit), - Self::Deneb(inner) => Some(&inner.gas_limit), + Self::Bellatrix(inner) => &inner.gas_limit, + Self::Capella(inner) => &inner.gas_limit, + Self::Deneb(inner) => &inner.gas_limit, } } - pub fn gas_used(&self) -> Option<&u64> { + pub fn gas_used(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_used), - Self::Capella(inner) => Some(&inner.gas_used), - Self::Deneb(inner) => Some(&inner.gas_used), + Self::Bellatrix(inner) => &inner.gas_used, + Self::Capella(inner) => &inner.gas_used, + Self::Deneb(inner) => &inner.gas_used, } } - pub fn timestamp(&self) -> Option<&u64> { + pub fn timestamp(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.timestamp), - Self::Capella(inner) => Some(&inner.timestamp), - Self::Deneb(inner) => Some(&inner.timestamp), + Self::Bellatrix(inner) => &inner.timestamp, + Self::Capella(inner) => &inner.timestamp, + Self::Deneb(inner) => &inner.timestamp, } } - pub fn extra_data(&self) -> Option<&ByteList> { + pub fn extra_data(&self) -> &ByteList { match self { - Self::Bellatrix(inner) => Some(&inner.extra_data), - Self::Capella(inner) => Some(&inner.extra_data), - Self::Deneb(inner) => Some(&inner.extra_data), + Self::Bellatrix(inner) => &inner.extra_data, + Self::Capella(inner) => &inner.extra_data, + Self::Deneb(inner) => &inner.extra_data, } } - pub fn base_fee_per_gas(&self) -> Option<&U256> { + pub fn base_fee_per_gas(&self) -> &U256 { match self { - Self::Bellatrix(inner) => Some(&inner.base_fee_per_gas), - Self::Capella(inner) => Some(&inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&inner.base_fee_per_gas), + Self::Bellatrix(inner) => &inner.base_fee_per_gas, + Self::Capella(inner) => &inner.base_fee_per_gas, + Self::Deneb(inner) => &inner.base_fee_per_gas, } } - pub fn block_hash(&self) -> Option<&Hash32> { + pub fn block_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.block_hash), - Self::Capella(inner) => Some(&inner.block_hash), - Self::Deneb(inner) => Some(&inner.block_hash), + Self::Bellatrix(inner) => &inner.block_hash, + Self::Capella(inner) => &inner.block_hash, + Self::Deneb(inner) => &inner.block_hash, } } pub fn transactions( &self, - ) -> Option<&List, MAX_TRANSACTIONS_PER_PAYLOAD>> { + ) -> &List, MAX_TRANSACTIONS_PER_PAYLOAD> { match self { - Self::Bellatrix(inner) => Some(&inner.transactions), - Self::Capella(inner) => Some(&inner.transactions), - Self::Deneb(inner) => Some(&inner.transactions), + Self::Bellatrix(inner) => &inner.transactions, + Self::Capella(inner) => &inner.transactions, + Self::Deneb(inner) => &inner.transactions, } } pub fn withdrawals(&self) -> Option<&List> { @@ -758,7 +778,8 @@ impl< Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum ExecutionPayloadRefMut< 'a, const BYTES_PER_LOGS_BLOOM: usize, @@ -811,6 +832,21 @@ impl< MAX_WITHDRAWALS_PER_PAYLOAD, > { + pub fn bellatrix( + &self, + ) -> Option< + &bellatrix::ExecutionPayload< + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + >, + > { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option< @@ -826,6 +862,22 @@ impl< _ => None, } } + pub fn capella( + &self, + ) -> Option< + &capella::ExecutionPayload< + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + >, + > { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option< @@ -842,6 +894,22 @@ impl< _ => None, } } + pub fn deneb( + &self, + ) -> Option< + &deneb::ExecutionPayload< + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + >, + > { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option< @@ -858,105 +926,218 @@ impl< _ => None, } } - pub fn parent_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn version(&self) -> Version { + match self { + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn parent_hash(&self) -> &Hash32 { + match self { + Self::Bellatrix(inner) => &inner.parent_hash, + Self::Capella(inner) => &inner.parent_hash, + Self::Deneb(inner) => &inner.parent_hash, + } + } + pub fn parent_hash_mut(&mut self) -> &mut Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.parent_hash), - Self::Capella(inner) => Some(&mut inner.parent_hash), - Self::Deneb(inner) => Some(&mut inner.parent_hash), + Self::Bellatrix(inner) => &mut inner.parent_hash, + Self::Capella(inner) => &mut inner.parent_hash, + Self::Deneb(inner) => &mut inner.parent_hash, } } - pub fn fee_recipient_mut(&mut self) -> Option<&mut ExecutionAddress> { + pub fn fee_recipient(&self) -> &ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&mut inner.fee_recipient), - Self::Capella(inner) => Some(&mut inner.fee_recipient), - Self::Deneb(inner) => Some(&mut inner.fee_recipient), + Self::Bellatrix(inner) => &inner.fee_recipient, + Self::Capella(inner) => &inner.fee_recipient, + Self::Deneb(inner) => &inner.fee_recipient, } } - pub fn state_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn fee_recipient_mut(&mut self) -> &mut ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&mut inner.state_root), - Self::Capella(inner) => Some(&mut inner.state_root), - Self::Deneb(inner) => Some(&mut inner.state_root), + Self::Bellatrix(inner) => &mut inner.fee_recipient, + Self::Capella(inner) => &mut inner.fee_recipient, + Self::Deneb(inner) => &mut inner.fee_recipient, } } - pub fn receipts_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn state_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.receipts_root), - Self::Capella(inner) => Some(&mut inner.receipts_root), - Self::Deneb(inner) => Some(&mut inner.receipts_root), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } - pub fn logs_bloom_mut(&mut self) -> Option<&mut ByteVector> { + pub fn state_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.logs_bloom), - Self::Capella(inner) => Some(&mut inner.logs_bloom), - Self::Deneb(inner) => Some(&mut inner.logs_bloom), + Self::Bellatrix(inner) => &mut inner.state_root, + Self::Capella(inner) => &mut inner.state_root, + Self::Deneb(inner) => &mut inner.state_root, } } - pub fn prev_randao_mut(&mut self) -> Option<&mut Bytes32> { + pub fn receipts_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.prev_randao), - Self::Capella(inner) => Some(&mut inner.prev_randao), - Self::Deneb(inner) => Some(&mut inner.prev_randao), + Self::Bellatrix(inner) => &inner.receipts_root, + Self::Capella(inner) => &inner.receipts_root, + Self::Deneb(inner) => &inner.receipts_root, } } - pub fn block_number_mut(&mut self) -> Option<&mut u64> { + pub fn receipts_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_number), - Self::Capella(inner) => Some(&mut inner.block_number), - Self::Deneb(inner) => Some(&mut inner.block_number), + Self::Bellatrix(inner) => &mut inner.receipts_root, + Self::Capella(inner) => &mut inner.receipts_root, + Self::Deneb(inner) => &mut inner.receipts_root, } } - pub fn gas_limit_mut(&mut self) -> Option<&mut u64> { + pub fn logs_bloom(&self) -> &ByteVector { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_limit), - Self::Capella(inner) => Some(&mut inner.gas_limit), - Self::Deneb(inner) => Some(&mut inner.gas_limit), + Self::Bellatrix(inner) => &inner.logs_bloom, + Self::Capella(inner) => &inner.logs_bloom, + Self::Deneb(inner) => &inner.logs_bloom, } } - pub fn gas_used_mut(&mut self) -> Option<&mut u64> { + pub fn logs_bloom_mut(&mut self) -> &mut ByteVector { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_used), - Self::Capella(inner) => Some(&mut inner.gas_used), - Self::Deneb(inner) => Some(&mut inner.gas_used), + Self::Bellatrix(inner) => &mut inner.logs_bloom, + Self::Capella(inner) => &mut inner.logs_bloom, + Self::Deneb(inner) => &mut inner.logs_bloom, } } - pub fn timestamp_mut(&mut self) -> Option<&mut u64> { + pub fn prev_randao(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.timestamp), - Self::Capella(inner) => Some(&mut inner.timestamp), - Self::Deneb(inner) => Some(&mut inner.timestamp), + Self::Bellatrix(inner) => &inner.prev_randao, + Self::Capella(inner) => &inner.prev_randao, + Self::Deneb(inner) => &inner.prev_randao, } } - pub fn extra_data_mut(&mut self) -> Option<&mut ByteList> { + pub fn prev_randao_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.extra_data), - Self::Capella(inner) => Some(&mut inner.extra_data), - Self::Deneb(inner) => Some(&mut inner.extra_data), + Self::Bellatrix(inner) => &mut inner.prev_randao, + Self::Capella(inner) => &mut inner.prev_randao, + Self::Deneb(inner) => &mut inner.prev_randao, } } - pub fn base_fee_per_gas_mut(&mut self) -> Option<&mut U256> { + pub fn block_number(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.base_fee_per_gas), - Self::Capella(inner) => Some(&mut inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&mut inner.base_fee_per_gas), + Self::Bellatrix(inner) => &inner.block_number, + Self::Capella(inner) => &inner.block_number, + Self::Deneb(inner) => &inner.block_number, } } - pub fn block_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn block_number_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_hash), - Self::Capella(inner) => Some(&mut inner.block_hash), - Self::Deneb(inner) => Some(&mut inner.block_hash), + Self::Bellatrix(inner) => &mut inner.block_number, + Self::Capella(inner) => &mut inner.block_number, + Self::Deneb(inner) => &mut inner.block_number, + } + } + pub fn gas_limit(&self) -> &u64 { + match self { + Self::Bellatrix(inner) => &inner.gas_limit, + Self::Capella(inner) => &inner.gas_limit, + Self::Deneb(inner) => &inner.gas_limit, + } + } + pub fn gas_limit_mut(&mut self) -> &mut u64 { + match self { + Self::Bellatrix(inner) => &mut inner.gas_limit, + Self::Capella(inner) => &mut inner.gas_limit, + Self::Deneb(inner) => &mut inner.gas_limit, + } + } + pub fn gas_used(&self) -> &u64 { + match self { + Self::Bellatrix(inner) => &inner.gas_used, + Self::Capella(inner) => &inner.gas_used, + Self::Deneb(inner) => &inner.gas_used, + } + } + pub fn gas_used_mut(&mut self) -> &mut u64 { + match self { + Self::Bellatrix(inner) => &mut inner.gas_used, + Self::Capella(inner) => &mut inner.gas_used, + Self::Deneb(inner) => &mut inner.gas_used, + } + } + pub fn timestamp(&self) -> &u64 { + match self { + Self::Bellatrix(inner) => &inner.timestamp, + Self::Capella(inner) => &inner.timestamp, + Self::Deneb(inner) => &inner.timestamp, + } + } + pub fn timestamp_mut(&mut self) -> &mut u64 { + match self { + Self::Bellatrix(inner) => &mut inner.timestamp, + Self::Capella(inner) => &mut inner.timestamp, + Self::Deneb(inner) => &mut inner.timestamp, + } + } + pub fn extra_data(&self) -> &ByteList { + match self { + Self::Bellatrix(inner) => &inner.extra_data, + Self::Capella(inner) => &inner.extra_data, + Self::Deneb(inner) => &inner.extra_data, + } + } + pub fn extra_data_mut(&mut self) -> &mut ByteList { + match self { + Self::Bellatrix(inner) => &mut inner.extra_data, + Self::Capella(inner) => &mut inner.extra_data, + Self::Deneb(inner) => &mut inner.extra_data, + } + } + pub fn base_fee_per_gas(&self) -> &U256 { + match self { + Self::Bellatrix(inner) => &inner.base_fee_per_gas, + Self::Capella(inner) => &inner.base_fee_per_gas, + Self::Deneb(inner) => &inner.base_fee_per_gas, + } + } + pub fn base_fee_per_gas_mut(&mut self) -> &mut U256 { + match self { + Self::Bellatrix(inner) => &mut inner.base_fee_per_gas, + Self::Capella(inner) => &mut inner.base_fee_per_gas, + Self::Deneb(inner) => &mut inner.base_fee_per_gas, + } + } + pub fn block_hash(&self) -> &Hash32 { + match self { + Self::Bellatrix(inner) => &inner.block_hash, + Self::Capella(inner) => &inner.block_hash, + Self::Deneb(inner) => &inner.block_hash, + } + } + pub fn block_hash_mut(&mut self) -> &mut Hash32 { + match self { + Self::Bellatrix(inner) => &mut inner.block_hash, + Self::Capella(inner) => &mut inner.block_hash, + Self::Deneb(inner) => &mut inner.block_hash, + } + } + pub fn transactions( + &self, + ) -> &List, MAX_TRANSACTIONS_PER_PAYLOAD> { + match self { + Self::Bellatrix(inner) => &inner.transactions, + Self::Capella(inner) => &inner.transactions, + Self::Deneb(inner) => &inner.transactions, } } pub fn transactions_mut( &mut self, - ) -> Option<&mut List, MAX_TRANSACTIONS_PER_PAYLOAD>> - { + ) -> &mut List, MAX_TRANSACTIONS_PER_PAYLOAD> { match self { - Self::Bellatrix(inner) => Some(&mut inner.transactions), - Self::Capella(inner) => Some(&mut inner.transactions), - Self::Deneb(inner) => Some(&mut inner.transactions), + Self::Bellatrix(inner) => &mut inner.transactions, + Self::Capella(inner) => &mut inner.transactions, + Self::Deneb(inner) => &mut inner.transactions, + } + } + pub fn withdrawals(&self) -> Option<&List> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.withdrawals), + Self::Deneb(inner) => Some(&inner.withdrawals), } } pub fn withdrawals_mut( @@ -968,6 +1149,13 @@ impl< Self::Deneb(inner) => Some(&mut inner.withdrawals), } } + pub fn blob_gas_used(&self) -> Option<&u64> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(inner) => Some(&inner.blob_gas_used), + } + } pub fn blob_gas_used_mut(&mut self) -> Option<&mut u64> { match self { Self::Bellatrix(_) => None, @@ -975,6 +1163,13 @@ impl< Self::Deneb(inner) => Some(&mut inner.blob_gas_used), } } + pub fn excess_blob_gas(&self) -> Option<&u64> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(inner) => Some(&inner.excess_blob_gas), + } + } pub fn excess_blob_gas_mut(&mut self) -> Option<&mut u64> { match self { Self::Bellatrix(_) => None, diff --git a/ethereum-consensus/src/types/execution_payload_header.rs b/ethereum-consensus/src/types/execution_payload_header.rs index 3da161089..f429b92c2 100644 --- a/ethereum-consensus/src/types/execution_payload_header.rs +++ b/ethereum-consensus/src/types/execution_payload_header.rs @@ -5,10 +5,10 @@ use crate::{ deneb::execution_payload as deneb, primitives::{Bytes32, ExecutionAddress, Hash32, Root}, ssz::prelude::*, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum ExecutionPayloadHeader< const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize, @@ -72,200 +72,207 @@ impl _ => None, } } - pub fn parent_hash(&self) -> Option<&Hash32> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.parent_hash), - Self::Capella(inner) => Some(&inner.parent_hash), - Self::Deneb(inner) => Some(&inner.parent_hash), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn parent_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn parent_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.parent_hash), - Self::Capella(inner) => Some(&mut inner.parent_hash), - Self::Deneb(inner) => Some(&mut inner.parent_hash), + Self::Bellatrix(inner) => &inner.parent_hash, + Self::Capella(inner) => &inner.parent_hash, + Self::Deneb(inner) => &inner.parent_hash, } } - pub fn fee_recipient(&self) -> Option<&ExecutionAddress> { + pub fn parent_hash_mut(&mut self) -> &mut Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.fee_recipient), - Self::Capella(inner) => Some(&inner.fee_recipient), - Self::Deneb(inner) => Some(&inner.fee_recipient), + Self::Bellatrix(inner) => &mut inner.parent_hash, + Self::Capella(inner) => &mut inner.parent_hash, + Self::Deneb(inner) => &mut inner.parent_hash, } } - pub fn fee_recipient_mut(&mut self) -> Option<&mut ExecutionAddress> { + pub fn fee_recipient(&self) -> &ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&mut inner.fee_recipient), - Self::Capella(inner) => Some(&mut inner.fee_recipient), - Self::Deneb(inner) => Some(&mut inner.fee_recipient), + Self::Bellatrix(inner) => &inner.fee_recipient, + Self::Capella(inner) => &inner.fee_recipient, + Self::Deneb(inner) => &inner.fee_recipient, } } - pub fn state_root(&self) -> Option<&Bytes32> { + pub fn fee_recipient_mut(&mut self) -> &mut ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&inner.state_root), - Self::Capella(inner) => Some(&inner.state_root), - Self::Deneb(inner) => Some(&inner.state_root), + Self::Bellatrix(inner) => &mut inner.fee_recipient, + Self::Capella(inner) => &mut inner.fee_recipient, + Self::Deneb(inner) => &mut inner.fee_recipient, } } - pub fn state_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn state_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.state_root), - Self::Capella(inner) => Some(&mut inner.state_root), - Self::Deneb(inner) => Some(&mut inner.state_root), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } - pub fn receipts_root(&self) -> Option<&Bytes32> { + pub fn state_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.receipts_root), - Self::Capella(inner) => Some(&inner.receipts_root), - Self::Deneb(inner) => Some(&inner.receipts_root), + Self::Bellatrix(inner) => &mut inner.state_root, + Self::Capella(inner) => &mut inner.state_root, + Self::Deneb(inner) => &mut inner.state_root, } } - pub fn receipts_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn receipts_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.receipts_root), - Self::Capella(inner) => Some(&mut inner.receipts_root), - Self::Deneb(inner) => Some(&mut inner.receipts_root), + Self::Bellatrix(inner) => &inner.receipts_root, + Self::Capella(inner) => &inner.receipts_root, + Self::Deneb(inner) => &inner.receipts_root, } } - pub fn logs_bloom(&self) -> Option<&ByteVector> { + pub fn receipts_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.logs_bloom), - Self::Capella(inner) => Some(&inner.logs_bloom), - Self::Deneb(inner) => Some(&inner.logs_bloom), + Self::Bellatrix(inner) => &mut inner.receipts_root, + Self::Capella(inner) => &mut inner.receipts_root, + Self::Deneb(inner) => &mut inner.receipts_root, } } - pub fn logs_bloom_mut(&mut self) -> Option<&mut ByteVector> { + pub fn logs_bloom(&self) -> &ByteVector { match self { - Self::Bellatrix(inner) => Some(&mut inner.logs_bloom), - Self::Capella(inner) => Some(&mut inner.logs_bloom), - Self::Deneb(inner) => Some(&mut inner.logs_bloom), + Self::Bellatrix(inner) => &inner.logs_bloom, + Self::Capella(inner) => &inner.logs_bloom, + Self::Deneb(inner) => &inner.logs_bloom, } } - pub fn prev_randao(&self) -> Option<&Bytes32> { + pub fn logs_bloom_mut(&mut self) -> &mut ByteVector { match self { - Self::Bellatrix(inner) => Some(&inner.prev_randao), - Self::Capella(inner) => Some(&inner.prev_randao), - Self::Deneb(inner) => Some(&inner.prev_randao), + Self::Bellatrix(inner) => &mut inner.logs_bloom, + Self::Capella(inner) => &mut inner.logs_bloom, + Self::Deneb(inner) => &mut inner.logs_bloom, } } - pub fn prev_randao_mut(&mut self) -> Option<&mut Bytes32> { + pub fn prev_randao(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.prev_randao), - Self::Capella(inner) => Some(&mut inner.prev_randao), - Self::Deneb(inner) => Some(&mut inner.prev_randao), + Self::Bellatrix(inner) => &inner.prev_randao, + Self::Capella(inner) => &inner.prev_randao, + Self::Deneb(inner) => &inner.prev_randao, } } - pub fn block_number(&self) -> Option<&u64> { + pub fn prev_randao_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.block_number), - Self::Capella(inner) => Some(&inner.block_number), - Self::Deneb(inner) => Some(&inner.block_number), + Self::Bellatrix(inner) => &mut inner.prev_randao, + Self::Capella(inner) => &mut inner.prev_randao, + Self::Deneb(inner) => &mut inner.prev_randao, } } - pub fn block_number_mut(&mut self) -> Option<&mut u64> { + pub fn block_number(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_number), - Self::Capella(inner) => Some(&mut inner.block_number), - Self::Deneb(inner) => Some(&mut inner.block_number), + Self::Bellatrix(inner) => &inner.block_number, + Self::Capella(inner) => &inner.block_number, + Self::Deneb(inner) => &inner.block_number, } } - pub fn gas_limit(&self) -> Option<&u64> { + pub fn block_number_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_limit), - Self::Capella(inner) => Some(&inner.gas_limit), - Self::Deneb(inner) => Some(&inner.gas_limit), + Self::Bellatrix(inner) => &mut inner.block_number, + Self::Capella(inner) => &mut inner.block_number, + Self::Deneb(inner) => &mut inner.block_number, } } - pub fn gas_limit_mut(&mut self) -> Option<&mut u64> { + pub fn gas_limit(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_limit), - Self::Capella(inner) => Some(&mut inner.gas_limit), - Self::Deneb(inner) => Some(&mut inner.gas_limit), + Self::Bellatrix(inner) => &inner.gas_limit, + Self::Capella(inner) => &inner.gas_limit, + Self::Deneb(inner) => &inner.gas_limit, } } - pub fn gas_used(&self) -> Option<&u64> { + pub fn gas_limit_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_used), - Self::Capella(inner) => Some(&inner.gas_used), - Self::Deneb(inner) => Some(&inner.gas_used), + Self::Bellatrix(inner) => &mut inner.gas_limit, + Self::Capella(inner) => &mut inner.gas_limit, + Self::Deneb(inner) => &mut inner.gas_limit, } } - pub fn gas_used_mut(&mut self) -> Option<&mut u64> { + pub fn gas_used(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_used), - Self::Capella(inner) => Some(&mut inner.gas_used), - Self::Deneb(inner) => Some(&mut inner.gas_used), + Self::Bellatrix(inner) => &inner.gas_used, + Self::Capella(inner) => &inner.gas_used, + Self::Deneb(inner) => &inner.gas_used, } } - pub fn timestamp(&self) -> Option<&u64> { + pub fn gas_used_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.timestamp), - Self::Capella(inner) => Some(&inner.timestamp), - Self::Deneb(inner) => Some(&inner.timestamp), + Self::Bellatrix(inner) => &mut inner.gas_used, + Self::Capella(inner) => &mut inner.gas_used, + Self::Deneb(inner) => &mut inner.gas_used, } } - pub fn timestamp_mut(&mut self) -> Option<&mut u64> { + pub fn timestamp(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.timestamp), - Self::Capella(inner) => Some(&mut inner.timestamp), - Self::Deneb(inner) => Some(&mut inner.timestamp), + Self::Bellatrix(inner) => &inner.timestamp, + Self::Capella(inner) => &inner.timestamp, + Self::Deneb(inner) => &inner.timestamp, } } - pub fn extra_data(&self) -> Option<&ByteList> { + pub fn timestamp_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&inner.extra_data), - Self::Capella(inner) => Some(&inner.extra_data), - Self::Deneb(inner) => Some(&inner.extra_data), + Self::Bellatrix(inner) => &mut inner.timestamp, + Self::Capella(inner) => &mut inner.timestamp, + Self::Deneb(inner) => &mut inner.timestamp, } } - pub fn extra_data_mut(&mut self) -> Option<&mut ByteList> { + pub fn extra_data(&self) -> &ByteList { match self { - Self::Bellatrix(inner) => Some(&mut inner.extra_data), - Self::Capella(inner) => Some(&mut inner.extra_data), - Self::Deneb(inner) => Some(&mut inner.extra_data), + Self::Bellatrix(inner) => &inner.extra_data, + Self::Capella(inner) => &inner.extra_data, + Self::Deneb(inner) => &inner.extra_data, } } - pub fn base_fee_per_gas(&self) -> Option<&U256> { + pub fn extra_data_mut(&mut self) -> &mut ByteList { match self { - Self::Bellatrix(inner) => Some(&inner.base_fee_per_gas), - Self::Capella(inner) => Some(&inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&inner.base_fee_per_gas), + Self::Bellatrix(inner) => &mut inner.extra_data, + Self::Capella(inner) => &mut inner.extra_data, + Self::Deneb(inner) => &mut inner.extra_data, } } - pub fn base_fee_per_gas_mut(&mut self) -> Option<&mut U256> { + pub fn base_fee_per_gas(&self) -> &U256 { match self { - Self::Bellatrix(inner) => Some(&mut inner.base_fee_per_gas), - Self::Capella(inner) => Some(&mut inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&mut inner.base_fee_per_gas), + Self::Bellatrix(inner) => &inner.base_fee_per_gas, + Self::Capella(inner) => &inner.base_fee_per_gas, + Self::Deneb(inner) => &inner.base_fee_per_gas, } } - pub fn block_hash(&self) -> Option<&Hash32> { + pub fn base_fee_per_gas_mut(&mut self) -> &mut U256 { match self { - Self::Bellatrix(inner) => Some(&inner.block_hash), - Self::Capella(inner) => Some(&inner.block_hash), - Self::Deneb(inner) => Some(&inner.block_hash), + Self::Bellatrix(inner) => &mut inner.base_fee_per_gas, + Self::Capella(inner) => &mut inner.base_fee_per_gas, + Self::Deneb(inner) => &mut inner.base_fee_per_gas, } } - pub fn block_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn block_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_hash), - Self::Capella(inner) => Some(&mut inner.block_hash), - Self::Deneb(inner) => Some(&mut inner.block_hash), + Self::Bellatrix(inner) => &inner.block_hash, + Self::Capella(inner) => &inner.block_hash, + Self::Deneb(inner) => &inner.block_hash, } } - pub fn transactions_root(&self) -> Option<&Root> { + pub fn block_hash_mut(&mut self) -> &mut Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.transactions_root), - Self::Capella(inner) => Some(&inner.transactions_root), - Self::Deneb(inner) => Some(&inner.transactions_root), + Self::Bellatrix(inner) => &mut inner.block_hash, + Self::Capella(inner) => &mut inner.block_hash, + Self::Deneb(inner) => &mut inner.block_hash, } } - pub fn transactions_root_mut(&mut self) -> Option<&mut Root> { + pub fn transactions_root(&self) -> &Root { match self { - Self::Bellatrix(inner) => Some(&mut inner.transactions_root), - Self::Capella(inner) => Some(&mut inner.transactions_root), - Self::Deneb(inner) => Some(&mut inner.transactions_root), + Self::Bellatrix(inner) => &inner.transactions_root, + Self::Capella(inner) => &inner.transactions_root, + Self::Deneb(inner) => &inner.transactions_root, + } + } + pub fn transactions_root_mut(&mut self) -> &mut Root { + match self { + Self::Bellatrix(inner) => &mut inner.transactions_root, + Self::Capella(inner) => &mut inner.transactions_root, + Self::Deneb(inner) => &mut inner.transactions_root, } } pub fn withdrawals_root(&self) -> Option<&Root> { @@ -311,18 +318,24 @@ impl } } } -impl serde::Serialize - for ExecutionPayloadHeader +impl<'de, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> + serde::Deserialize<'de> for ExecutionPayloadHeader { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } #[derive(Debug, PartialEq, Eq)] @@ -363,102 +376,109 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> _ => None, } } - pub fn parent_hash(&self) -> Option<&Hash32> { + pub fn version(&self) -> Version { match self { - Self::Bellatrix(inner) => Some(&inner.parent_hash), - Self::Capella(inner) => Some(&inner.parent_hash), - Self::Deneb(inner) => Some(&inner.parent_hash), + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, } } - pub fn fee_recipient(&self) -> Option<&ExecutionAddress> { + pub fn parent_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.fee_recipient), - Self::Capella(inner) => Some(&inner.fee_recipient), - Self::Deneb(inner) => Some(&inner.fee_recipient), + Self::Bellatrix(inner) => &inner.parent_hash, + Self::Capella(inner) => &inner.parent_hash, + Self::Deneb(inner) => &inner.parent_hash, } } - pub fn state_root(&self) -> Option<&Bytes32> { + pub fn fee_recipient(&self) -> &ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&inner.state_root), - Self::Capella(inner) => Some(&inner.state_root), - Self::Deneb(inner) => Some(&inner.state_root), + Self::Bellatrix(inner) => &inner.fee_recipient, + Self::Capella(inner) => &inner.fee_recipient, + Self::Deneb(inner) => &inner.fee_recipient, } } - pub fn receipts_root(&self) -> Option<&Bytes32> { + pub fn state_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.receipts_root), - Self::Capella(inner) => Some(&inner.receipts_root), - Self::Deneb(inner) => Some(&inner.receipts_root), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } - pub fn logs_bloom(&self) -> Option<&ByteVector> { + pub fn receipts_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.logs_bloom), - Self::Capella(inner) => Some(&inner.logs_bloom), - Self::Deneb(inner) => Some(&inner.logs_bloom), + Self::Bellatrix(inner) => &inner.receipts_root, + Self::Capella(inner) => &inner.receipts_root, + Self::Deneb(inner) => &inner.receipts_root, } } - pub fn prev_randao(&self) -> Option<&Bytes32> { + pub fn logs_bloom(&self) -> &ByteVector { match self { - Self::Bellatrix(inner) => Some(&inner.prev_randao), - Self::Capella(inner) => Some(&inner.prev_randao), - Self::Deneb(inner) => Some(&inner.prev_randao), + Self::Bellatrix(inner) => &inner.logs_bloom, + Self::Capella(inner) => &inner.logs_bloom, + Self::Deneb(inner) => &inner.logs_bloom, } } - pub fn block_number(&self) -> Option<&u64> { + pub fn prev_randao(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&inner.block_number), - Self::Capella(inner) => Some(&inner.block_number), - Self::Deneb(inner) => Some(&inner.block_number), + Self::Bellatrix(inner) => &inner.prev_randao, + Self::Capella(inner) => &inner.prev_randao, + Self::Deneb(inner) => &inner.prev_randao, } } - pub fn gas_limit(&self) -> Option<&u64> { + pub fn block_number(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_limit), - Self::Capella(inner) => Some(&inner.gas_limit), - Self::Deneb(inner) => Some(&inner.gas_limit), + Self::Bellatrix(inner) => &inner.block_number, + Self::Capella(inner) => &inner.block_number, + Self::Deneb(inner) => &inner.block_number, } } - pub fn gas_used(&self) -> Option<&u64> { + pub fn gas_limit(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.gas_used), - Self::Capella(inner) => Some(&inner.gas_used), - Self::Deneb(inner) => Some(&inner.gas_used), + Self::Bellatrix(inner) => &inner.gas_limit, + Self::Capella(inner) => &inner.gas_limit, + Self::Deneb(inner) => &inner.gas_limit, } } - pub fn timestamp(&self) -> Option<&u64> { + pub fn gas_used(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.timestamp), - Self::Capella(inner) => Some(&inner.timestamp), - Self::Deneb(inner) => Some(&inner.timestamp), + Self::Bellatrix(inner) => &inner.gas_used, + Self::Capella(inner) => &inner.gas_used, + Self::Deneb(inner) => &inner.gas_used, } } - pub fn extra_data(&self) -> Option<&ByteList> { + pub fn timestamp(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&inner.extra_data), - Self::Capella(inner) => Some(&inner.extra_data), - Self::Deneb(inner) => Some(&inner.extra_data), + Self::Bellatrix(inner) => &inner.timestamp, + Self::Capella(inner) => &inner.timestamp, + Self::Deneb(inner) => &inner.timestamp, } } - pub fn base_fee_per_gas(&self) -> Option<&U256> { + pub fn extra_data(&self) -> &ByteList { match self { - Self::Bellatrix(inner) => Some(&inner.base_fee_per_gas), - Self::Capella(inner) => Some(&inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&inner.base_fee_per_gas), + Self::Bellatrix(inner) => &inner.extra_data, + Self::Capella(inner) => &inner.extra_data, + Self::Deneb(inner) => &inner.extra_data, } } - pub fn block_hash(&self) -> Option<&Hash32> { + pub fn base_fee_per_gas(&self) -> &U256 { match self { - Self::Bellatrix(inner) => Some(&inner.block_hash), - Self::Capella(inner) => Some(&inner.block_hash), - Self::Deneb(inner) => Some(&inner.block_hash), + Self::Bellatrix(inner) => &inner.base_fee_per_gas, + Self::Capella(inner) => &inner.base_fee_per_gas, + Self::Deneb(inner) => &inner.base_fee_per_gas, } } - pub fn transactions_root(&self) -> Option<&Root> { + pub fn block_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&inner.transactions_root), - Self::Capella(inner) => Some(&inner.transactions_root), - Self::Deneb(inner) => Some(&inner.transactions_root), + Self::Bellatrix(inner) => &inner.block_hash, + Self::Capella(inner) => &inner.block_hash, + Self::Deneb(inner) => &inner.block_hash, + } + } + pub fn transactions_root(&self) -> &Root { + match self { + Self::Bellatrix(inner) => &inner.transactions_root, + Self::Capella(inner) => &inner.transactions_root, + Self::Deneb(inner) => &inner.transactions_root, } } pub fn withdrawals_root(&self) -> Option<&Root> { @@ -513,7 +533,8 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> Self::Deneb(value) } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Merkleized)] +#[ssz(transparent)] pub enum ExecutionPayloadHeaderRefMut< 'a, const BYTES_PER_LOGS_BLOOM: usize, @@ -528,6 +549,15 @@ pub enum ExecutionPayloadHeaderRefMut< impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> ExecutionPayloadHeaderRefMut<'a, BYTES_PER_LOGS_BLOOM, MAX_EXTRA_DATA_BYTES> { + pub fn bellatrix( + &self, + ) -> Option<&bellatrix::ExecutionPayloadHeader> + { + match self { + Self::Bellatrix(inner) => Some(inner), + _ => None, + } + } pub fn bellatrix_mut( &mut self, ) -> Option<&mut bellatrix::ExecutionPayloadHeader> @@ -537,6 +567,14 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> _ => None, } } + pub fn capella( + &self, + ) -> Option<&capella::ExecutionPayloadHeader> { + match self { + Self::Capella(inner) => Some(inner), + _ => None, + } + } pub fn capella_mut( &mut self, ) -> Option<&mut capella::ExecutionPayloadHeader> @@ -546,6 +584,14 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> _ => None, } } + pub fn deneb( + &self, + ) -> Option<&deneb::ExecutionPayloadHeader> { + match self { + Self::Deneb(inner) => Some(inner), + _ => None, + } + } pub fn deneb_mut( &mut self, ) -> Option<&mut deneb::ExecutionPayloadHeader> @@ -555,102 +601,214 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> _ => None, } } - pub fn parent_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn version(&self) -> Version { + match self { + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } + pub fn parent_hash(&self) -> &Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.parent_hash), - Self::Capella(inner) => Some(&mut inner.parent_hash), - Self::Deneb(inner) => Some(&mut inner.parent_hash), + Self::Bellatrix(inner) => &inner.parent_hash, + Self::Capella(inner) => &inner.parent_hash, + Self::Deneb(inner) => &inner.parent_hash, } } - pub fn fee_recipient_mut(&mut self) -> Option<&mut ExecutionAddress> { + pub fn parent_hash_mut(&mut self) -> &mut Hash32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.fee_recipient), - Self::Capella(inner) => Some(&mut inner.fee_recipient), - Self::Deneb(inner) => Some(&mut inner.fee_recipient), + Self::Bellatrix(inner) => &mut inner.parent_hash, + Self::Capella(inner) => &mut inner.parent_hash, + Self::Deneb(inner) => &mut inner.parent_hash, } } - pub fn state_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn fee_recipient(&self) -> &ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&mut inner.state_root), - Self::Capella(inner) => Some(&mut inner.state_root), - Self::Deneb(inner) => Some(&mut inner.state_root), + Self::Bellatrix(inner) => &inner.fee_recipient, + Self::Capella(inner) => &inner.fee_recipient, + Self::Deneb(inner) => &inner.fee_recipient, } } - pub fn receipts_root_mut(&mut self) -> Option<&mut Bytes32> { + pub fn fee_recipient_mut(&mut self) -> &mut ExecutionAddress { match self { - Self::Bellatrix(inner) => Some(&mut inner.receipts_root), - Self::Capella(inner) => Some(&mut inner.receipts_root), - Self::Deneb(inner) => Some(&mut inner.receipts_root), + Self::Bellatrix(inner) => &mut inner.fee_recipient, + Self::Capella(inner) => &mut inner.fee_recipient, + Self::Deneb(inner) => &mut inner.fee_recipient, } } - pub fn logs_bloom_mut(&mut self) -> Option<&mut ByteVector> { + pub fn state_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.logs_bloom), - Self::Capella(inner) => Some(&mut inner.logs_bloom), - Self::Deneb(inner) => Some(&mut inner.logs_bloom), + Self::Bellatrix(inner) => &inner.state_root, + Self::Capella(inner) => &inner.state_root, + Self::Deneb(inner) => &inner.state_root, } } - pub fn prev_randao_mut(&mut self) -> Option<&mut Bytes32> { + pub fn state_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.prev_randao), - Self::Capella(inner) => Some(&mut inner.prev_randao), - Self::Deneb(inner) => Some(&mut inner.prev_randao), + Self::Bellatrix(inner) => &mut inner.state_root, + Self::Capella(inner) => &mut inner.state_root, + Self::Deneb(inner) => &mut inner.state_root, } } - pub fn block_number_mut(&mut self) -> Option<&mut u64> { + pub fn receipts_root(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_number), - Self::Capella(inner) => Some(&mut inner.block_number), - Self::Deneb(inner) => Some(&mut inner.block_number), + Self::Bellatrix(inner) => &inner.receipts_root, + Self::Capella(inner) => &inner.receipts_root, + Self::Deneb(inner) => &inner.receipts_root, } } - pub fn gas_limit_mut(&mut self) -> Option<&mut u64> { + pub fn receipts_root_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_limit), - Self::Capella(inner) => Some(&mut inner.gas_limit), - Self::Deneb(inner) => Some(&mut inner.gas_limit), + Self::Bellatrix(inner) => &mut inner.receipts_root, + Self::Capella(inner) => &mut inner.receipts_root, + Self::Deneb(inner) => &mut inner.receipts_root, } } - pub fn gas_used_mut(&mut self) -> Option<&mut u64> { + pub fn logs_bloom(&self) -> &ByteVector { match self { - Self::Bellatrix(inner) => Some(&mut inner.gas_used), - Self::Capella(inner) => Some(&mut inner.gas_used), - Self::Deneb(inner) => Some(&mut inner.gas_used), + Self::Bellatrix(inner) => &inner.logs_bloom, + Self::Capella(inner) => &inner.logs_bloom, + Self::Deneb(inner) => &inner.logs_bloom, } } - pub fn timestamp_mut(&mut self) -> Option<&mut u64> { + pub fn logs_bloom_mut(&mut self) -> &mut ByteVector { match self { - Self::Bellatrix(inner) => Some(&mut inner.timestamp), - Self::Capella(inner) => Some(&mut inner.timestamp), - Self::Deneb(inner) => Some(&mut inner.timestamp), + Self::Bellatrix(inner) => &mut inner.logs_bloom, + Self::Capella(inner) => &mut inner.logs_bloom, + Self::Deneb(inner) => &mut inner.logs_bloom, } } - pub fn extra_data_mut(&mut self) -> Option<&mut ByteList> { + pub fn prev_randao(&self) -> &Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.extra_data), - Self::Capella(inner) => Some(&mut inner.extra_data), - Self::Deneb(inner) => Some(&mut inner.extra_data), + Self::Bellatrix(inner) => &inner.prev_randao, + Self::Capella(inner) => &inner.prev_randao, + Self::Deneb(inner) => &inner.prev_randao, } } - pub fn base_fee_per_gas_mut(&mut self) -> Option<&mut U256> { + pub fn prev_randao_mut(&mut self) -> &mut Bytes32 { match self { - Self::Bellatrix(inner) => Some(&mut inner.base_fee_per_gas), - Self::Capella(inner) => Some(&mut inner.base_fee_per_gas), - Self::Deneb(inner) => Some(&mut inner.base_fee_per_gas), + Self::Bellatrix(inner) => &mut inner.prev_randao, + Self::Capella(inner) => &mut inner.prev_randao, + Self::Deneb(inner) => &mut inner.prev_randao, } } - pub fn block_hash_mut(&mut self) -> Option<&mut Hash32> { + pub fn block_number(&self) -> &u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.block_hash), - Self::Capella(inner) => Some(&mut inner.block_hash), - Self::Deneb(inner) => Some(&mut inner.block_hash), + Self::Bellatrix(inner) => &inner.block_number, + Self::Capella(inner) => &inner.block_number, + Self::Deneb(inner) => &inner.block_number, } } - pub fn transactions_root_mut(&mut self) -> Option<&mut Root> { + pub fn block_number_mut(&mut self) -> &mut u64 { match self { - Self::Bellatrix(inner) => Some(&mut inner.transactions_root), - Self::Capella(inner) => Some(&mut inner.transactions_root), - Self::Deneb(inner) => Some(&mut inner.transactions_root), + Self::Bellatrix(inner) => &mut inner.block_number, + Self::Capella(inner) => &mut inner.block_number, + Self::Deneb(inner) => &mut inner.block_number, + } + } + pub fn gas_limit(&self) -> &u64 { + match self { + Self::Bellatrix(inner) => &inner.gas_limit, + Self::Capella(inner) => &inner.gas_limit, + Self::Deneb(inner) => &inner.gas_limit, + } + } + pub fn gas_limit_mut(&mut self) -> &mut u64 { + match self { + Self::Bellatrix(inner) => &mut inner.gas_limit, + Self::Capella(inner) => &mut inner.gas_limit, + Self::Deneb(inner) => &mut inner.gas_limit, + } + } + pub fn gas_used(&self) -> &u64 { + match self { + Self::Bellatrix(inner) => &inner.gas_used, + Self::Capella(inner) => &inner.gas_used, + Self::Deneb(inner) => &inner.gas_used, + } + } + pub fn gas_used_mut(&mut self) -> &mut u64 { + match self { + Self::Bellatrix(inner) => &mut inner.gas_used, + Self::Capella(inner) => &mut inner.gas_used, + Self::Deneb(inner) => &mut inner.gas_used, + } + } + pub fn timestamp(&self) -> &u64 { + match self { + Self::Bellatrix(inner) => &inner.timestamp, + Self::Capella(inner) => &inner.timestamp, + Self::Deneb(inner) => &inner.timestamp, + } + } + pub fn timestamp_mut(&mut self) -> &mut u64 { + match self { + Self::Bellatrix(inner) => &mut inner.timestamp, + Self::Capella(inner) => &mut inner.timestamp, + Self::Deneb(inner) => &mut inner.timestamp, + } + } + pub fn extra_data(&self) -> &ByteList { + match self { + Self::Bellatrix(inner) => &inner.extra_data, + Self::Capella(inner) => &inner.extra_data, + Self::Deneb(inner) => &inner.extra_data, + } + } + pub fn extra_data_mut(&mut self) -> &mut ByteList { + match self { + Self::Bellatrix(inner) => &mut inner.extra_data, + Self::Capella(inner) => &mut inner.extra_data, + Self::Deneb(inner) => &mut inner.extra_data, + } + } + pub fn base_fee_per_gas(&self) -> &U256 { + match self { + Self::Bellatrix(inner) => &inner.base_fee_per_gas, + Self::Capella(inner) => &inner.base_fee_per_gas, + Self::Deneb(inner) => &inner.base_fee_per_gas, + } + } + pub fn base_fee_per_gas_mut(&mut self) -> &mut U256 { + match self { + Self::Bellatrix(inner) => &mut inner.base_fee_per_gas, + Self::Capella(inner) => &mut inner.base_fee_per_gas, + Self::Deneb(inner) => &mut inner.base_fee_per_gas, + } + } + pub fn block_hash(&self) -> &Hash32 { + match self { + Self::Bellatrix(inner) => &inner.block_hash, + Self::Capella(inner) => &inner.block_hash, + Self::Deneb(inner) => &inner.block_hash, + } + } + pub fn block_hash_mut(&mut self) -> &mut Hash32 { + match self { + Self::Bellatrix(inner) => &mut inner.block_hash, + Self::Capella(inner) => &mut inner.block_hash, + Self::Deneb(inner) => &mut inner.block_hash, + } + } + pub fn transactions_root(&self) -> &Root { + match self { + Self::Bellatrix(inner) => &inner.transactions_root, + Self::Capella(inner) => &inner.transactions_root, + Self::Deneb(inner) => &inner.transactions_root, + } + } + pub fn transactions_root_mut(&mut self) -> &mut Root { + match self { + Self::Bellatrix(inner) => &mut inner.transactions_root, + Self::Capella(inner) => &mut inner.transactions_root, + Self::Deneb(inner) => &mut inner.transactions_root, + } + } + pub fn withdrawals_root(&self) -> Option<&Root> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(inner) => Some(&inner.withdrawals_root), + Self::Deneb(inner) => Some(&inner.withdrawals_root), } } pub fn withdrawals_root_mut(&mut self) -> Option<&mut Root> { @@ -660,6 +818,13 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> Self::Deneb(inner) => Some(&mut inner.withdrawals_root), } } + pub fn blob_gas_used(&self) -> Option<&u64> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(inner) => Some(&inner.blob_gas_used), + } + } pub fn blob_gas_used_mut(&mut self) -> Option<&mut u64> { match self { Self::Bellatrix(_) => None, @@ -667,6 +832,13 @@ impl<'a, const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize> Self::Deneb(inner) => Some(&mut inner.blob_gas_used), } } + pub fn excess_blob_gas(&self) -> Option<&u64> { + match self { + Self::Bellatrix(_) => None, + Self::Capella(_) => None, + Self::Deneb(inner) => Some(&inner.excess_blob_gas), + } + } pub fn excess_blob_gas_mut(&mut self) -> Option<&mut u64> { match self { Self::Bellatrix(_) => None, diff --git a/ethereum-consensus/src/types/signed_beacon_block.rs b/ethereum-consensus/src/types/signed_beacon_block.rs index 784d72847..f8fce347a 100644 --- a/ethereum-consensus/src/types/signed_beacon_block.rs +++ b/ethereum-consensus/src/types/signed_beacon_block.rs @@ -8,10 +8,10 @@ use crate::{ primitives::BlsSignature, ssz::prelude::*, types::beacon_block::{BeaconBlockRef, BeaconBlockRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum SignedBeaconBlock< const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, @@ -345,6 +345,15 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Phase0(_) => Version::Phase0, + Self::Altair(_) => Version::Altair, + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn message( &self, ) -> BeaconBlockRef< @@ -417,6 +426,7 @@ impl< } } impl< + 'de, const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, const MAX_ATTESTER_SLASHINGS: usize, @@ -431,7 +441,7 @@ impl< const MAX_WITHDRAWALS_PER_PAYLOAD: usize, const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, - > serde::Serialize + > serde::Deserialize<'de> for SignedBeaconBlock< MAX_PROPOSER_SLASHINGS, MAX_VALIDATORS_PER_COMMITTEE, @@ -449,16 +459,26 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Phase0(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Altair(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Altair(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Phase0(inner)) } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } diff --git a/ethereum-consensus/src/types/signed_blinded_beacon_block.rs b/ethereum-consensus/src/types/signed_blinded_beacon_block.rs index 09f0cc0b3..10ac56245 100644 --- a/ethereum-consensus/src/types/signed_blinded_beacon_block.rs +++ b/ethereum-consensus/src/types/signed_blinded_beacon_block.rs @@ -6,10 +6,10 @@ use crate::{ primitives::BlsSignature, ssz::prelude::*, types::blinded_beacon_block::{BlindedBeaconBlockRef, BlindedBeaconBlockRefMut}, + Fork as Version, }; -#[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] -#[serde(tag = "version", content = "data")] -#[serde(rename_all = "lowercase")] +#[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] +#[serde(untagged)] pub enum SignedBlindedBeaconBlock< const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, @@ -219,68 +219,72 @@ impl< _ => None, } } + pub fn version(&self) -> Version { + match self { + Self::Bellatrix(_) => Version::Bellatrix, + Self::Capella(_) => Version::Capella, + Self::Deneb(_) => Version::Deneb, + } + } pub fn message( &self, - ) -> Option< - BlindedBeaconBlockRef< - MAX_PROPOSER_SLASHINGS, - MAX_VALIDATORS_PER_COMMITTEE, - MAX_ATTESTER_SLASHINGS, - MAX_ATTESTATIONS, - MAX_DEPOSITS, - MAX_VOLUNTARY_EXITS, - SYNC_COMMITTEE_SIZE, - BYTES_PER_LOGS_BLOOM, - MAX_EXTRA_DATA_BYTES, - MAX_BLS_TO_EXECUTION_CHANGES, - MAX_BLOB_COMMITMENTS_PER_BLOCK, - >, + ) -> BlindedBeaconBlockRef< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, > { match self { - Self::Bellatrix(inner) => Some(From::from(&inner.message)), - Self::Capella(inner) => Some(From::from(&inner.message)), - Self::Deneb(inner) => Some(From::from(&inner.message)), + Self::Bellatrix(inner) => From::from(&inner.message), + Self::Capella(inner) => From::from(&inner.message), + Self::Deneb(inner) => From::from(&inner.message), } } pub fn message_mut( &mut self, - ) -> Option< - BlindedBeaconBlockRefMut< - MAX_PROPOSER_SLASHINGS, - MAX_VALIDATORS_PER_COMMITTEE, - MAX_ATTESTER_SLASHINGS, - MAX_ATTESTATIONS, - MAX_DEPOSITS, - MAX_VOLUNTARY_EXITS, - SYNC_COMMITTEE_SIZE, - BYTES_PER_LOGS_BLOOM, - MAX_EXTRA_DATA_BYTES, - MAX_BLS_TO_EXECUTION_CHANGES, - MAX_BLOB_COMMITMENTS_PER_BLOCK, - >, + ) -> BlindedBeaconBlockRefMut< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BLS_TO_EXECUTION_CHANGES, + MAX_BLOB_COMMITMENTS_PER_BLOCK, > { match self { - Self::Bellatrix(inner) => Some(From::from(&mut inner.message)), - Self::Capella(inner) => Some(From::from(&mut inner.message)), - Self::Deneb(inner) => Some(From::from(&mut inner.message)), + Self::Bellatrix(inner) => From::from(&mut inner.message), + Self::Capella(inner) => From::from(&mut inner.message), + Self::Deneb(inner) => From::from(&mut inner.message), } } - pub fn signature(&self) -> Option<&BlsSignature> { + pub fn signature(&self) -> &BlsSignature { match self { - Self::Bellatrix(inner) => Some(&inner.signature), - Self::Capella(inner) => Some(&inner.signature), - Self::Deneb(inner) => Some(&inner.signature), + Self::Bellatrix(inner) => &inner.signature, + Self::Capella(inner) => &inner.signature, + Self::Deneb(inner) => &inner.signature, } } - pub fn signature_mut(&mut self) -> Option<&mut BlsSignature> { + pub fn signature_mut(&mut self) -> &mut BlsSignature { match self { - Self::Bellatrix(inner) => Some(&mut inner.signature), - Self::Capella(inner) => Some(&mut inner.signature), - Self::Deneb(inner) => Some(&mut inner.signature), + Self::Bellatrix(inner) => &mut inner.signature, + Self::Capella(inner) => &mut inner.signature, + Self::Deneb(inner) => &mut inner.signature, } } } impl< + 'de, const MAX_PROPOSER_SLASHINGS: usize, const MAX_VALIDATORS_PER_COMMITTEE: usize, const MAX_ATTESTER_SLASHINGS: usize, @@ -292,7 +296,7 @@ impl< const MAX_EXTRA_DATA_BYTES: usize, const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, - > serde::Serialize + > serde::Deserialize<'de> for SignedBlindedBeaconBlock< MAX_PROPOSER_SLASHINGS, MAX_VALIDATORS_PER_COMMITTEE, @@ -307,14 +311,20 @@ impl< MAX_BLOB_COMMITMENTS_PER_BLOCK, > { - fn serialize(&self, serializer: S) -> Result + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer, + D: serde::Deserializer<'de>, { - match self { - Self::Bellatrix(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Capella(inner) => <_ as serde::Serialize>::serialize(inner, serializer), - Self::Deneb(inner) => <_ as serde::Serialize>::serialize(inner, serializer), + let value = serde_json::Value::deserialize(deserializer)?; + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Deneb(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Capella(inner)) + } + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::Bellatrix(inner)) } + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } diff --git a/spec-gen/src/generator.rs b/spec-gen/src/generator.rs index 6e58b583f..320250508 100644 --- a/spec-gen/src/generator.rs +++ b/spec-gen/src/generator.rs @@ -128,7 +128,7 @@ impl Fork { use std::cmp; use std::collections::HashSet; use crate::ssz::prelude::*; - use crate::crypto::{hash, verify_signature, fast_aggregate_verify}; + use crate::crypto::{hash, fast_aggregate_verify}; pub use crate::altair::fork::upgrade_to_altair; }; @@ -142,7 +142,7 @@ impl Fork { use std::iter::zip; use crate::ssz::prelude::*; use integer_sqrt::IntegerSquareRoot; - use crate::crypto::{hash, verify_signature, fast_aggregate_verify, eth_aggregate_public_keys, eth_fast_aggregate_verify}; + use crate::crypto::{hash, fast_aggregate_verify, eth_aggregate_public_keys, eth_fast_aggregate_verify}; pub use crate::bellatrix::fork::upgrade_to_bellatrix; }; @@ -156,7 +156,7 @@ impl Fork { use std::iter::zip; use crate::ssz::prelude::*; use integer_sqrt::IntegerSquareRoot; - use crate::crypto::{hash, verify_signature, fast_aggregate_verify, eth_aggregate_public_keys, eth_fast_aggregate_verify}; + use crate::crypto::{hash, fast_aggregate_verify, eth_aggregate_public_keys, eth_fast_aggregate_verify}; pub use crate::capella::fork::upgrade_to_capella; }; @@ -170,7 +170,7 @@ impl Fork { use std::iter::zip; use crate::ssz::prelude::*; use integer_sqrt::IntegerSquareRoot; - use crate::crypto::{hash, verify_signature, fast_aggregate_verify, eth_aggregate_public_keys, eth_fast_aggregate_verify}; + use crate::crypto::{hash, fast_aggregate_verify, eth_aggregate_public_keys, eth_fast_aggregate_verify}; pub use crate::deneb::fork::upgrade_to_deneb; }; diff --git a/spec-gen/src/type_generator.rs b/spec-gen/src/type_generator.rs index e46fa6235..0675f6084 100644 --- a/spec-gen/src/type_generator.rs +++ b/spec-gen/src/type_generator.rs @@ -5,8 +5,8 @@ use crate::{ use convert_case::{Case, Casing}; use std::{collections::HashSet, fs}; use syn::{ - parse_quote, token::Mut, visit::Visit, AngleBracketedGenericArguments, Arm, Generics, Ident, - ImplItemMethod, Item, ItemStruct, + parse_quote, token::Mut, visit::Visit, AngleBracketedGenericArguments, Arm, Attribute, Expr, + GenericParam, Generics, Ident, ImplItemMethod, Item, ItemStruct, }; const SOURCE_ROOT: &str = "ethereum-consensus/src"; @@ -115,16 +115,16 @@ impl Type { altair::beacon_block as altair, bellatrix::beacon_block as bellatrix, capella::beacon_block as capella, - deneb::beacon_block as deneb, + deneb::{beacon_block as deneb, polynomial_commitments::KzgCommitment}, phase0::{ beacon_block as phase0, Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing, SignedVoluntaryExit, }, altair::SyncAggregate, capella::SignedBlsToExecutionChange, - kzg::KzgCommitment, primitives::{BlsSignature, Bytes32}, ssz::prelude::*, + Fork as Version, types::execution_payload::{ExecutionPayloadRef, ExecutionPayloadRefMut}, }; }, @@ -132,16 +132,16 @@ impl Type { use crate::{ bellatrix::blinded_beacon_block as bellatrix, capella::blinded_beacon_block as capella, - deneb::blinded_beacon_block as deneb, + deneb::{blinded_beacon_block as deneb, polynomial_commitments::KzgCommitment}, phase0::{ Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing, SignedVoluntaryExit, }, altair::SyncAggregate, capella::SignedBlsToExecutionChange, - kzg::KzgCommitment, primitives::{BlsSignature, Bytes32}, ssz::prelude::*, + Fork as Version, types::execution_payload_header::{ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut}, }; }, @@ -154,6 +154,7 @@ impl Type { phase0::beacon_block as phase0, primitives::{Slot, ValidatorIndex, Root}, ssz::prelude::*, + Fork as Version, types::beacon_block_body::{BeaconBlockBodyRef, BeaconBlockBodyRefMut}, }; }, @@ -164,6 +165,7 @@ impl Type { deneb::blinded_beacon_block as deneb, primitives::{Slot, ValidatorIndex, Root}, ssz::prelude::*, + Fork as Version, types::blinded_beacon_block_body::{BlindedBeaconBlockBodyRef, BlindedBeaconBlockBodyRefMut}, }; }, @@ -176,6 +178,7 @@ impl Type { phase0::beacon_block as phase0, primitives::BlsSignature, ssz::prelude::*, + Fork as Version, types::beacon_block::{BeaconBlockRef, BeaconBlockRefMut}, }; }, @@ -186,6 +189,7 @@ impl Type { deneb::blinded_beacon_block as deneb, primitives::BlsSignature, ssz::prelude::*, + Fork as Version, types::blinded_beacon_block::{BlindedBeaconBlockRef, BlindedBeaconBlockRefMut}, }; }, @@ -196,6 +200,7 @@ impl Type { deneb::execution_payload as deneb, primitives::{Hash32, ExecutionAddress, Bytes32}, ssz::prelude::*, + Fork as Version, }; }, Self::ExecutionPayloadHeader => parse_quote! { @@ -205,6 +210,7 @@ impl Type { deneb::execution_payload as deneb, primitives::{Hash32, Root, ExecutionAddress, Bytes32}, ssz::prelude::*, + Fork as Version, }; }, Self::BeaconState => parse_quote! { @@ -218,6 +224,7 @@ impl Type { phase0::{JUSTIFICATION_BITS_LENGTH, beacon_block::BeaconBlockHeader, validator::Validator, operations::{PendingAttestation, Checkpoint, Eth1Data}}, primitives::{Root, ValidatorIndex, WithdrawalIndex, ParticipationFlags, Slot, Gwei, Bytes32}, ssz::prelude::*, + Fork as Version, types::execution_payload_header::{ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut}, }; }, @@ -356,9 +363,8 @@ fn derive_type_defn(target_type: &Type, merge_type: &MergeType) -> (Item, Generi }) .collect::>(); let enum_defn = parse_quote! { - #[derive(Debug, Clone, PartialEq, Eq, SimpleSerialize, serde::Deserialize)] - #[serde(tag = "version", content = "data")] - #[serde(rename_all = "lowercase")] + #[derive(Debug, Clone, PartialEq, Eq, Merkleized, serde::Serialize)] + #[serde(untagged)] pub enum #type_name #generics { #(#variant_defns),* } @@ -366,16 +372,23 @@ fn derive_type_defn(target_type: &Type, merge_type: &MergeType) -> (Item, Generi (enum_defn, generics_copy) } -// NOTE: this should be fused w/ `derive_optional_method_set` -// it started out distinct but after supporting all the features we need, it is -// worthwhile to just make one merged routine... -fn derive_maybe_non_optional_method_set( +fn derive_method_set( target_type: &Type, field_defn: &FieldDefn, fork_sequence: &[Fork], ref_type: &Option, ) -> Vec { let ident = &field_defn.ident; + let deletion_fork = target_type.field_deletions().and_then(|(fork, fields)| { + let identifier = ident.to_string(); + if fields.contains(&identifier.as_str()) { + Some(fork) + } else { + None + } + }); + let field_defined_in_all_forks = field_defn.fork == fork_sequence[0]; + let is_optional = deletion_fork.is_some() || !field_defined_in_all_forks; let is_polymorphic = target_type.polymorphic_fields().contains(&ident.to_string().as_ref()); let ty: syn::Type = if is_polymorphic { let base = target_type.get_polymorphic_type(); @@ -394,11 +407,31 @@ fn derive_maybe_non_optional_method_set( #name #arguments } } else { - let ty = &field_defn.type_def; + let type_def = &field_defn.type_def; parse_quote! { - &#ty + &#type_def } }; + let ty: syn::Type = if is_optional { parse_quote!(Option<#ty>) } else { ty }; + + let match_arms = derive_match_arms( + &field_defn.fork, + fork_sequence, + ident, + false, + is_polymorphic, + is_optional, + deletion_fork, + ); + let immut_ref = parse_quote! { + pub fn #ident(&self) -> #ty { + match self { + #(#match_arms)* + } + } + }; + + let mut_ident = as_syn_ident(format!("{ident}_mut")); let ty_mut: syn::Type = if is_polymorphic { let base = target_type.get_polymorphic_type(); let name = as_syn_ident(format!("{base}RefMut")); @@ -416,50 +449,21 @@ fn derive_maybe_non_optional_method_set( #name #arguments } } else { - let ty = &field_defn.type_def; + let type_def = &field_defn.type_def; parse_quote! { - &mut #ty + &mut #type_def } }; - - let identifier = ident.to_string(); - let deletion_fork = target_type.field_deletions().and_then(|(fork, fields)| { - if fields.contains(&identifier.as_str()) { - Some(fork) - } else { - None - } - }); - + let ty_mut: syn::Type = if is_optional { parse_quote!(Option<#ty_mut>) } else { ty_mut }; let match_arms = derive_match_arms( &field_defn.fork, fork_sequence, ident, - false, - false, - is_polymorphic, - deletion_fork, - ); - let ty: syn::Type = if deletion_fork.is_some() { parse_quote!(Option<#ty>) } else { ty }; - let immut_ref = parse_quote! { - pub fn #ident(&self) -> #ty { - match self { - #(#match_arms)* - } - } - }; - let mut_ident = as_syn_ident(format!("{ident}_mut")); - let match_arms = derive_match_arms( - &field_defn.fork, - fork_sequence, - ident, - false, true, is_polymorphic, + is_optional, deletion_fork, ); - let ty_mut: syn::Type = - if deletion_fork.is_some() { parse_quote!(Option<#ty_mut>) } else { ty_mut }; let mut_ref = parse_quote! { pub fn #mut_ident(&mut self) -> #ty_mut { match self { @@ -469,7 +473,7 @@ fn derive_maybe_non_optional_method_set( }; match ref_type { Some(RefType::Immutable) => vec![immut_ref], - Some(RefType::Mutable) => vec![mut_ref], + Some(RefType::Mutable) => vec![immut_ref, mut_ref], None => vec![immut_ref, mut_ref], } } @@ -478,9 +482,9 @@ fn derive_match_arms( source_fork: &Fork, fork_sequence: &[Fork], ident: &Ident, - is_optional: bool, is_mut: bool, is_polymorphic: bool, + is_optional: bool, deletion_fork: Option, ) -> Vec { let mutability = if is_mut { Some(Mut::default()) } else { None }; @@ -489,8 +493,6 @@ fn derive_match_arms( } else { parse_quote!(&#mutability inner.#ident) }; - let accessor_expr: syn::Expr = - if is_optional { parse_quote!(Some(#accessor_expr)) } else { accessor_expr }; fork_sequence .iter() .map(|fork| { @@ -500,7 +502,7 @@ fn derive_match_arms( } else { false }; - let accessor_expr = if deletion_fork.is_some() { + let accessor_expr = if is_optional { parse_quote!(Some(#accessor_expr)) } else { accessor_expr.clone() @@ -518,105 +520,6 @@ fn derive_match_arms( .collect() } -fn derive_optional_method_set( - target_type: &Type, - field_defn: &FieldDefn, - fork_sequence: &[Fork], - ref_type: &Option, -) -> Vec { - let ident = &field_defn.ident; - let is_polymorphic = target_type.polymorphic_fields().contains(&ident.to_string().as_ref()); - let ty: syn::Type = if is_polymorphic { - let base = target_type.get_polymorphic_type(); - let name = as_syn_ident(format!("{base}Ref")); - - let ty = &field_defn.type_def; - let mut visitor = ToGenericsVisitor::default(); - visitor.visit_type(ty); - let bounds = visitor.bounds; - let arguments: AngleBracketedGenericArguments = parse_quote! { - < - #(#bounds),* - > - }; - parse_quote! { - #name #arguments - } - } else { - let ty = &field_defn.type_def; - parse_quote! { - &#ty - } - }; - let ty_mut: syn::Type = if is_polymorphic { - let base = target_type.get_polymorphic_type(); - let name = as_syn_ident(format!("{base}RefMut")); - - let ty = &field_defn.type_def; - let mut visitor = ToGenericsVisitor::default(); - visitor.visit_type(ty); - let bounds = visitor.bounds; - let arguments: AngleBracketedGenericArguments = parse_quote! { - < - #(#bounds),* - > - }; - parse_quote! { - #name #arguments - } - } else { - let ty = &field_defn.type_def; - parse_quote! { - &mut #ty - } - }; - let match_arms = derive_match_arms( - &field_defn.fork, - fork_sequence, - ident, - true, - false, - is_polymorphic, - None, - ); - let immut_ref = parse_quote! { - pub fn #ident(&self) -> Option<#ty> { - match self { - #(#match_arms)* - } - } - }; - let match_arms = - derive_match_arms(&field_defn.fork, fork_sequence, ident, true, true, is_polymorphic, None); - let mut_ident = as_syn_ident(format!("{ident}_mut")); - let mut_ref = parse_quote! { - pub fn #mut_ident(&mut self) -> Option<#ty_mut> { - match self { - #(#match_arms)* - } - } - }; - match ref_type { - Some(RefType::Immutable) => vec![immut_ref], - Some(RefType::Mutable) => vec![mut_ref], - None => vec![immut_ref, mut_ref], - } -} - -fn derive_method_set( - target_type: &Type, - field_defn: &FieldDefn, - fork_sequence: &[Fork], - ref_type: &Option, -) -> Vec { - match &field_defn.fork { - Fork::Phase0 => { - derive_maybe_non_optional_method_set(target_type, field_defn, fork_sequence, ref_type) - } - _ => derive_optional_method_set(target_type, field_defn, fork_sequence, ref_type), - } -} - enum RefType { Immutable, Mutable, @@ -660,20 +563,33 @@ fn derive_fields_impl( }; match ref_type { Some(RefType::Immutable) => vec![immut_ref], - Some(RefType::Mutable) => vec![mut_ref], + Some(RefType::Mutable) => vec![immut_ref, mut_ref], None => vec![immut_ref, mut_ref], } }) .collect::>(); let fork_sequence = merge_type.supported_forks(); - let field_accessors = merge_type - .fields + let fork_accessor_arms = fork_sequence .iter() - .flat_map(|field_defn| { - derive_method_set(target_type, field_defn, &fork_sequence, &ref_type) + .map(|fork| { + let fork = as_syn_ident(format!("{fork:?}")); + parse_quote! { + Self::#fork(_) => Version::#fork, + } }) - .collect::>(); + .collect::>(); + fields.push(parse_quote! { + pub fn version(&self) -> Version { + match self { + #(#fork_accessor_arms)* + } + } + }); + + let field_accessors = merge_type.fields.iter().flat_map(|field_defn| { + derive_method_set(target_type, field_defn, &fork_sequence, &ref_type) + }); fields.extend(field_accessors); fields } @@ -727,9 +643,17 @@ fn derive_ref_impl_type( } }) .collect::>(); + let derive_attr: Attribute = if is_mut { + parse_quote!(#[derive(Debug, PartialEq, Eq, Merkleized)]) + } else { + parse_quote!(#[derive(Debug, PartialEq, Eq)]) + }; + let ssz_attr: Option = + if is_mut { Some(parse_quote!(#[ssz(transparent)])) } else { None }; ( parse_quote! { - #[derive(Debug, PartialEq, Eq)] + #derive_attr + #ssz_attr pub enum #type_name #generics { #(#variant_defns,)* } @@ -810,28 +734,36 @@ fn derive_ref_impl(target_type: &Type, merge_type: &MergeType, is_mut: bool) -> result } -fn derive_serde_ser_impl(target_type: &Type, generics: &Generics, merge_type: &MergeType) -> Item { +fn derive_serde_de_impl(target_type: &Type, generics: &Generics, merge_type: &MergeType) -> Item { let type_name = as_syn_ident(target_type.name()); let arguments = generics_to_arguments(generics); - let match_arms: Vec = merge_type + let de_by_fork: Vec = merge_type .variants .iter() + .rev() .map(|variant| { let fork_name = as_syn_ident(format!("{:?}", variant.fork)); parse_quote! { - Self::#fork_name(inner) => <_ as serde::Serialize>::serialize(inner, serializer) + if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) { + return Ok(Self::#fork_name(inner)) + } } }) .collect(); + let mut generics = generics.clone(); + let de_lifetime: GenericParam = parse_quote! { + 'de + }; + generics.params.insert(0, de_lifetime); parse_quote! { - impl #generics serde::Serialize for #type_name #arguments { - fn serialize(&self, serializer: S) -> Result + impl #generics serde::Deserialize<'de> for #type_name #arguments { + fn deserialize(deserializer: D) -> Result where - S: serde::Serializer + D: serde::Deserializer<'de>, { - match self { - #(#match_arms,)* - } + let value = serde_json::Value::deserialize(deserializer)?; + #(#de_by_fork)* + Err(serde::de::Error::custom("no variant could be deserialized from input")) } } } @@ -842,10 +774,10 @@ fn as_syn(target_type: &Type, merge_type: &MergeType) -> Vec { let impl_defn = derive_impl_defn(target_type, merge_type, &generics); - let serde_ser_impl = derive_serde_ser_impl(target_type, &generics, merge_type); + let serde_de_impl = derive_serde_de_impl(target_type, &generics, merge_type); let imports = target_type.imports(); - let mut result = vec![imports, type_defn, impl_defn, serde_ser_impl]; + let mut result = vec![imports, type_defn, impl_defn, serde_de_impl]; if target_type.needs_ref_types() { result.extend(derive_ref_impl(target_type, merge_type, false));