diff --git a/beacon_node/http_api/src/block_id.rs b/beacon_node/http_api/src/block_id.rs index 45fc651f05..f35df2f5e8 100644 --- a/beacon_node/http_api/src/block_id.rs +++ b/beacon_node/http_api/src/block_id.rs @@ -123,6 +123,15 @@ impl BlockId { } } + pub fn blinded_block_by_root( + root: &Hash256, + chain: &BeaconChain, + ) -> Result>, warp::Rejection> { + chain + .get_blinded_block(root) + .map_err(warp_utils::reject::beacon_chain_error) + } + /// Return the `SignedBeaconBlock` identified by `self`. pub fn blinded_block( &self, @@ -149,38 +158,32 @@ impl BlockId { } CoreBlockId::Slot(slot) => { let (root, execution_optimistic, finalized) = self.root(chain)?; - chain - .get_blinded_block(&root) - .map_err(warp_utils::reject::beacon_chain_error) - .and_then(|block_opt| match block_opt { - Some(block) => { - if block.slot() != *slot { - return Err(warp_utils::reject::custom_not_found(format!( - "slot {} was skipped", - slot - ))); - } - Ok((block, execution_optimistic, finalized)) + BlockId::blinded_block_by_root(&root, chain).and_then(|block_opt| match block_opt { + Some(block) => { + if block.slot() != *slot { + return Err(warp_utils::reject::custom_not_found(format!( + "slot {} was skipped", + slot + ))); } - None => Err(warp_utils::reject::custom_not_found(format!( - "beacon block with root {}", - root - ))), - }) + Ok((block, execution_optimistic, finalized)) + } + None => Err(warp_utils::reject::custom_not_found(format!( + "beacon block with root {}", + root + ))), + }) } _ => { let (root, execution_optimistic, finalized) = self.root(chain)?; - let block = chain - .get_blinded_block(&root) - .map_err(warp_utils::reject::beacon_chain_error) - .and_then(|root_opt| { - root_opt.ok_or_else(|| { - warp_utils::reject::custom_not_found(format!( - "beacon block with root {}", - root - )) - }) - })?; + let block = BlockId::blinded_block_by_root(&root, chain).and_then(|root_opt| { + root_opt.ok_or_else(|| { + warp_utils::reject::custom_not_found(format!( + "beacon block with root {}", + root + )) + }) + })?; Ok((block, execution_optimistic, finalized)) } } @@ -252,23 +255,30 @@ impl BlockId { } } - /// Return the `BlobSidecarList` identified by `self`. - pub fn blob_sidecar_list( - &self, - chain: &BeaconChain, - ) -> Result, warp::Rejection> { - let root = self.root(chain)?.0; - chain - .get_blobs(&root) - .map_err(warp_utils::reject::beacon_chain_error) - } - - pub fn blob_sidecar_list_filtered( + #[allow(clippy::type_complexity)] + pub fn get_blinded_block_and_blob_list_filtered( &self, indices: BlobIndicesQuery, chain: &BeaconChain, - ) -> Result, warp::Rejection> { - let blob_sidecar_list = self.blob_sidecar_list(chain)?; + ) -> Result< + ( + SignedBlindedBeaconBlock, + BlobSidecarList, + ExecutionOptimistic, + Finalized, + ), + warp::Rejection, + > { + let (root, execution_optimistic, finalized) = self.root(chain)?; + let block = BlockId::blinded_block_by_root(&root, chain)?.ok_or_else(|| { + warp_utils::reject::custom_not_found(format!("beacon block with root {}", root)) + })?; + + // Return the `BlobSidecarList` identified by `self`. + let blob_sidecar_list = chain + .get_blobs(&root) + .map_err(warp_utils::reject::beacon_chain_error)?; + let blob_sidecar_list_filtered = match indices.indices { Some(vec) => { let list = blob_sidecar_list @@ -280,7 +290,12 @@ impl BlockId { } None => blob_sidecar_list, }; - Ok(blob_sidecar_list_filtered) + Ok(( + block, + blob_sidecar_list_filtered, + execution_optimistic, + finalized, + )) } } diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index aa47d5c464..93499b7c38 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1736,8 +1736,12 @@ pub fn serve( accept_header: Option| { task_spawner.blocking_response_task(Priority::P1, move || { let indices = indices_res?; - let blob_sidecar_list_filtered = - block_id.blob_sidecar_list_filtered(indices, &chain)?; + let (block, blob_sidecar_list_filtered, execution_optimistic, finalized) = + block_id.get_blinded_block_and_blob_list_filtered(indices, &chain)?; + let fork_name = block + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + match accept_header { Some(api_types::Accept::Ssz) => Response::builder() .status(200) @@ -1749,11 +1753,19 @@ pub fn serve( e )) }), - _ => Ok(warp::reply::json(&api_types::GenericResponse::from( - blob_sidecar_list_filtered, - )) - .into_response()), + _ => { + // Post as a V2 endpoint so we return the fork version. + let res = execution_optimistic_finalized_fork_versioned_response( + V2, + fork_name, + execution_optimistic, + finalized, + &blob_sidecar_list_filtered, + )?; + Ok(warp::reply::json(&res).into_response()) + } } + .map(|resp| add_consensus_version_header(resp, fork_name)) }) }, ); diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index f0c25124dd..2805d36b90 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1141,7 +1141,8 @@ impl BeaconNodeHttpClient { &self, block_id: BlockId, indices: Option<&[u64]>, - ) -> Result>>, Error> { + ) -> Result>>, Error> + { let mut path = self.get_blobs_path(block_id)?; if let Some(indices) = indices { let indices_string = indices diff --git a/consensus/types/src/blob_sidecar.rs b/consensus/types/src/blob_sidecar.rs index 6b32523c35..0f7dbb2673 100644 --- a/consensus/types/src/blob_sidecar.rs +++ b/consensus/types/src/blob_sidecar.rs @@ -1,9 +1,10 @@ use crate::test_utils::TestRandom; +use crate::ForkName; use crate::{ beacon_block_body::BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockHeader, BeaconStateError, Blob, Epoch, EthSpec, FixedVector, Hash256, SignedBeaconBlockHeader, Slot, VariableList, }; -use crate::{KzgProofs, SignedBeaconBlock}; +use crate::{ForkVersionDeserialize, KzgProofs, SignedBeaconBlock}; use bls::Signature; use derivative::Derivative; use kzg::{Blob as KzgBlob, Kzg, KzgCommitment, KzgProof, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT}; @@ -273,3 +274,12 @@ pub type BlobSidecarList = VariableList>, :: pub type FixedBlobSidecarList = FixedVector>>, ::MaxBlobsPerBlock>; pub type BlobsList = VariableList, ::MaxBlobCommitmentsPerBlock>; + +impl ForkVersionDeserialize for BlobSidecarList { + fn deserialize_by_fork<'de, D: serde::Deserializer<'de>>( + value: serde_json::value::Value, + _: ForkName, + ) -> Result { + serde_json::from_value::>(value).map_err(serde::de::Error::custom) + } +}