mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 10:11:44 +00:00
Sidecar inclusion proof (#4900)
* Refactor BlobSidecar to new type * Fix some compile errors * Gossip verification compiles * Fix http api types take 1 * Fix another round of compile errors * Beacon node crate compiles * EF tests compile * Remove all blob signing from VC * fmt * Tests compile * Fix some tests * Fix more http tests * get compiling * Fix gossip conditions and tests * Add basic proof generation and verification * remove unnecessary ssz decode * add back build_sidecar * remove default at fork for blobs * fix beacon chain tests * get relase tests compiling * fix lints * fix existing spec tests * add new ef tests * fix gossip duplicate rule * lints * add back sidecar signature check in gossip * add finalized descendant check to blob sidecar gossip * fix error conversion * fix release tests * sidecar inclusion self review cleanup * Add proof verification and computation metrics * Remove accidentally committed file * Unify some block and blob errors; add slashing conditions for sidecars * Address review comment * Clean up re-org tests (#4957) * Address more review comments * Add Comments & Eliminate Unnecessary Clones * update names * Update beacon_node/beacon_chain/src/metrics.rs Co-authored-by: Jimmy Chen <jchen.tc@gmail.com> * Update beacon_node/network/src/network_beacon_processor/tests.rs Co-authored-by: Jimmy Chen <jchen.tc@gmail.com> * pr feedback * fix test compile * Sidecar Inclusion proof small refactor and updates (#4967) * Update some comments, variables and small cosmetic fixes. * Couple blobs and proofs into a tuple in `PayloadAndBlobs` for simplicity and safety. * Update function comment. * Update testing/ef_tests/src/cases/merkle_proof_validity.rs Co-authored-by: Jimmy Chen <jchen.tc@gmail.com> * Rename the block and blob wrapper types used in the beacon API interfaces. * make sure gossip invalid blobs are passed to the slasher (#4970) * Add blob headers to slasher before adding to DA checker * Replace Vec with HashSet in BlockQueue * fmt * Rename gindex -> index * Simplify gossip condition --------- Co-authored-by: realbigsean <seananderson33@gmail.com> Co-authored-by: realbigsean <sean@sigmaprime.io> Co-authored-by: Michael Sproul <michael@sigmaprime.io> Co-authored-by: Mark Mackey <mark@sigmaprime.io> Co-authored-by: Jimmy Chen <jchen.tc@gmail.com>
This commit is contained in:
@@ -769,9 +769,9 @@ impl BeaconNodeHttpClient {
|
||||
/// `POST beacon/blocks`
|
||||
///
|
||||
/// Returns `Ok(None)` on a 404 error.
|
||||
pub async fn post_beacon_blocks<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blocks<T: EthSpec>(
|
||||
&self,
|
||||
block_contents: &SignedBlockContents<T, Payload>,
|
||||
block_contents: &PublishBlockRequest<T>,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
@@ -789,9 +789,9 @@ impl BeaconNodeHttpClient {
|
||||
/// `POST beacon/blocks`
|
||||
///
|
||||
/// Returns `Ok(None)` on a 404 error.
|
||||
pub async fn post_beacon_blocks_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blocks_ssz<T: EthSpec>(
|
||||
&self,
|
||||
block_contents: &SignedBlockContents<T, Payload>,
|
||||
block_contents: &PublishBlockRequest<T>,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
@@ -813,9 +813,9 @@ impl BeaconNodeHttpClient {
|
||||
/// `POST beacon/blinded_blocks`
|
||||
///
|
||||
/// Returns `Ok(None)` on a 404 error.
|
||||
pub async fn post_beacon_blinded_blocks<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blinded_blocks<T: EthSpec>(
|
||||
&self,
|
||||
block: &SignedBlockContents<T, Payload>,
|
||||
block: &SignedBlindedBeaconBlock<T>,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
@@ -833,9 +833,9 @@ impl BeaconNodeHttpClient {
|
||||
/// `POST beacon/blinded_blocks`
|
||||
///
|
||||
/// Returns `Ok(None)` on a 404 error.
|
||||
pub async fn post_beacon_blinded_blocks_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blinded_blocks_ssz<T: EthSpec>(
|
||||
&self,
|
||||
block: &SignedBlockContents<T, Payload>,
|
||||
block: &SignedBlindedBeaconBlock<T>,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
@@ -887,9 +887,9 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `POST v2/beacon/blocks`
|
||||
pub async fn post_beacon_blocks_v2<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blocks_v2<T: EthSpec>(
|
||||
&self,
|
||||
block_contents: &SignedBlockContents<T, Payload>,
|
||||
block_contents: &PublishBlockRequest<T>,
|
||||
validation_level: Option<BroadcastValidation>,
|
||||
) -> Result<(), Error> {
|
||||
self.post_generic_with_consensus_version(
|
||||
@@ -904,9 +904,9 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `POST v2/beacon/blocks`
|
||||
pub async fn post_beacon_blocks_v2_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blocks_v2_ssz<T: EthSpec>(
|
||||
&self,
|
||||
block_contents: &SignedBlockContents<T, Payload>,
|
||||
block_contents: &PublishBlockRequest<T>,
|
||||
validation_level: Option<BroadcastValidation>,
|
||||
) -> Result<(), Error> {
|
||||
self.post_generic_with_consensus_version_and_ssz_body(
|
||||
@@ -921,16 +921,16 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `POST v2/beacon/blinded_blocks`
|
||||
pub async fn post_beacon_blinded_blocks_v2<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn post_beacon_blinded_blocks_v2<T: EthSpec>(
|
||||
&self,
|
||||
block_contents: &SignedBlockContents<T, Payload>,
|
||||
signed_block: &SignedBlindedBeaconBlock<T>,
|
||||
validation_level: Option<BroadcastValidation>,
|
||||
) -> Result<(), Error> {
|
||||
self.post_generic_with_consensus_version(
|
||||
self.post_beacon_blinded_blocks_v2_path(validation_level)?,
|
||||
block_contents,
|
||||
signed_block,
|
||||
Some(self.timeouts.proposal),
|
||||
block_contents.signed_block().message().body().fork_name(),
|
||||
signed_block.message().body().fork_name(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -940,14 +940,14 @@ impl BeaconNodeHttpClient {
|
||||
/// `POST v2/beacon/blinded_blocks`
|
||||
pub async fn post_beacon_blinded_blocks_v2_ssz<T: EthSpec>(
|
||||
&self,
|
||||
block_contents: &SignedBlindedBlockContents<T>,
|
||||
signed_block: &SignedBlindedBeaconBlock<T>,
|
||||
validation_level: Option<BroadcastValidation>,
|
||||
) -> Result<(), Error> {
|
||||
self.post_generic_with_consensus_version_and_ssz_body(
|
||||
self.post_beacon_blinded_blocks_v2_path(validation_level)?,
|
||||
block_contents.as_ssz_bytes(),
|
||||
signed_block.as_ssz_bytes(),
|
||||
Some(self.timeouts.proposal),
|
||||
block_contents.signed_block().message().body().fork_name(),
|
||||
signed_block.message().body().fork_name(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -1700,38 +1700,33 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET v2/validator/blocks/{slot}`
|
||||
pub async fn get_validator_blocks<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blocks<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
) -> Result<ForkVersionedResponse<BlockContents<T, Payload>>, Error> {
|
||||
) -> Result<ForkVersionedResponse<FullBlockContents<T>>, Error> {
|
||||
self.get_validator_blocks_modular(slot, randao_reveal, graffiti, SkipRandaoVerification::No)
|
||||
.await
|
||||
}
|
||||
|
||||
/// `GET v2/validator/blocks/{slot}`
|
||||
pub async fn get_validator_blocks_modular<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blocks_modular<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
) -> Result<ForkVersionedResponse<BlockContents<T, Payload>>, Error> {
|
||||
) -> Result<ForkVersionedResponse<FullBlockContents<T>>, Error> {
|
||||
let path = self
|
||||
.get_validator_blocks_path::<T, Payload>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
skip_randao_verification,
|
||||
)
|
||||
.get_validator_blocks_path::<T>(slot, randao_reveal, graffiti, skip_randao_verification)
|
||||
.await?;
|
||||
|
||||
self.get(path).await
|
||||
}
|
||||
|
||||
/// returns `GET v2/validator/blocks/{slot}` URL path
|
||||
pub async fn get_validator_blocks_path<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blocks_path<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
@@ -1837,12 +1832,12 @@ impl BeaconNodeHttpClient {
|
||||
|
||||
if is_blinded_payload {
|
||||
let blinded_payload = response
|
||||
.json::<ForkVersionedResponse<BlockContents<T, BlindedPayload<T>>>>()
|
||||
.json::<ForkVersionedResponse<BlindedBeaconBlock<T>>>()
|
||||
.await?;
|
||||
Ok(ForkVersionedBeaconBlockType::Blinded(blinded_payload))
|
||||
} else {
|
||||
let full_payload = response
|
||||
.json::<ForkVersionedResponse<BlockContents<T, FullPayload<T>>>>()
|
||||
.json::<ForkVersionedResponse<FullBlockContents<T>>>()
|
||||
.await?;
|
||||
Ok(ForkVersionedBeaconBlockType::Full(full_payload))
|
||||
}
|
||||
@@ -1901,13 +1896,13 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET v2/validator/blocks/{slot}` in ssz format
|
||||
pub async fn get_validator_blocks_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blocks_ssz<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
) -> Result<Option<Vec<u8>>, Error> {
|
||||
self.get_validator_blocks_modular_ssz::<T, Payload>(
|
||||
self.get_validator_blocks_modular_ssz::<T>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
@@ -1917,7 +1912,7 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET v2/validator/blocks/{slot}` in ssz format
|
||||
pub async fn get_validator_blocks_modular_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blocks_modular_ssz<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
@@ -1925,12 +1920,7 @@ impl BeaconNodeHttpClient {
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
) -> Result<Option<Vec<u8>>, Error> {
|
||||
let path = self
|
||||
.get_validator_blocks_path::<T, Payload>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
skip_randao_verification,
|
||||
)
|
||||
.get_validator_blocks_path::<T>(slot, randao_reveal, graffiti, skip_randao_verification)
|
||||
.await?;
|
||||
|
||||
self.get_bytes_opt_accept_header(path, Accept::Ssz, self.timeouts.get_validator_block_ssz)
|
||||
@@ -1938,12 +1928,12 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET v2/validator/blinded_blocks/{slot}`
|
||||
pub async fn get_validator_blinded_blocks<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blinded_blocks<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
) -> Result<ForkVersionedResponse<BlockContents<T, Payload>>, Error> {
|
||||
) -> Result<ForkVersionedResponse<BlindedBeaconBlock<T>>, Error> {
|
||||
self.get_validator_blinded_blocks_modular(
|
||||
slot,
|
||||
randao_reveal,
|
||||
@@ -1954,7 +1944,7 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// returns `GET v1/validator/blinded_blocks/{slot}` URL path
|
||||
pub async fn get_validator_blinded_blocks_path<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blinded_blocks_path<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
@@ -1986,18 +1976,15 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET v1/validator/blinded_blocks/{slot}`
|
||||
pub async fn get_validator_blinded_blocks_modular<
|
||||
T: EthSpec,
|
||||
Payload: AbstractExecPayload<T>,
|
||||
>(
|
||||
pub async fn get_validator_blinded_blocks_modular<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
) -> Result<ForkVersionedResponse<BlockContents<T, Payload>>, Error> {
|
||||
) -> Result<ForkVersionedResponse<BlindedBeaconBlock<T>>, Error> {
|
||||
let path = self
|
||||
.get_validator_blinded_blocks_path::<T, Payload>(
|
||||
.get_validator_blinded_blocks_path::<T>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
@@ -2009,13 +1996,13 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET v2/validator/blinded_blocks/{slot}` in ssz format
|
||||
pub async fn get_validator_blinded_blocks_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
pub async fn get_validator_blinded_blocks_ssz<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
graffiti: Option<&Graffiti>,
|
||||
) -> Result<Option<Vec<u8>>, Error> {
|
||||
self.get_validator_blinded_blocks_modular_ssz::<T, Payload>(
|
||||
self.get_validator_blinded_blocks_modular_ssz::<T>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
@@ -2024,10 +2011,7 @@ impl BeaconNodeHttpClient {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_validator_blinded_blocks_modular_ssz<
|
||||
T: EthSpec,
|
||||
Payload: AbstractExecPayload<T>,
|
||||
>(
|
||||
pub async fn get_validator_blinded_blocks_modular_ssz<T: EthSpec>(
|
||||
&self,
|
||||
slot: Slot,
|
||||
randao_reveal: &SignatureBytes,
|
||||
@@ -2035,7 +2019,7 @@ impl BeaconNodeHttpClient {
|
||||
skip_randao_verification: SkipRandaoVerification,
|
||||
) -> Result<Option<Vec<u8>>, Error> {
|
||||
let path = self
|
||||
.get_validator_blinded_blocks_path::<T, Payload>(
|
||||
.get_validator_blinded_blocks_path::<T>(
|
||||
slot,
|
||||
randao_reveal,
|
||||
graffiti,
|
||||
|
||||
@@ -12,9 +12,7 @@ use std::convert::TryFrom;
|
||||
use std::fmt::{self, Display};
|
||||
use std::str::{from_utf8, FromStr};
|
||||
use std::time::Duration;
|
||||
use tree_hash::TreeHash;
|
||||
use types::beacon_block_body::KzgCommitments;
|
||||
use types::builder_bid::BlindedBlobsBundle;
|
||||
pub use types::*;
|
||||
|
||||
#[cfg(feature = "lighthouse")]
|
||||
@@ -901,9 +899,9 @@ pub struct SseBlobSidecar {
|
||||
impl SseBlobSidecar {
|
||||
pub fn from_blob_sidecar<E: EthSpec>(blob_sidecar: &BlobSidecar<E>) -> SseBlobSidecar {
|
||||
SseBlobSidecar {
|
||||
block_root: blob_sidecar.block_root,
|
||||
block_root: blob_sidecar.block_root(),
|
||||
index: blob_sidecar.index,
|
||||
slot: blob_sidecar.slot,
|
||||
slot: blob_sidecar.slot(),
|
||||
kzg_commitment: blob_sidecar.kzg_commitment,
|
||||
versioned_hash: blob_sidecar.kzg_commitment.calculate_versioned_hash(),
|
||||
}
|
||||
@@ -1411,15 +1409,14 @@ pub mod serde_status_code {
|
||||
}
|
||||
|
||||
pub enum ForkVersionedBeaconBlockType<T: EthSpec> {
|
||||
Full(ForkVersionedResponse<BlockContents<T, FullPayload<T>>>),
|
||||
Blinded(ForkVersionedResponse<BlockContents<T, BlindedPayload<T>>>),
|
||||
Full(ForkVersionedResponse<FullBlockContents<T>>),
|
||||
Blinded(ForkVersionedResponse<BlindedBeaconBlock<T>>),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ssz::Encode;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
fn query_vec() {
|
||||
@@ -1460,17 +1457,17 @@ mod tests {
|
||||
type E = MainnetEthSpec;
|
||||
let spec = ForkName::Capella.make_genesis_spec(E::default_spec());
|
||||
|
||||
let block: SignedBlockContents<E, FullPayload<E>> = SignedBeaconBlock::from_block(
|
||||
let block: PublishBlockRequest<E> = SignedBeaconBlock::from_block(
|
||||
BeaconBlock::<E>::Capella(BeaconBlockCapella::empty(&spec)),
|
||||
Signature::empty(),
|
||||
)
|
||||
.try_into()
|
||||
.expect("should convert into signed block contents");
|
||||
|
||||
let decoded: SignedBlockContents<E> =
|
||||
SignedBlockContents::from_ssz_bytes(&block.as_ssz_bytes(), &spec)
|
||||
let decoded: PublishBlockRequest<E> =
|
||||
PublishBlockRequest::from_ssz_bytes(&block.as_ssz_bytes(), &spec)
|
||||
.expect("should decode Block");
|
||||
assert!(matches!(decoded, SignedBlockContents::Block(_)));
|
||||
assert!(matches!(decoded, PublishBlockRequest::Block(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1482,87 +1479,49 @@ mod tests {
|
||||
BeaconBlock::<E>::Deneb(BeaconBlockDeneb::empty(&spec)),
|
||||
Signature::empty(),
|
||||
);
|
||||
let blobs = SignedSidecarList::from(vec![SignedSidecar {
|
||||
message: Arc::new(BlobSidecar::empty()),
|
||||
signature: Signature::empty(),
|
||||
_phantom: Default::default(),
|
||||
}]);
|
||||
let signed_block_contents = SignedBlockContents::new(block, Some(blobs));
|
||||
let blobs = BlobsList::<E>::from(vec![Blob::<E>::default()]);
|
||||
let kzg_proofs = KzgProofs::<E>::from(vec![KzgProof::empty()]);
|
||||
let signed_block_contents = PublishBlockRequest::new(block, Some((kzg_proofs, blobs)));
|
||||
|
||||
let decoded: SignedBlockContents<E, FullPayload<E>> =
|
||||
SignedBlockContents::from_ssz_bytes(&signed_block_contents.as_ssz_bytes(), &spec)
|
||||
let decoded: PublishBlockRequest<E> =
|
||||
PublishBlockRequest::from_ssz_bytes(&signed_block_contents.as_ssz_bytes(), &spec)
|
||||
.expect("should decode BlockAndBlobSidecars");
|
||||
assert!(matches!(
|
||||
decoded,
|
||||
SignedBlockContents::BlockAndBlobSidecars(_)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssz_signed_blinded_block_contents_with_blobs() {
|
||||
type E = MainnetEthSpec;
|
||||
let mut spec = E::default_spec();
|
||||
spec.altair_fork_epoch = Some(Epoch::new(0));
|
||||
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
|
||||
spec.capella_fork_epoch = Some(Epoch::new(0));
|
||||
spec.deneb_fork_epoch = Some(Epoch::new(0));
|
||||
|
||||
let blinded_block = SignedBeaconBlock::from_block(
|
||||
BeaconBlock::<E, BlindedPayload<E>>::Deneb(BeaconBlockDeneb::empty(&spec)),
|
||||
Signature::empty(),
|
||||
);
|
||||
let blinded_blobs = SignedSidecarList::from(vec![SignedSidecar {
|
||||
message: Arc::new(BlindedBlobSidecar::empty()),
|
||||
signature: Signature::empty(),
|
||||
_phantom: Default::default(),
|
||||
}]);
|
||||
let signed_block_contents = SignedBlockContents::new(blinded_block, Some(blinded_blobs));
|
||||
|
||||
let decoded: SignedBlockContents<E, BlindedPayload<E>> =
|
||||
SignedBlockContents::from_ssz_bytes(&signed_block_contents.as_ssz_bytes(), &spec)
|
||||
.expect("should decode BlindedBlockAndBlobSidecars");
|
||||
assert!(matches!(
|
||||
decoded,
|
||||
SignedBlockContents::BlindedBlockAndBlobSidecars(_)
|
||||
));
|
||||
assert!(matches!(decoded, PublishBlockRequest::BlockContents(_)));
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper over a [`BeaconBlock`] or a [`BeaconBlockAndBlobSidecars`].
|
||||
#[derive(Debug, Encode, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[serde(bound = "E: EthSpec")]
|
||||
#[ssz(enum_behaviour = "transparent")]
|
||||
pub enum ProduceBlockV3Response<E: EthSpec> {
|
||||
Full(FullBlockContents<E>),
|
||||
Blinded(BlindedBeaconBlock<E>),
|
||||
}
|
||||
|
||||
/// A wrapper over a [`BeaconBlock`] or a [`BlockContents`].
|
||||
#[derive(Debug, Encode, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
#[ssz(enum_behaviour = "transparent")]
|
||||
pub enum BlockContents<T: EthSpec, Payload: AbstractExecPayload<T>> {
|
||||
BlockAndBlobSidecars(BeaconBlockAndBlobSidecars<T, Payload>),
|
||||
BlindedBlockAndBlobSidecars(BlindedBeaconBlockAndBlobSidecars<T, Payload>),
|
||||
Block(BeaconBlock<T, Payload>),
|
||||
pub enum FullBlockContents<T: EthSpec> {
|
||||
/// This is a full deneb variant with block and blobs.
|
||||
BlockContents(BlockContents<T>),
|
||||
/// This variant is for all pre-deneb full blocks.
|
||||
Block(BeaconBlock<T>),
|
||||
}
|
||||
|
||||
pub type BlockContentsTuple<T, Payload> = (
|
||||
BeaconBlock<T, Payload>,
|
||||
Option<SidecarList<T, <Payload as AbstractExecPayload<T>>::Sidecar>>,
|
||||
);
|
||||
pub type BlockContentsTuple<T> = (BeaconBlock<T>, Option<(KzgProofs<T>, BlobsList<T>)>);
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> BlockContents<T, Payload> {
|
||||
pub fn new(
|
||||
block: BeaconBlock<T, Payload>,
|
||||
blobs: Option<SidecarList<T, Payload::Sidecar>>,
|
||||
) -> Self {
|
||||
match (Payload::block_type(), blobs) {
|
||||
(BlockType::Full, Some(blobs)) => {
|
||||
Self::BlockAndBlobSidecars(BeaconBlockAndBlobSidecars {
|
||||
block,
|
||||
blob_sidecars: blobs,
|
||||
})
|
||||
}
|
||||
(BlockType::Blinded, Some(blobs)) => {
|
||||
Self::BlindedBlockAndBlobSidecars(BlindedBeaconBlockAndBlobSidecars {
|
||||
blinded_block: block,
|
||||
blinded_blob_sidecars: blobs,
|
||||
})
|
||||
}
|
||||
(_, None) => Self::Block(block),
|
||||
impl<T: EthSpec> FullBlockContents<T> {
|
||||
pub fn new(block: BeaconBlock<T>, blob_data: Option<(KzgProofs<T>, BlobsList<T>)>) -> Self {
|
||||
match blob_data {
|
||||
Some((kzg_proofs, blobs)) => Self::BlockContents(BlockContents {
|
||||
block,
|
||||
kzg_proofs,
|
||||
blobs,
|
||||
}),
|
||||
None => Self::Block(block),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1581,43 +1540,41 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> BlockContents<T, Payload> {
|
||||
|
||||
match fork_at_slot {
|
||||
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
|
||||
BeaconBlock::from_ssz_bytes(bytes, spec).map(|block| BlockContents::Block(block))
|
||||
BeaconBlock::from_ssz_bytes(bytes, spec)
|
||||
.map(|block| FullBlockContents::Block(block))
|
||||
}
|
||||
ForkName::Deneb => {
|
||||
let mut builder = ssz::SszDecoderBuilder::new(bytes);
|
||||
|
||||
builder.register_anonymous_variable_length_item()?;
|
||||
builder.register_type::<SidecarList<T, Payload::Sidecar>>()?;
|
||||
builder.register_type::<KzgProofs<T>>()?;
|
||||
builder.register_type::<BlobsList<T>>()?;
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
let block =
|
||||
decoder.decode_next_with(|bytes| BeaconBlock::from_ssz_bytes(bytes, spec))?;
|
||||
let kzg_proofs = decoder.decode_next()?;
|
||||
let blobs = decoder.decode_next()?;
|
||||
Ok(BlockContents::new(block, Some(blobs)))
|
||||
|
||||
Ok(FullBlockContents::new(block, Some((kzg_proofs, blobs))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block(&self) -> &BeaconBlock<T, Payload> {
|
||||
pub fn block(&self) -> &BeaconBlock<T> {
|
||||
match self {
|
||||
BlockContents::BlockAndBlobSidecars(block_and_sidecars) => &block_and_sidecars.block,
|
||||
BlockContents::BlindedBlockAndBlobSidecars(block_and_sidecars) => {
|
||||
&block_and_sidecars.blinded_block
|
||||
}
|
||||
BlockContents::Block(block) => block,
|
||||
FullBlockContents::BlockContents(block_and_sidecars) => &block_and_sidecars.block,
|
||||
FullBlockContents::Block(block) => block,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deconstruct(self) -> BlockContentsTuple<T, Payload> {
|
||||
pub fn deconstruct(self) -> BlockContentsTuple<T> {
|
||||
match self {
|
||||
BlockContents::BlockAndBlobSidecars(block_and_sidecars) => (
|
||||
FullBlockContents::BlockContents(block_and_sidecars) => (
|
||||
block_and_sidecars.block,
|
||||
Some(block_and_sidecars.blob_sidecars),
|
||||
Some((block_and_sidecars.kzg_proofs, block_and_sidecars.blobs)),
|
||||
),
|
||||
BlockContents::BlindedBlockAndBlobSidecars(block_and_sidecars) => (
|
||||
block_and_sidecars.blinded_block,
|
||||
Some(block_and_sidecars.blinded_blob_sidecars),
|
||||
),
|
||||
BlockContents::Block(block) => (block, None),
|
||||
FullBlockContents::Block(block) => (block, None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1628,104 +1585,64 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> BlockContents<T, Payload> {
|
||||
fork: &Fork,
|
||||
genesis_validators_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> SignedBlockContents<T, Payload> {
|
||||
) -> PublishBlockRequest<T> {
|
||||
let (block, maybe_blobs) = self.deconstruct();
|
||||
let signed_block = block.sign(secret_key, fork, genesis_validators_root, spec);
|
||||
let signed_blobs = maybe_blobs.map(|blobs| {
|
||||
blobs
|
||||
.into_iter()
|
||||
.map(|blob| blob.sign(secret_key, fork, genesis_validators_root, spec))
|
||||
.collect::<Vec<_>>()
|
||||
.into()
|
||||
});
|
||||
SignedBlockContents::new(signed_block, signed_blobs)
|
||||
PublishBlockRequest::new(signed_block, maybe_blobs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> ForkVersionDeserialize
|
||||
for BlockContents<T, Payload>
|
||||
{
|
||||
impl<T: EthSpec> ForkVersionDeserialize for FullBlockContents<T> {
|
||||
fn deserialize_by_fork<'de, D: serde::Deserializer<'de>>(
|
||||
value: serde_json::value::Value,
|
||||
fork_name: ForkName,
|
||||
) -> Result<Self, D::Error> {
|
||||
match fork_name {
|
||||
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
|
||||
Ok(BlockContents::Block(BeaconBlock::deserialize_by_fork::<
|
||||
'de,
|
||||
D,
|
||||
>(value, fork_name)?))
|
||||
}
|
||||
ForkName::Deneb => {
|
||||
let block_contents = match Payload::block_type() {
|
||||
BlockType::Blinded => BlockContents::BlindedBlockAndBlobSidecars(
|
||||
BlindedBeaconBlockAndBlobSidecars::deserialize_by_fork::<'de, D>(
|
||||
value, fork_name,
|
||||
)?,
|
||||
),
|
||||
BlockType::Full => BlockContents::BlockAndBlobSidecars(
|
||||
BeaconBlockAndBlobSidecars::deserialize_by_fork::<'de, D>(
|
||||
value, fork_name,
|
||||
)?,
|
||||
),
|
||||
};
|
||||
Ok(block_contents)
|
||||
Ok(FullBlockContents::Block(
|
||||
BeaconBlock::deserialize_by_fork::<'de, D>(value, fork_name)?,
|
||||
))
|
||||
}
|
||||
ForkName::Deneb => Ok(FullBlockContents::BlockContents(
|
||||
BlockContents::deserialize_by_fork::<'de, D>(value, fork_name)?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> Into<BeaconBlock<T, Payload>>
|
||||
for BlockContents<T, Payload>
|
||||
{
|
||||
fn into(self) -> BeaconBlock<T, Payload> {
|
||||
impl<T: EthSpec> Into<BeaconBlock<T>> for FullBlockContents<T> {
|
||||
fn into(self) -> BeaconBlock<T> {
|
||||
match self {
|
||||
Self::BlockAndBlobSidecars(block_and_sidecars) => block_and_sidecars.block,
|
||||
Self::BlindedBlockAndBlobSidecars(block_and_sidecars) => {
|
||||
block_and_sidecars.blinded_block
|
||||
}
|
||||
Self::BlockContents(block_and_sidecars) => block_and_sidecars.block,
|
||||
Self::Block(block) => block,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type SignedBlockContentsTuple<T, Payload> = (
|
||||
SignedBeaconBlock<T, Payload>,
|
||||
Option<SignedSidecarList<T, <Payload as AbstractExecPayload<T>>::Sidecar>>,
|
||||
);
|
||||
pub type SignedBlockContentsTuple<T> = (SignedBeaconBlock<T>, Option<(KzgProofs<T>, BlobsList<T>)>);
|
||||
|
||||
pub type SignedBlindedBlockContents<E> = SignedBlockContents<E, BlindedPayload<E>>;
|
||||
|
||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobSidecars`].
|
||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBlockContents`].
|
||||
#[derive(Clone, Debug, Encode, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
#[ssz(enum_behaviour = "transparent")]
|
||||
pub enum SignedBlockContents<T: EthSpec, Payload: AbstractExecPayload<T> = FullPayload<T>> {
|
||||
BlockAndBlobSidecars(SignedBeaconBlockAndBlobSidecars<T, Payload>),
|
||||
BlindedBlockAndBlobSidecars(SignedBlindedBeaconBlockAndBlobSidecars<T, Payload>),
|
||||
Block(SignedBeaconBlock<T, Payload>),
|
||||
pub enum PublishBlockRequest<T: EthSpec> {
|
||||
BlockContents(SignedBlockContents<T>),
|
||||
Block(SignedBeaconBlock<T>),
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> SignedBlockContents<T, Payload> {
|
||||
impl<T: EthSpec> PublishBlockRequest<T> {
|
||||
pub fn new(
|
||||
block: SignedBeaconBlock<T, Payload>,
|
||||
blobs: Option<SignedSidecarList<T, Payload::Sidecar>>,
|
||||
block: SignedBeaconBlock<T>,
|
||||
blob_items: Option<(KzgProofs<T>, BlobsList<T>)>,
|
||||
) -> Self {
|
||||
match (Payload::block_type(), blobs) {
|
||||
(BlockType::Full, Some(blobs)) => {
|
||||
Self::BlockAndBlobSidecars(SignedBeaconBlockAndBlobSidecars {
|
||||
signed_block: block,
|
||||
signed_blob_sidecars: blobs,
|
||||
})
|
||||
}
|
||||
(BlockType::Blinded, Some(blobs)) => {
|
||||
Self::BlindedBlockAndBlobSidecars(SignedBlindedBeaconBlockAndBlobSidecars {
|
||||
signed_blinded_block: block,
|
||||
signed_blinded_blob_sidecars: blobs,
|
||||
})
|
||||
}
|
||||
(_, None) => Self::Block(block),
|
||||
match blob_items {
|
||||
Some((kzg_proofs, blobs)) => Self::BlockContents(SignedBlockContents {
|
||||
signed_block: block,
|
||||
kzg_proofs,
|
||||
blobs,
|
||||
}),
|
||||
None => Self::Block(block),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1745,133 +1662,88 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> SignedBlockContents<T, Payload
|
||||
match fork_at_slot {
|
||||
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
|
||||
SignedBeaconBlock::from_ssz_bytes(bytes, spec)
|
||||
.map(|block| SignedBlockContents::Block(block))
|
||||
.map(|block| PublishBlockRequest::Block(block))
|
||||
}
|
||||
ForkName::Deneb => {
|
||||
let mut builder = ssz::SszDecoderBuilder::new(bytes);
|
||||
builder.register_anonymous_variable_length_item()?;
|
||||
builder.register_type::<SignedSidecarList<T, Payload::Sidecar>>()?;
|
||||
builder.register_type::<KzgProofs<T>>()?;
|
||||
builder.register_type::<BlobsList<T>>()?;
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
let block = decoder
|
||||
.decode_next_with(|bytes| SignedBeaconBlock::from_ssz_bytes(bytes, spec))?;
|
||||
let kzg_proofs = decoder.decode_next()?;
|
||||
let blobs = decoder.decode_next()?;
|
||||
Ok(SignedBlockContents::new(block, Some(blobs)))
|
||||
Ok(PublishBlockRequest::new(block, Some((kzg_proofs, blobs))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signed_block(&self) -> &SignedBeaconBlock<T, Payload> {
|
||||
pub fn signed_block(&self) -> &SignedBeaconBlock<T> {
|
||||
match self {
|
||||
SignedBlockContents::BlockAndBlobSidecars(block_and_sidecars) => {
|
||||
PublishBlockRequest::BlockContents(block_and_sidecars) => {
|
||||
&block_and_sidecars.signed_block
|
||||
}
|
||||
SignedBlockContents::BlindedBlockAndBlobSidecars(block_and_sidecars) => {
|
||||
&block_and_sidecars.signed_blinded_block
|
||||
}
|
||||
SignedBlockContents::Block(block) => block,
|
||||
PublishBlockRequest::Block(block) => block,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blobs_cloned(&self) -> Option<SignedSidecarList<T, Payload::Sidecar>> {
|
||||
pub fn deconstruct(self) -> SignedBlockContentsTuple<T> {
|
||||
match self {
|
||||
SignedBlockContents::BlockAndBlobSidecars(block_and_sidecars) => {
|
||||
Some(block_and_sidecars.signed_blob_sidecars.clone())
|
||||
}
|
||||
SignedBlockContents::BlindedBlockAndBlobSidecars(block_and_sidecars) => {
|
||||
Some(block_and_sidecars.signed_blinded_blob_sidecars.clone())
|
||||
}
|
||||
SignedBlockContents::Block(_block) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deconstruct(self) -> SignedBlockContentsTuple<T, Payload> {
|
||||
match self {
|
||||
SignedBlockContents::BlockAndBlobSidecars(block_and_sidecars) => (
|
||||
PublishBlockRequest::BlockContents(block_and_sidecars) => (
|
||||
block_and_sidecars.signed_block,
|
||||
Some(block_and_sidecars.signed_blob_sidecars),
|
||||
Some((block_and_sidecars.kzg_proofs, block_and_sidecars.blobs)),
|
||||
),
|
||||
SignedBlockContents::BlindedBlockAndBlobSidecars(block_and_sidecars) => (
|
||||
block_and_sidecars.signed_blinded_block,
|
||||
Some(block_and_sidecars.signed_blinded_blob_sidecars),
|
||||
),
|
||||
SignedBlockContents::Block(block) => (block, None),
|
||||
PublishBlockRequest::Block(block) => (block, None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> SignedBlockContents<T, BlindedPayload<T>> {
|
||||
pub fn try_into_full_block_and_blobs(
|
||||
self,
|
||||
maybe_full_payload_contents: Option<FullPayloadContents<T>>,
|
||||
) -> Result<SignedBlockContents<T, FullPayload<T>>, String> {
|
||||
match self {
|
||||
SignedBlockContents::BlindedBlockAndBlobSidecars(blinded_block_and_blob_sidecars) => {
|
||||
match maybe_full_payload_contents {
|
||||
None | Some(FullPayloadContents::Payload(_)) => {
|
||||
Err("Can't build full block contents without payload and blobs".to_string())
|
||||
}
|
||||
Some(FullPayloadContents::PayloadAndBlobs(payload_and_blobs)) => {
|
||||
let signed_block = blinded_block_and_blob_sidecars
|
||||
.signed_blinded_block
|
||||
.try_into_full_block(Some(payload_and_blobs.execution_payload))
|
||||
.ok_or("Failed to build full block with payload".to_string())?;
|
||||
let signed_blob_sidecars: SignedBlobSidecarList<T> =
|
||||
blinded_block_and_blob_sidecars
|
||||
.signed_blinded_blob_sidecars
|
||||
.into_iter()
|
||||
.zip(payload_and_blobs.blobs_bundle.blobs)
|
||||
.map(|(blinded_blob_sidecar, blob)| {
|
||||
blinded_blob_sidecar.into_full_blob_sidecars(blob)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into();
|
||||
/// Converting from a `SignedBlindedBeaconBlock` into a full `SignedBlockContents`.
|
||||
pub fn into_full_block_and_blobs<T: EthSpec>(
|
||||
blinded_block: SignedBlindedBeaconBlock<T>,
|
||||
maybe_full_payload_contents: Option<FullPayloadContents<T>>,
|
||||
) -> Result<PublishBlockRequest<T>, String> {
|
||||
match maybe_full_payload_contents {
|
||||
None => {
|
||||
let signed_block = blinded_block
|
||||
.try_into_full_block(None)
|
||||
.ok_or("Failed to build full block with payload".to_string())?;
|
||||
Ok(PublishBlockRequest::new(signed_block, None))
|
||||
}
|
||||
// This variant implies a pre-deneb block
|
||||
Some(FullPayloadContents::Payload(execution_payload)) => {
|
||||
let signed_block = blinded_block
|
||||
.try_into_full_block(Some(execution_payload))
|
||||
.ok_or("Failed to build full block with payload".to_string())?;
|
||||
Ok(PublishBlockRequest::new(signed_block, None))
|
||||
}
|
||||
// This variant implies a post-deneb block
|
||||
Some(FullPayloadContents::PayloadAndBlobs(payload_and_blobs)) => {
|
||||
let signed_block = blinded_block
|
||||
.try_into_full_block(Some(payload_and_blobs.execution_payload))
|
||||
.ok_or("Failed to build full block with payload".to_string())?;
|
||||
|
||||
Ok(SignedBlockContents::new(
|
||||
signed_block,
|
||||
Some(signed_blob_sidecars),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
SignedBlockContents::Block(blinded_block) => {
|
||||
let full_payload_opt = maybe_full_payload_contents.map(|o| o.deconstruct().0);
|
||||
blinded_block
|
||||
.try_into_full_block(full_payload_opt)
|
||||
.map(SignedBlockContents::Block)
|
||||
.ok_or("Can't build full block without payload".to_string())
|
||||
}
|
||||
SignedBlockContents::BlockAndBlobSidecars(_) => Err(
|
||||
"BlockAndBlobSidecars variant not expected when constructing full block"
|
||||
.to_string(),
|
||||
),
|
||||
Ok(PublishBlockRequest::new(
|
||||
signed_block,
|
||||
Some((
|
||||
payload_and_blobs.blobs_bundle.proofs,
|
||||
payload_and_blobs.blobs_bundle.blobs,
|
||||
)),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> SignedBlockContents<T> {
|
||||
pub fn clone_as_blinded(&self) -> SignedBlindedBlockContents<T> {
|
||||
let blinded_blobs = self.blobs_cloned().map(|blob_sidecars| {
|
||||
blob_sidecars
|
||||
.into_iter()
|
||||
.map(|blob| blob.into())
|
||||
.collect::<Vec<_>>()
|
||||
.into()
|
||||
});
|
||||
SignedBlockContents::new(self.signed_block().clone_as_blinded(), blinded_blobs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> TryFrom<SignedBeaconBlock<T, Payload>>
|
||||
for SignedBlockContents<T, Payload>
|
||||
{
|
||||
impl<T: EthSpec> TryFrom<SignedBeaconBlock<T>> for PublishBlockRequest<T> {
|
||||
type Error = &'static str;
|
||||
fn try_from(block: SignedBeaconBlock<T, Payload>) -> Result<Self, Self::Error> {
|
||||
fn try_from(block: SignedBeaconBlock<T>) -> Result<Self, Self::Error> {
|
||||
match block {
|
||||
SignedBeaconBlock::Base(_)
|
||||
| SignedBeaconBlock::Altair(_)
|
||||
| SignedBeaconBlock::Merge(_)
|
||||
| SignedBeaconBlock::Capella(_) => Ok(SignedBlockContents::Block(block)),
|
||||
| SignedBeaconBlock::Capella(_) => Ok(PublishBlockRequest::Block(block)),
|
||||
SignedBeaconBlock::Deneb(_) => {
|
||||
Err("deneb block contents cannot be fully constructed from just the signed block")
|
||||
}
|
||||
@@ -1879,93 +1751,49 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> TryFrom<SignedBeaconBlock<T, P
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> From<SignedBlockContentsTuple<T, Payload>>
|
||||
for SignedBlockContents<T, Payload>
|
||||
{
|
||||
fn from(block_contents_tuple: SignedBlockContentsTuple<T, Payload>) -> Self {
|
||||
SignedBlockContents::new(block_contents_tuple.0, block_contents_tuple.1)
|
||||
impl<T: EthSpec> From<SignedBlockContentsTuple<T>> for PublishBlockRequest<T> {
|
||||
fn from(block_contents_tuple: SignedBlockContentsTuple<T>) -> Self {
|
||||
PublishBlockRequest::new(block_contents_tuple.0, block_contents_tuple.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Encode)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct SignedBeaconBlockAndBlobSidecars<T: EthSpec, Payload: AbstractExecPayload<T>> {
|
||||
pub signed_block: SignedBeaconBlock<T, Payload>,
|
||||
pub signed_blob_sidecars: SignedSidecarList<T, Payload::Sidecar>,
|
||||
pub struct SignedBlockContents<T: EthSpec> {
|
||||
pub signed_block: SignedBeaconBlock<T>,
|
||||
pub kzg_proofs: KzgProofs<T>,
|
||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_fixed_vec")]
|
||||
pub blobs: BlobsList<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Encode)]
|
||||
#[serde(bound = "T: EthSpec, Payload: AbstractExecPayload<T>")]
|
||||
pub struct BeaconBlockAndBlobSidecars<T: EthSpec, Payload: AbstractExecPayload<T>> {
|
||||
pub block: BeaconBlock<T, Payload>,
|
||||
pub blob_sidecars: SidecarList<T, Payload::Sidecar>,
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct BlockContents<T: EthSpec> {
|
||||
pub block: BeaconBlock<T>,
|
||||
pub kzg_proofs: KzgProofs<T>,
|
||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_fixed_vec")]
|
||||
pub blobs: BlobsList<T>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> ForkVersionDeserialize
|
||||
for BeaconBlockAndBlobSidecars<T, Payload>
|
||||
{
|
||||
impl<T: EthSpec> ForkVersionDeserialize for BlockContents<T> {
|
||||
fn deserialize_by_fork<'de, D: serde::Deserializer<'de>>(
|
||||
value: serde_json::value::Value,
|
||||
fork_name: ForkName,
|
||||
) -> Result<Self, D::Error> {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(bound = "T: EthSpec, S: Sidecar<T>")]
|
||||
struct Helper<T: EthSpec, S: Sidecar<T>> {
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
struct Helper<T: EthSpec> {
|
||||
block: serde_json::Value,
|
||||
blob_sidecars: SidecarList<T, S>,
|
||||
kzg_proofs: KzgProofs<T>,
|
||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_fixed_vec")]
|
||||
blobs: BlobsList<T>,
|
||||
}
|
||||
let helper: Helper<T, Payload::Sidecar> =
|
||||
serde_json::from_value(value).map_err(serde::de::Error::custom)?;
|
||||
let helper: Helper<T> = serde_json::from_value(value).map_err(serde::de::Error::custom)?;
|
||||
|
||||
Ok(Self {
|
||||
block: BeaconBlock::deserialize_by_fork::<'de, D>(helper.block, fork_name)?,
|
||||
blob_sidecars: helper.blob_sidecars,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Encode)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct SignedBlindedBeaconBlockAndBlobSidecars<
|
||||
T: EthSpec,
|
||||
Payload: AbstractExecPayload<T> = BlindedPayload<T>,
|
||||
> {
|
||||
pub signed_blinded_block: SignedBeaconBlock<T, Payload>,
|
||||
pub signed_blinded_blob_sidecars: SignedSidecarList<T, Payload::Sidecar>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Encode)]
|
||||
#[serde(bound = "T: EthSpec, Payload: AbstractExecPayload<T>")]
|
||||
pub struct BlindedBeaconBlockAndBlobSidecars<
|
||||
T: EthSpec,
|
||||
Payload: AbstractExecPayload<T> = BlindedPayload<T>,
|
||||
> {
|
||||
pub blinded_block: BeaconBlock<T, Payload>,
|
||||
pub blinded_blob_sidecars: SidecarList<T, Payload::Sidecar>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> ForkVersionDeserialize
|
||||
for BlindedBeaconBlockAndBlobSidecars<T, Payload>
|
||||
{
|
||||
fn deserialize_by_fork<'de, D: serde::Deserializer<'de>>(
|
||||
value: serde_json::value::Value,
|
||||
fork_name: ForkName,
|
||||
) -> Result<Self, D::Error> {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(bound = "T: EthSpec, S: Sidecar<T>")]
|
||||
struct Helper<T: EthSpec, S: Sidecar<T>> {
|
||||
blinded_block: serde_json::Value,
|
||||
blinded_blob_sidecars: SidecarList<T, S>,
|
||||
}
|
||||
let helper: Helper<T, Payload::Sidecar> =
|
||||
serde_json::from_value(value).map_err(serde::de::Error::custom)?;
|
||||
|
||||
Ok(Self {
|
||||
blinded_block: BeaconBlock::deserialize_by_fork::<'de, D>(
|
||||
helper.blinded_block,
|
||||
fork_name,
|
||||
)?,
|
||||
blinded_blob_sidecars: helper.blinded_blob_sidecars,
|
||||
kzg_proofs: helper.kzg_proofs,
|
||||
blobs: helper.blobs,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2051,18 +1879,3 @@ pub struct BlobsBundle<E: EthSpec> {
|
||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_fixed_vec")]
|
||||
pub blobs: BlobsList<E>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Into<BlindedBlobsBundle<E>> for BlobsBundle<E> {
|
||||
fn into(self) -> BlindedBlobsBundle<E> {
|
||||
BlindedBlobsBundle {
|
||||
commitments: self.commitments,
|
||||
proofs: self.proofs,
|
||||
blob_roots: self
|
||||
.blobs
|
||||
.into_iter()
|
||||
.map(|blob| blob.tree_hash_root())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user