diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 268cd87d17..1e775000b1 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -963,15 +963,25 @@ impl BeaconChain { )>, Error, > { - if let (Some(block), Some(blobs)) = ( - self.early_attester_cache.get_block(*block_root), - self.early_attester_cache.get_blobs(*block_root), - ) { - return Ok(Some((block, blobs))); - } - if let Some(block) = self.get_block(block_root).await?.map(Arc::new) { - let blobs = self.get_blobs(block_root)?.map(Arc::new); - Ok(blobs.map(|blobs| (block, blobs))) + // If there is no data availability boundary, the Eip4844 fork is disabled. + if let Some(finalized_data_availability_boundary) = + self.finalized_data_availability_boundary() + { + // Only use the attester cache if we can find both the block and blob + if let (Some(block), Some(blobs)) = ( + self.early_attester_cache.get_block(*block_root), + self.early_attester_cache.get_blobs(*block_root), + ) { + Ok(Some((block, blobs))) + // Attempt to get the block and blobs from the database + } else if let Some(block) = self.get_block(block_root).await?.map(Arc::new) { + let blobs = self + .get_blobs(block_root, finalized_data_availability_boundary)? + .map(Arc::new); + Ok(blobs.map(|blobs| (block, blobs))) + } else { + Ok(None) + } } else { Ok(None) } @@ -1046,7 +1056,7 @@ impl BeaconChain { /// Returns the blobs at the given root, if any. /// - /// Returns `Ok(None)` if the blobs and associated block are not found. + /// Returns `Ok(None)` if the blobs and associated block are not found. /// /// If we can find the corresponding block in our database, we know whether we *should* have /// blobs. If we should have blobs and no blobs are found, this will error. If we shouldn't, @@ -1060,6 +1070,7 @@ impl BeaconChain { pub fn get_blobs( &self, block_root: &Hash256, + data_availability_boundary: Epoch, ) -> Result>, Error> { match self.store.get_blobs(block_root)? { Some(blobs) => Ok(Some(blobs)), @@ -1076,13 +1087,11 @@ impl BeaconChain { }; if expected_kzg_commitments.is_empty() { Ok(BlobsSidecar::empty_from_parts(*block_root, block.slot())) + } else if data_availability_boundary <= block.epoch() { + // We should have blobs for all blocks younger than the boundary. + Err(Error::BlobsUnavailable) } else { - if let Some(boundary) = self.data_availability_boundary() { - // We should have blobs for all blocks younger than the boundary. - if boundary <= block.epoch() { - return Err(Error::BlobsUnavailable); - } - } + // We shouldn't have blobs for blocks older than the boundary. Err(Error::BlobsOlderThanDataAvailabilityBoundary(block.epoch())) } }) diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index d9a3c2eea3..451c31668b 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -267,9 +267,9 @@ impl Worker { break; } Err(BeaconChainError::NoKzgCommitmentsFieldOnBlock) => { - error!( + debug!( self.log, - "No kzg_commitments field in block"; + "Peer requested blobs for a pre-eip4844 block"; "peer" => %peer_id, "block_root" => ?root, ); @@ -283,49 +283,22 @@ impl Worker { break; } Err(BeaconChainError::BlobsOlderThanDataAvailabilityBoundary(block_epoch)) => { - let finalized_data_availability_boundary = self.chain.finalized_data_availability_boundary(); - - match finalized_data_availability_boundary { - Some(boundary_epoch) => { - if block_epoch >= boundary_epoch { - error!( - self.log, - "Peer requested block and blob that should be available, but no blob found"; - "request" => %request, - "peer" => %peer_id, - "request_root" => ?root, - "finalized_data_availability_boundary" => %boundary_epoch, - ); - self.send_error_response( - peer_id, - RPCResponseErrorCode::ResourceUnavailable, - "Blobs older than data availability boundary".into(), - request_id, - ); - send_response = false; - break; - } else { - debug!( - self.log, - "Peer requested block and blob older than the data availability \ - boundary for ByRoot request, no blob found"; - "peer" => %peer_id, - "request_root" => ?root, - "finalized_data_availability_boundary" => ?finalized_data_availability_boundary, - ); - } - } - None => { - debug!(self.log, "Eip4844 fork is disabled"); - self.send_error_response( - peer_id, - RPCResponseErrorCode::ResourceUnavailable, - "Eip4844 fork is disabled".into(), - request_id, - ); - return; - } - } + debug!( + self.log, + "Peer requested block and blobs older than the data availability \ + boundary for ByRoot request, no blob found"; + "peer" => %peer_id, + "request_root" => ?root, + "block_epoch" => ?block_epoch, + ); + self.send_error_response( + peer_id, + RPCResponseErrorCode::ResourceUnavailable, + "Blobs older than data availability boundary".into(), + request_id, + ); + send_response = false; + break; } Err(BeaconChainError::BlockHashMissingFromExecutionLayer(_)) => { debug!( @@ -670,35 +643,13 @@ impl Worker { let start_slot = Slot::from(req.start_slot); let start_epoch = start_slot.epoch(T::EthSpec::slots_per_epoch()); - let data_availability_boundary = self.chain.data_availability_boundary(); - - let serve_blobs_from_slot = match data_availability_boundary { - Some(data_availability_boundary_epoch) => { - if Some(start_epoch) < data_availability_boundary { - let oldest_blob_slot = self - .chain - .store - .get_blob_info() - .map(|blob_info| blob_info.oldest_blob_slot); - - debug!( - self.log, - "Range request start slot is older than data availability boundary"; - "requested_slot" => %req.start_slot, - "oldest_known_slot" => oldest_blob_slot, - "data_availability_boundary" => data_availability_boundary - ); - - data_availability_boundary_epoch.start_slot(T::EthSpec::slots_per_epoch()) - } else { - start_slot - } - } + let data_availability_boundary = match self.chain.data_availability_boundary() { + Some(boundary) => boundary, None => { debug!(self.log, "Eip4844 fork is disabled"); self.send_error_response( peer_id, - RPCResponseErrorCode::ResourceUnavailable, + RPCResponseErrorCode::ServerError, "Eip4844 fork is disabled".into(), request_id, ); @@ -706,6 +657,26 @@ impl Worker { } }; + let serve_blobs_from_slot = if start_epoch < data_availability_boundary { + let oldest_blob_slot = self + .chain + .store + .get_blob_info() + .map(|blob_info| blob_info.oldest_blob_slot); + + debug!( + self.log, + "Range request start slot is older than data availability boundary"; + "requested_slot" => %req.start_slot, + "oldest_known_slot" => oldest_blob_slot, + "data_availability_boundary" => data_availability_boundary + ); + + data_availability_boundary.start_slot(T::EthSpec::slots_per_epoch()) + } else { + start_slot + }; + // Should not send more than max request blocks if req.count > MAX_REQUEST_BLOBS_SIDECARS { req.count = MAX_REQUEST_BLOBS_SIDECARS; @@ -785,7 +756,7 @@ impl Worker { let mut send_response = true; for root in block_roots { - match self.chain.get_blobs(&root) { + match self.chain.get_blobs(&root, data_availability_boundary) { Ok(Some(blobs)) => { blobs_sent += 1; self.send_network_message(NetworkMessage::SendResponse {