Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't request block components until having block #5774

Merged
merged 4 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 9 additions & 22 deletions beacon_node/network/src/sync/block_lookups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::metrics;
use crate::sync::block_lookups::common::{ResponseType, PARENT_DEPTH_TOLERANCE};
use crate::sync::block_lookups::parent_chain::find_oldest_fork_ancestor;
use crate::sync::manager::{Id, SingleLookupReqId};
use crate::sync::network_context::LookupFailure;
use beacon_chain::block_verification_types::AsBlock;
use beacon_chain::data_availability_checker::AvailabilityCheckErrorCategory;
use beacon_chain::{AvailabilityProcessingStatus, BeaconChainTypes, BlockError};
Expand Down Expand Up @@ -325,12 +324,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
response: RpcProcessingResult<R::VerifiedResponseType>,
cx: &mut SyncNetworkContext<T>,
) -> Result<LookupResult, LookupRequestError> {
// Downscore peer even if lookup is not known
// Only downscore lookup verify errors. RPC errors are downscored in the network handler.
if let Err(LookupFailure::LookupVerifyError(e)) = &response {
// Note: the error is displayed in full debug form on the match below
cx.report_peer(peer_id, PeerAction::LowToleranceError, e.into());
}
// Note: no need to downscore peers here, already downscored on network context

let response_type = R::response_type();
let Some(lookup) = self.single_block_lookups.get_mut(&id.lookup_id) else {
Expand Down Expand Up @@ -459,23 +453,16 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
// if both components have been processed.
request_state.on_processing_success()?;

// If this was the result of a block request, we can't determined if the block peer did anything
// wrong. If we already had both a block and blobs response processed, we should penalize the
// blobs peer because they did not provide all blobs on the initial request.
if lookup.both_components_processed() {
if let Some(blob_peer) = lookup
.blob_request_state
.state
.on_post_process_validation_failure()?
{
cx.report_peer(
blob_peer,
PeerAction::MidToleranceError,
"sent_incomplete_blobs",
);
}
// We don't request for other block components until being sure that the block has
// data. If we request blobs / columns to a peer we are sure those must exist.
// Therefore if all components are processed and we still receive `MissingComponents`
// it indicates an internal bug.
return Err(LookupRequestError::MissingComponentsAfterAllProcessed);
} else {
// Continue request, potentially request blobs
Action::Retry
}
Action::Retry
}
BlockProcessingResult::Ignored => {
// Beacon processor signalled to ignore the block processing result.
Expand Down
33 changes: 9 additions & 24 deletions beacon_node/network/src/sync/block_lookups/single_block_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ pub enum LookupRequestError {
BadState(String),
/// Lookup failed for some other reason and should be dropped
Failed,
/// Received MissingComponents when all components have been processed. This should never
/// happen, and indicates some internal bug
MissingComponentsAfterAllProcessed,
/// Attempted to retrieve a not known lookup id
UnknownLookup,
/// Received a download result for a different request id than the in-flight request.
Expand Down Expand Up @@ -158,7 +161,7 @@ impl<T: BeaconChainTypes> SingleBlockLookup<T> {
}

/// Potentially makes progress on this request if it's in a progress-able state
pub fn continue_request<R: RequestState<T>>(
fn continue_request<R: RequestState<T>>(
&mut self,
cx: &mut SyncNetworkContext<T>,
) -> Result<(), LookupRequestError> {
Expand Down Expand Up @@ -285,10 +288,8 @@ pub enum State<T: Clone> {
AwaitingProcess(DownloadResult<T>),
/// Request is processing, sent by lookup sync
Processing(DownloadResult<T>),
/// Request is processed:
/// - `Processed(Some)` if lookup sync downloaded and sent to process this request
/// - `Processed(None)` if another source (i.e. gossip) sent this component for processing
Processed(Option<PeerId>),
/// Request is processed
Processed,
}

/// Object representing the state of a single block or blob lookup request.
Expand Down Expand Up @@ -463,8 +464,8 @@ impl<T: Clone> SingleLookupRequestState<T> {

pub fn on_processing_success(&mut self) -> Result<(), LookupRequestError> {
match &self.state {
State::Processing(result) => {
self.state = State::Processed(Some(result.peer_id));
State::Processing(_) => {
self.state = State::Processed;
Ok(())
}
other => Err(LookupRequestError::BadState(format!(
Expand All @@ -473,27 +474,11 @@ impl<T: Clone> SingleLookupRequestState<T> {
}
}

pub fn on_post_process_validation_failure(
&mut self,
) -> Result<Option<PeerId>, LookupRequestError> {
match &self.state {
State::Processed(peer_id) => {
let peer_id = *peer_id;
self.failed_processing = self.failed_processing.saturating_add(1);
self.state = State::AwaitingDownload;
Ok(peer_id)
}
other => Err(LookupRequestError::BadState(format!(
"Bad state on_post_process_validation_failure expected Processed got {other}"
))),
}
}

/// Mark a request as complete without any download or processing
pub fn on_completed_request(&mut self) -> Result<(), LookupRequestError> {
match &self.state {
State::AwaitingDownload => {
self.state = State::Processed(None);
self.state = State::Processed;
Ok(())
}
other => Err(LookupRequestError::BadState(format!(
Expand Down
Loading
Loading