mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 12:47:05 +00:00
Implement get validator block endpoint for EIP-4844
This commit is contained in:
@@ -4759,30 +4759,41 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.kzg
|
||||
.as_ref()
|
||||
.ok_or(BlockProductionError::TrustedSetupNotInitialized)?;
|
||||
let kzg_aggregated_proof =
|
||||
kzg_utils::compute_aggregate_kzg_proof::<T::EthSpec>(kzg, &blobs)
|
||||
.map_err(BlockProductionError::KzgError)?;
|
||||
let beacon_block_root = block.canonical_root();
|
||||
let expected_kzg_commitments = block.body().blob_kzg_commitments().map_err(|_| {
|
||||
BlockProductionError::InvalidBlockVariant(
|
||||
"EIP4844 block does not contain kzg commitments".to_string(),
|
||||
)
|
||||
})?;
|
||||
let blobs_sidecar = BlobsSidecar {
|
||||
beacon_block_slot: slot,
|
||||
beacon_block_root,
|
||||
blobs,
|
||||
kzg_aggregated_proof,
|
||||
};
|
||||
kzg_utils::validate_blobs_sidecar(
|
||||
kzg,
|
||||
slot,
|
||||
beacon_block_root,
|
||||
expected_kzg_commitments,
|
||||
&blobs_sidecar,
|
||||
)
|
||||
.map_err(BlockProductionError::KzgError)?;
|
||||
self.blob_cache.put(beacon_block_root, blobs_sidecar);
|
||||
|
||||
let blob_sidecars = VariableList::from(
|
||||
blobs
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(blob_index, blob)| {
|
||||
BlobSidecar {
|
||||
block_root: beacon_block_root,
|
||||
index: blob_index as u64,
|
||||
slot,
|
||||
block_parent_root: block.parent_root(),
|
||||
proposer_index,
|
||||
blob,
|
||||
kzg_commitment: expected_kzg_commitments[blob_index].clone(),
|
||||
kzg_proof: Default::default(), // TODO: compute KZG proof
|
||||
}
|
||||
})
|
||||
.collect::<Vec<BlobSidecar<T::EthSpec>>>(),
|
||||
);
|
||||
|
||||
// TODO: validate blobs
|
||||
// kzg_utils::validate_blobs_sidecar(
|
||||
// kzg,
|
||||
// slot,
|
||||
// beacon_block_root,
|
||||
// expected_kzg_commitments,
|
||||
// &blobs_sidecar,
|
||||
// ).map_err(BlockProductionError::KzgError)?;
|
||||
self.blob_cache.put(beacon_block_root, blob_sidecars);
|
||||
}
|
||||
|
||||
metrics::inc_counter(&metrics::BLOCK_PRODUCTION_SUCCESSES);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use lru::LruCache;
|
||||
use parking_lot::Mutex;
|
||||
use types::{BlobsSidecar, EthSpec, Hash256};
|
||||
use types::{BlobSidecars, EthSpec, Hash256};
|
||||
|
||||
pub const DEFAULT_BLOB_CACHE_SIZE: usize = 10;
|
||||
|
||||
/// A cache blobs by beacon block root.
|
||||
pub struct BlobCache<T: EthSpec> {
|
||||
blobs: Mutex<LruCache<BlobCacheId, BlobsSidecar<T>>>,
|
||||
blobs: Mutex<LruCache<BlobCacheId, BlobSidecars<T>>>,
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq)]
|
||||
@@ -21,11 +21,11 @@ impl<T: EthSpec> Default for BlobCache<T> {
|
||||
}
|
||||
|
||||
impl<T: EthSpec> BlobCache<T> {
|
||||
pub fn put(&self, beacon_block: Hash256, blobs: BlobsSidecar<T>) -> Option<BlobsSidecar<T>> {
|
||||
pub fn put(&self, beacon_block: Hash256, blobs: BlobSidecars<T>) -> Option<BlobSidecars<T>> {
|
||||
self.blobs.lock().put(BlobCacheId(beacon_block), blobs)
|
||||
}
|
||||
|
||||
pub fn pop(&self, root: &Hash256) -> Option<BlobsSidecar<T>> {
|
||||
pub fn pop(&self, root: &Hash256) -> Option<BlobSidecars<T>> {
|
||||
self.blobs.lock().pop(&BlobCacheId(*root))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,6 +266,7 @@ pub enum BlockProductionError {
|
||||
blob_block_hash: ExecutionBlockHash,
|
||||
payload_block_hash: ExecutionBlockHash,
|
||||
},
|
||||
NoBlobsCached,
|
||||
FailedToReadFinalizedBlock(store::Error),
|
||||
MissingFinalizedBlock(Hash256),
|
||||
BlockTooLarge(usize),
|
||||
|
||||
34
beacon_node/http_api/src/build_block_contents.rs
Normal file
34
beacon_node/http_api/src/build_block_contents.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes, BlockProductionError};
|
||||
use std::sync::Arc;
|
||||
use types::{
|
||||
AbstractExecPayload, BeaconBlock, BeaconBlockAndBlobSidecars, BlockContents, ForkName,
|
||||
};
|
||||
|
||||
type Error = warp::reject::Rejection;
|
||||
|
||||
pub fn build_block_contents<T: BeaconChainTypes, Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
fork_name: ForkName,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
block: BeaconBlock<T::EthSpec, Payload>,
|
||||
) -> Result<BlockContents<T::EthSpec, Payload>, Error> {
|
||||
match fork_name {
|
||||
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
|
||||
Ok(BlockContents::Block(block))
|
||||
}
|
||||
ForkName::Eip4844 => {
|
||||
let block_root = &block.canonical_root();
|
||||
if let Some(blob_sidecars) = chain.blob_cache.pop(block_root) {
|
||||
let block_and_blobs = BeaconBlockAndBlobSidecars {
|
||||
block,
|
||||
blob_sidecars,
|
||||
};
|
||||
|
||||
Ok(BlockContents::BlockAndBlobSidecars(block_and_blobs))
|
||||
} else {
|
||||
return Err(warp_utils::reject::block_production_error(
|
||||
BlockProductionError::NoBlobsCached,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ mod attester_duties;
|
||||
mod block_id;
|
||||
mod block_packing_efficiency;
|
||||
mod block_rewards;
|
||||
mod build_block_contents;
|
||||
mod database;
|
||||
mod metrics;
|
||||
mod proposer_duties;
|
||||
@@ -2421,7 +2422,10 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.fork_name(&chain.spec)
|
||||
.map_err(inconsistent_fork_rejection)?;
|
||||
|
||||
fork_versioned_response(endpoint_version, fork_name, block)
|
||||
let block_contents =
|
||||
build_block_contents::build_block_contents(fork_name, chain, block);
|
||||
|
||||
fork_versioned_response(endpoint_version, fork_name, block_contents?)
|
||||
.map(|response| warp::reply::json(&response))
|
||||
},
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ use tokio::sync::mpsc::UnboundedSender;
|
||||
use tree_hash::TreeHash;
|
||||
use types::{
|
||||
AbstractExecPayload, BlindedPayload, EthSpec, ExecPayload, ExecutionBlockHash, FullPayload,
|
||||
Hash256, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar,
|
||||
Hash256, SignedBeaconBlock,
|
||||
};
|
||||
use warp::Rejection;
|
||||
|
||||
@@ -40,10 +40,11 @@ pub async fn publish_block<T: BeaconChainTypes>(
|
||||
let wrapped_block: BlockWrapper<T::EthSpec> =
|
||||
if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) {
|
||||
if let Some(sidecar) = chain.blob_cache.pop(&block_root) {
|
||||
let block_and_blobs = SignedBeaconBlockAndBlobsSidecar {
|
||||
beacon_block: block,
|
||||
blobs_sidecar: Arc::new(sidecar),
|
||||
};
|
||||
// TODO: Needs to be adjusted
|
||||
// let block_and_blobs = SignedBeaconBlockAndBlobsSidecar {
|
||||
// beacon_block: block,
|
||||
// blobs_sidecar: Arc::new(sidecar),
|
||||
// };
|
||||
unimplemented!("Needs to be adjusted")
|
||||
} else {
|
||||
//FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required
|
||||
|
||||
Reference in New Issue
Block a user