mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 22:04:44 +00:00
Implement /eth/v1/beacon/blobs endpoint (#8103)
* #8085 Co-Authored-By: Tan Chee Keong <tanck@sigmaprime.io> Co-Authored-By: chonghe <44791194+chong-he@users.noreply.github.com>
This commit is contained in:
@@ -2,15 +2,16 @@ use crate::version::inconsistent_fork_rejection;
|
||||
use crate::{ExecutionOptimistic, state_id::checkpoint_slot_and_execution_optimistic};
|
||||
use beacon_chain::kzg_utils::reconstruct_blobs;
|
||||
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes, WhenSlotSkipped};
|
||||
use eth2::types::BlobIndicesQuery;
|
||||
use eth2::types::BlockId as CoreBlockId;
|
||||
use eth2::types::DataColumnIndicesQuery;
|
||||
use eth2::types::{BlobIndicesQuery, BlobWrapper, BlobsVersionedHashesQuery};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use types::{
|
||||
BlobSidecarList, DataColumnSidecarList, EthSpec, FixedBytesExtended, ForkName, Hash256,
|
||||
SignedBeaconBlock, SignedBlindedBeaconBlock, Slot,
|
||||
SignedBeaconBlock, SignedBlindedBeaconBlock, Slot, UnversionedResponse,
|
||||
beacon_response::ExecutionOptimisticFinalizedMetadata,
|
||||
};
|
||||
use warp::Rejection;
|
||||
|
||||
@@ -352,6 +353,68 @@ impl BlockId {
|
||||
Ok((block, blob_sidecar_list, execution_optimistic, finalized))
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn get_blobs_by_versioned_hashes<T: BeaconChainTypes>(
|
||||
&self,
|
||||
query: BlobsVersionedHashesQuery,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<
|
||||
UnversionedResponse<Vec<BlobWrapper<T::EthSpec>>, ExecutionOptimisticFinalizedMetadata>,
|
||||
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))
|
||||
})?;
|
||||
|
||||
// Error if the block is pre-Deneb and lacks blobs.
|
||||
let blob_kzg_commitments = block.message().body().blob_kzg_commitments().map_err(|_| {
|
||||
warp_utils::reject::custom_bad_request(
|
||||
"block is pre-Deneb and has no blobs".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let blob_indices_opt = query.versioned_hashes.map(|versioned_hashes| {
|
||||
versioned_hashes
|
||||
.iter()
|
||||
.flat_map(|versioned_hash| {
|
||||
blob_kzg_commitments.iter().position(|commitment| {
|
||||
let computed_hash = commitment.calculate_versioned_hash();
|
||||
computed_hash == *versioned_hash
|
||||
})
|
||||
})
|
||||
.map(|index| index as u64)
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
let max_blobs_per_block = chain.spec.max_blobs_per_block(block.epoch()) as usize;
|
||||
let blob_sidecar_list = if !blob_kzg_commitments.is_empty() {
|
||||
if chain.spec.is_peer_das_enabled_for_epoch(block.epoch()) {
|
||||
Self::get_blobs_from_data_columns(chain, root, blob_indices_opt, &block)?
|
||||
} else {
|
||||
Self::get_blobs(chain, root, blob_indices_opt, max_blobs_per_block)?
|
||||
}
|
||||
} else {
|
||||
BlobSidecarList::new(vec![], max_blobs_per_block)
|
||||
.map_err(|e| warp_utils::reject::custom_server_error(format!("{:?}", e)))?
|
||||
};
|
||||
|
||||
let blobs = blob_sidecar_list
|
||||
.into_iter()
|
||||
.map(|sidecar| BlobWrapper::<T::EthSpec> {
|
||||
blob: sidecar.blob.clone(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(UnversionedResponse {
|
||||
metadata: ExecutionOptimisticFinalizedMetadata {
|
||||
execution_optimistic: Some(execution_optimistic),
|
||||
finalized: Some(finalized),
|
||||
},
|
||||
data: blobs,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_blobs<T: BeaconChainTypes>(
|
||||
chain: &BeaconChain<T>,
|
||||
root: Hash256,
|
||||
@@ -369,9 +432,9 @@ impl BlockId {
|
||||
|
||||
let blob_sidecar_list_filtered = match indices {
|
||||
Some(vec) => {
|
||||
let list: Vec<_> = blob_sidecar_list
|
||||
let list: Vec<_> = vec
|
||||
.into_iter()
|
||||
.filter(|blob_sidecar| vec.contains(&blob_sidecar.index))
|
||||
.flat_map(|index| blob_sidecar_list.get(index as usize).cloned())
|
||||
.collect();
|
||||
|
||||
BlobSidecarList::new(list, max_blobs_per_block)
|
||||
|
||||
Reference in New Issue
Block a user