mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-04 21:34:36 +00:00
lots of refactoring
This commit is contained in:
@@ -511,7 +511,7 @@ impl<T: EthSpec> TryInto<AvailableBlock<T>> for MaybeAvailableBlock<T> {
|
|||||||
fn try_into(self) -> Result<AvailableBlock<T>, Self::Error> {
|
fn try_into(self) -> Result<AvailableBlock<T>, Self::Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Available(block) => Ok(block),
|
Self::Available(block) => Ok(block),
|
||||||
Self::AvailabilityPending(block) => Err(AvailabilityCheckError::MissingBlobs),
|
Self::AvailabilityPending(_block) => Err(AvailabilityCheckError::MissingBlobs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -312,7 +312,9 @@ pub enum BlockError<T: EthSpec> {
|
|||||||
ParentExecutionPayloadInvalid {
|
ParentExecutionPayloadInvalid {
|
||||||
parent_root: Hash256,
|
parent_root: Hash256,
|
||||||
},
|
},
|
||||||
|
/// The blob alone failed validation.
|
||||||
BlobValidation(BlobError<T>),
|
BlobValidation(BlobError<T>),
|
||||||
|
/// The block and blob together failed validation.
|
||||||
AvailabilityCheck(AvailabilityCheckError),
|
AvailabilityCheck(AvailabilityCheckError),
|
||||||
MissingBlockParts(Slot, Hash256),
|
MissingBlockParts(Slot, Hash256),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ pub enum AvailabilityCheckError {
|
|||||||
SszTypes(ssz_types::Error),
|
SszTypes(ssz_types::Error),
|
||||||
MissingBlobs,
|
MissingBlobs,
|
||||||
NumBlobsMismatch {
|
NumBlobsMismatch {
|
||||||
|
/// The peer sent us an invalid block, we must penalise harshly.
|
||||||
num_kzg_commitments: usize,
|
num_kzg_commitments: usize,
|
||||||
num_blobs: usize,
|
num_blobs: usize,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -546,7 +546,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.request_parent_blob(parent_lookup, cx);
|
self.request_parent_blobs(parent_lookup, cx);
|
||||||
} else {
|
} else {
|
||||||
self.parent_lookups.push(parent_lookup)
|
self.parent_lookups.push(parent_lookup)
|
||||||
}
|
}
|
||||||
@@ -557,53 +557,9 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
// processing result arrives.
|
// processing result arrives.
|
||||||
self.parent_lookups.push(parent_lookup);
|
self.parent_lookups.push(parent_lookup);
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => {
|
||||||
ParentVerifyError::RootMismatch
|
self.handle_parent_verify_error(peer_id, parent_lookup, ResponseType::Block, e, cx)
|
||||||
| ParentVerifyError::NoBlockReturned
|
}
|
||||||
| ParentVerifyError::NotEnoughBlobsReturned
|
|
||||||
| ParentVerifyError::ExtraBlocksReturned
|
|
||||||
| ParentVerifyError::UnrequestedBlobId
|
|
||||||
| ParentVerifyError::ExtraBlobsReturned
|
|
||||||
| ParentVerifyError::InvalidIndex(_) => {
|
|
||||||
let e = e.into();
|
|
||||||
warn!(self.log, "Peer sent invalid response to parent request.";
|
|
||||||
"peer_id" => %peer_id, "reason" => %e);
|
|
||||||
|
|
||||||
// We do not tolerate these kinds of errors. We will accept a few but these are signs
|
|
||||||
// of a faulty peer.
|
|
||||||
cx.report_peer(peer_id, PeerAction::LowToleranceError, e);
|
|
||||||
|
|
||||||
// We try again if possible.
|
|
||||||
self.request_parent_block(parent_lookup, cx);
|
|
||||||
}
|
|
||||||
ParentVerifyError::PreviousFailure { parent_root } => {
|
|
||||||
debug!(
|
|
||||||
self.log,
|
|
||||||
"Parent chain ignored due to past failure";
|
|
||||||
"block" => %parent_root,
|
|
||||||
);
|
|
||||||
// Add the root block to failed chains
|
|
||||||
self.failed_chains.insert(parent_lookup.chain_hash());
|
|
||||||
|
|
||||||
cx.report_peer(
|
|
||||||
peer_id,
|
|
||||||
PeerAction::MidToleranceError,
|
|
||||||
"bbroot_failed_chains",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ParentVerifyError::BenignFailure => {
|
|
||||||
trace!(
|
|
||||||
self.log,
|
|
||||||
"Requested peer could not respond to block request, requesting a new peer";
|
|
||||||
);
|
|
||||||
parent_lookup
|
|
||||||
.current_parent_request
|
|
||||||
.block_request_state
|
|
||||||
.potential_peers
|
|
||||||
.remove(&peer_id);
|
|
||||||
self.request_parent_block(parent_lookup, cx);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
metrics::set_gauge(
|
metrics::set_gauge(
|
||||||
@@ -660,53 +616,9 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
// Waiting for more blobs to arrive
|
// Waiting for more blobs to arrive
|
||||||
self.parent_lookups.push(parent_lookup);
|
self.parent_lookups.push(parent_lookup);
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => {
|
||||||
ParentVerifyError::RootMismatch
|
self.handle_parent_verify_error(peer_id, parent_lookup, ResponseType::Blob, e, cx)
|
||||||
| ParentVerifyError::NoBlockReturned
|
}
|
||||||
| ParentVerifyError::NotEnoughBlobsReturned
|
|
||||||
| ParentVerifyError::ExtraBlocksReturned
|
|
||||||
| ParentVerifyError::UnrequestedBlobId
|
|
||||||
| ParentVerifyError::ExtraBlobsReturned
|
|
||||||
| ParentVerifyError::InvalidIndex(_) => {
|
|
||||||
let e = e.into();
|
|
||||||
warn!(self.log, "Peer sent invalid response to parent request.";
|
|
||||||
"peer_id" => %peer_id, "reason" => %e);
|
|
||||||
|
|
||||||
// We do not tolerate these kinds of errors. We will accept a few but these are signs
|
|
||||||
// of a faulty peer.
|
|
||||||
cx.report_peer(peer_id, PeerAction::LowToleranceError, e);
|
|
||||||
|
|
||||||
// We try again if possible.
|
|
||||||
self.request_parent_blob(parent_lookup, cx);
|
|
||||||
}
|
|
||||||
ParentVerifyError::PreviousFailure { parent_root } => {
|
|
||||||
debug!(
|
|
||||||
self.log,
|
|
||||||
"Parent chain ignored due to past failure";
|
|
||||||
"block" => %parent_root,
|
|
||||||
);
|
|
||||||
// Add the root block to failed chains
|
|
||||||
self.failed_chains.insert(parent_lookup.chain_hash());
|
|
||||||
|
|
||||||
cx.report_peer(
|
|
||||||
peer_id,
|
|
||||||
PeerAction::MidToleranceError,
|
|
||||||
"bbroot_failed_chains",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ParentVerifyError::BenignFailure => {
|
|
||||||
trace!(
|
|
||||||
self.log,
|
|
||||||
"Requested peer could not respond to blob request, requesting a new peer";
|
|
||||||
);
|
|
||||||
parent_lookup
|
|
||||||
.current_parent_request
|
|
||||||
.blob_request_state
|
|
||||||
.potential_peers
|
|
||||||
.remove(&peer_id);
|
|
||||||
self.request_parent_blob(parent_lookup, cx);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
metrics::set_gauge(
|
metrics::set_gauge(
|
||||||
@@ -715,36 +627,91 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_parent_verify_error(
|
||||||
|
&mut self,
|
||||||
|
peer_id: PeerId,
|
||||||
|
mut parent_lookup: ParentLookup<T>,
|
||||||
|
response_type: ResponseType,
|
||||||
|
e: ParentVerifyError,
|
||||||
|
cx: &mut SyncNetworkContext<T>,
|
||||||
|
) {
|
||||||
|
match e {
|
||||||
|
ParentVerifyError::RootMismatch
|
||||||
|
| ParentVerifyError::NoBlockReturned
|
||||||
|
| ParentVerifyError::NotEnoughBlobsReturned
|
||||||
|
| ParentVerifyError::ExtraBlocksReturned
|
||||||
|
| ParentVerifyError::UnrequestedBlobId
|
||||||
|
| ParentVerifyError::ExtraBlobsReturned
|
||||||
|
| ParentVerifyError::InvalidIndex(_) => {
|
||||||
|
let e = e.into();
|
||||||
|
warn!(self.log, "Peer sent invalid response to parent request.";
|
||||||
|
"peer_id" => %peer_id, "reason" => %e);
|
||||||
|
|
||||||
|
// We do not tolerate these kinds of errors. We will accept a few but these are signs
|
||||||
|
// of a faulty peer.
|
||||||
|
cx.report_peer(peer_id, PeerAction::LowToleranceError, e);
|
||||||
|
|
||||||
|
// We try again if possible.
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.request_parent_block(parent_lookup, cx),
|
||||||
|
ResponseType::Blob => self.request_parent_blobs(parent_lookup, cx),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ParentVerifyError::PreviousFailure { parent_root } => {
|
||||||
|
debug!(
|
||||||
|
self.log,
|
||||||
|
"Parent chain ignored due to past failure";
|
||||||
|
"block" => %parent_root,
|
||||||
|
);
|
||||||
|
// Add the root block to failed chains
|
||||||
|
self.failed_chains.insert(parent_lookup.chain_hash());
|
||||||
|
|
||||||
|
cx.report_peer(
|
||||||
|
peer_id,
|
||||||
|
PeerAction::MidToleranceError,
|
||||||
|
"bbroot_failed_chains",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ParentVerifyError::BenignFailure => {
|
||||||
|
trace!(
|
||||||
|
self.log,
|
||||||
|
"Requested peer could not respond to block request, requesting a new peer";
|
||||||
|
);
|
||||||
|
parent_lookup
|
||||||
|
.current_parent_request
|
||||||
|
.remove_peer_if_useless(&peer_id, response_type);
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.request_parent_block(parent_lookup, cx),
|
||||||
|
ResponseType::Blob => self.request_parent_blobs(parent_lookup, cx),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Error responses */
|
/* Error responses */
|
||||||
|
|
||||||
pub fn peer_disconnected(&mut self, peer_id: &PeerId, cx: &mut SyncNetworkContext<T>) {
|
pub fn peer_disconnected(&mut self, peer_id: &PeerId, cx: &mut SyncNetworkContext<T>) {
|
||||||
self.single_block_lookups
|
self.single_block_lookups
|
||||||
.retain_mut(|(block_id_opt, blob_id_opt, req)| {
|
.retain_mut(|(block_id_opt, blob_id_opt, req)| {
|
||||||
let should_remove_block = block_id_opt
|
let should_remove_block = should_remove_disconnected_peer(
|
||||||
.as_mut()
|
block_id_opt,
|
||||||
.filter(|_| req.block_request_state
|
ResponseType::Block,
|
||||||
.check_peer_disconnected(peer_id)
|
peer_id,
|
||||||
.is_err())
|
cx,
|
||||||
.map(|block_id| {
|
req,
|
||||||
|
&self.log,
|
||||||
|
);
|
||||||
|
let should_remove_blob = should_remove_disconnected_peer(
|
||||||
|
blob_id_opt,
|
||||||
|
ResponseType::Blob,
|
||||||
|
peer_id,
|
||||||
|
cx,
|
||||||
|
req,
|
||||||
|
&self.log,
|
||||||
|
);
|
||||||
|
|
||||||
trace!(self.log, "Single block lookup failed on peer disconnection"; "block_root" => ?req.requested_block_root, );
|
matches!(should_remove_block, ShouldRemoveLookup::False)
|
||||||
retry_request_after_failure(block_id, req, ResponseType::Block, peer_id, cx, &self.log)
|
&& matches!(should_remove_blob, ShouldRemoveLookup::False)
|
||||||
})
|
|
||||||
.unwrap_or(ShouldRemoveLookup::False);
|
|
||||||
|
|
||||||
let should_remove_blob = blob_id_opt
|
|
||||||
.as_mut()
|
|
||||||
.filter(|_| req.blob_request_state
|
|
||||||
.check_peer_disconnected(peer_id)
|
|
||||||
.is_err())
|
|
||||||
.map(|blob_id| {
|
|
||||||
|
|
||||||
trace!(self.log, "Single blob lookup failed on peer disconnection"; "block_root" => ?req.requested_block_root, );
|
|
||||||
retry_request_after_failure(blob_id, req, ResponseType::Blob, peer_id, cx, &self.log)
|
|
||||||
})
|
|
||||||
.unwrap_or(ShouldRemoveLookup::False);
|
|
||||||
|
|
||||||
matches!(should_remove_block, ShouldRemoveLookup::False) && matches!(should_remove_blob, ShouldRemoveLookup::False)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Check disconnection for parent lookups */
|
/* Check disconnection for parent lookups */
|
||||||
@@ -790,7 +757,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
parent_lookup.blob_download_failed();
|
parent_lookup.blob_download_failed();
|
||||||
trace!(self.log, "Parent lookup blobs request failed"; &parent_lookup, "error" => msg);
|
trace!(self.log, "Parent lookup blobs request failed"; &parent_lookup, "error" => msg);
|
||||||
|
|
||||||
self.request_parent_blob(parent_lookup, cx);
|
self.request_parent_blobs(parent_lookup, cx);
|
||||||
} else {
|
} else {
|
||||||
return debug!(self.log, "RPC failure for a blobs parent lookup request that was not found"; "peer_id" => %peer_id, "error" => msg);
|
return debug!(self.log, "RPC failure for a blobs parent lookup request that was not found"; "peer_id" => %peer_id, "error" => msg);
|
||||||
};
|
};
|
||||||
@@ -808,30 +775,32 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
error: RPCError,
|
error: RPCError,
|
||||||
) {
|
) {
|
||||||
let msg = error.as_static_str();
|
let msg = error.as_static_str();
|
||||||
self.single_block_lookups.retain_mut(|(block_id_opt, blob_id_opt, req)|{
|
self.single_block_lookups
|
||||||
|
.retain_mut(|(block_id_opt, blob_id_opt, req)| {
|
||||||
|
let should_remove_block = should_remove_failed_lookup(
|
||||||
|
block_id_opt,
|
||||||
|
ResponseType::Block,
|
||||||
|
id,
|
||||||
|
msg,
|
||||||
|
peer_id,
|
||||||
|
cx,
|
||||||
|
req,
|
||||||
|
&self.log,
|
||||||
|
);
|
||||||
|
let should_remove_blob = should_remove_failed_lookup(
|
||||||
|
blob_id_opt,
|
||||||
|
ResponseType::Blob,
|
||||||
|
id,
|
||||||
|
msg,
|
||||||
|
peer_id,
|
||||||
|
cx,
|
||||||
|
req,
|
||||||
|
&self.log,
|
||||||
|
);
|
||||||
|
|
||||||
let should_remove_block = block_id_opt
|
matches!(should_remove_block, ShouldRemoveLookup::False)
|
||||||
.as_mut()
|
&& matches!(should_remove_blob, ShouldRemoveLookup::False)
|
||||||
.filter(|block_id| **block_id == id)
|
});
|
||||||
.map(|block_id| {
|
|
||||||
req.block_request_state.register_failure_downloading();
|
|
||||||
trace!(self.log, "Single block lookup failed"; "block" => %req.requested_block_root, "error" => msg);
|
|
||||||
retry_request_after_failure(block_id, req, ResponseType::Block, peer_id, cx, &self.log)
|
|
||||||
})
|
|
||||||
.unwrap_or(ShouldRemoveLookup::False);
|
|
||||||
|
|
||||||
let should_remove_blob = blob_id_opt
|
|
||||||
.as_mut()
|
|
||||||
.filter(|blob_id| **blob_id == id)
|
|
||||||
.map(|blob_id| {
|
|
||||||
req.blob_request_state.register_failure_downloading();
|
|
||||||
trace!(self.log, "Single blob lookup failed"; "block" => %req.requested_block_root, "error" =>msg);
|
|
||||||
retry_request_after_failure(blob_id, req, ResponseType::Block, peer_id, cx, &self.log)
|
|
||||||
})
|
|
||||||
.unwrap_or(ShouldRemoveLookup::False);
|
|
||||||
|
|
||||||
matches!(should_remove_block, ShouldRemoveLookup::False) && matches!(should_remove_blob, ShouldRemoveLookup::False)
|
|
||||||
});
|
|
||||||
|
|
||||||
metrics::set_gauge(
|
metrics::set_gauge(
|
||||||
&metrics::SYNC_SINGLE_BLOCK_LOOKUPS,
|
&metrics::SYNC_SINGLE_BLOCK_LOOKUPS,
|
||||||
@@ -850,13 +819,9 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
) {
|
) {
|
||||||
let lookup_components_opt = self.single_block_lookups.iter_mut().enumerate().find_map(
|
let lookup_components_opt = self.single_block_lookups.iter_mut().enumerate().find_map(
|
||||||
|(index, (block_id_opt, blob_id_opt, req))| {
|
|(index, (block_id_opt, blob_id_opt, req))| {
|
||||||
let id_filter = |id: &Id| -> bool { target_id == *id };
|
let block_match = block_id_opt.as_ref() == Some(&target_id);
|
||||||
let block_matches = block_id_opt.as_ref().map(id_filter).unwrap_or(false);
|
let blob_match = blob_id_opt.as_ref() == Some(&target_id);
|
||||||
let blob_matches = blob_id_opt.as_ref().map(id_filter).unwrap_or(false);
|
(block_match || blob_match).then_some((index, block_id_opt, blob_id_opt, req))
|
||||||
if !block_matches && !blob_matches {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some((index, block_id_opt, blob_id_opt, req))
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let (index, block_id_ref, blob_id_ref, request_ref) = match lookup_components_opt {
|
let (index, block_id_ref, blob_id_ref, request_ref) = match lookup_components_opt {
|
||||||
@@ -883,116 +848,14 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
trace!(self.log, "Single block processing succeeded"; "block" => %root);
|
trace!(self.log, "Single block processing succeeded"; "block" => %root);
|
||||||
ShouldRemoveLookup::True
|
ShouldRemoveLookup::True
|
||||||
}
|
}
|
||||||
AvailabilityProcessingStatus::MissingComponents(_, block_root) => {
|
AvailabilityProcessingStatus::MissingComponents(_, _block_root) => {
|
||||||
// if peer should have both, and missing components is received after we've
|
should_remove_missing_components(
|
||||||
// processed the opposite, then we can downscore.
|
request_ref,
|
||||||
let should_remove = match response_type {
|
response_type,
|
||||||
ResponseType::Block => {
|
blob_id_ref,
|
||||||
if request_ref.blob_request_state.component_processed {
|
cx,
|
||||||
match request_ref.processing_peer(ResponseType::Blob) {
|
&self.log,
|
||||||
Ok(PeerShouldHave::BlockAndBlobs(other_peer)) => {
|
)
|
||||||
cx.report_peer(
|
|
||||||
peer_id.to_peer_id(),
|
|
||||||
PeerAction::MidToleranceError,
|
|
||||||
"single_block_failure",
|
|
||||||
);
|
|
||||||
if let Some(blob_id_ref) = blob_id_ref {
|
|
||||||
// Try it again if possible.
|
|
||||||
retry_request_after_failure(
|
|
||||||
blob_id_ref,
|
|
||||||
request_ref,
|
|
||||||
ResponseType::Blob,
|
|
||||||
peer_id.as_peer_id(),
|
|
||||||
cx,
|
|
||||||
&self.log,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(PeerShouldHave::Neither(other_peer)) => {
|
|
||||||
request_ref
|
|
||||||
.blob_request_state
|
|
||||||
.remove_peer_if_useless(&other_peer);
|
|
||||||
if let Some(blob_id_ref) = blob_id_ref {
|
|
||||||
// Try it again if possible.
|
|
||||||
retry_request_after_failure(
|
|
||||||
blob_id_ref,
|
|
||||||
request_ref,
|
|
||||||
ResponseType::Blob,
|
|
||||||
peer_id.as_peer_id(),
|
|
||||||
cx,
|
|
||||||
&self.log,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(()) => {
|
|
||||||
//TODO(sean) retry?
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
request_ref.block_request_state.component_processed = true;
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ResponseType::Blob => {
|
|
||||||
if request_ref.block_request_state.component_processed {
|
|
||||||
match request_ref.processing_peer(ResponseType::Blob) {
|
|
||||||
Ok(PeerShouldHave::BlockAndBlobs(other_peer)) => {
|
|
||||||
cx.report_peer(
|
|
||||||
other_peer,
|
|
||||||
PeerAction::MidToleranceError,
|
|
||||||
"single_block_failure",
|
|
||||||
);
|
|
||||||
if let Some(blob_id_ref) = blob_id_ref {
|
|
||||||
// Try it again if possible.
|
|
||||||
retry_request_after_failure(
|
|
||||||
blob_id_ref,
|
|
||||||
request_ref,
|
|
||||||
ResponseType::Blob,
|
|
||||||
peer_id.as_peer_id(),
|
|
||||||
cx,
|
|
||||||
&self.log,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(PeerShouldHave::Neither(other_peer)) => {
|
|
||||||
request_ref
|
|
||||||
.blob_request_state
|
|
||||||
.remove_peer_if_useless(&other_peer);
|
|
||||||
if let Some(blob_id_ref) = blob_id_ref {
|
|
||||||
// Try it again if possible.
|
|
||||||
retry_request_after_failure(
|
|
||||||
blob_id_ref,
|
|
||||||
request_ref,
|
|
||||||
ResponseType::Blob,
|
|
||||||
peer_id.as_peer_id(),
|
|
||||||
cx,
|
|
||||||
&self.log,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(()) => {
|
|
||||||
//TODO(sean) retry?
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// retry block here?
|
|
||||||
|
|
||||||
request_ref.blob_request_state.component_processed = true;
|
|
||||||
ShouldRemoveLookup::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
should_remove
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BlockProcessingResult::Ignored => {
|
BlockProcessingResult::Ignored => {
|
||||||
@@ -1018,13 +881,14 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
ShouldRemoveLookup::True
|
ShouldRemoveLookup::True
|
||||||
}
|
}
|
||||||
BlockError::ParentUnknown(block) => {
|
BlockError::ParentUnknown(block) => {
|
||||||
self.search_parent(
|
let slot = block.slot();
|
||||||
block.slot(),
|
let parent_root = block.parent_root();
|
||||||
root,
|
let (block, blobs) = block.deconstruct();
|
||||||
block.parent_root(),
|
request_ref.add_unknown_parent_block(block);
|
||||||
peer_id.to_peer_id(),
|
if let Some(blobs) = blobs {
|
||||||
cx,
|
request_ref.add_unknown_parent_blobs(blobs);
|
||||||
);
|
}
|
||||||
|
self.search_parent(slot, root, parent_root, peer_id.to_peer_id(), cx);
|
||||||
ShouldRemoveLookup::False
|
ShouldRemoveLookup::False
|
||||||
}
|
}
|
||||||
ref e @ BlockError::ExecutionPayloadError(ref epe) if !epe.penalize_peer() => {
|
ref e @ BlockError::ExecutionPayloadError(ref epe) if !epe.penalize_peer() => {
|
||||||
@@ -1047,27 +911,32 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
);
|
);
|
||||||
if let Some(blob_id_ref) = blob_id_ref {
|
if let Some(blob_id_ref) = blob_id_ref {
|
||||||
// Try it again if possible.
|
// Try it again if possible.
|
||||||
retry_request_after_failure(
|
if !request_ref.awaiting_download(ResponseType::Blob) {
|
||||||
blob_id_ref,
|
retry_request_after_failure(
|
||||||
request_ref,
|
blob_id_ref,
|
||||||
ResponseType::Blob,
|
request_ref,
|
||||||
peer_id.as_peer_id(),
|
ResponseType::Blob,
|
||||||
cx,
|
peer_id.as_peer_id(),
|
||||||
&self.log,
|
cx,
|
||||||
)
|
&self.log,
|
||||||
} else if let Some(block_id_ref) = block_id_ref {
|
);
|
||||||
// Try it again if possible.
|
}
|
||||||
retry_request_after_failure(
|
|
||||||
block_id_ref,
|
|
||||||
request_ref,
|
|
||||||
ResponseType::Block,
|
|
||||||
peer_id.as_peer_id(),
|
|
||||||
cx,
|
|
||||||
&self.log,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ShouldRemoveLookup::True
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(block_id_ref) = block_id_ref {
|
||||||
|
if !request_ref.awaiting_download(ResponseType::Block) {
|
||||||
|
// Try it again if possible.
|
||||||
|
retry_request_after_failure(
|
||||||
|
block_id_ref,
|
||||||
|
request_ref,
|
||||||
|
ResponseType::Block,
|
||||||
|
peer_id.as_peer_id(),
|
||||||
|
cx,
|
||||||
|
&self.log,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShouldRemoveLookup::False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1396,7 +1265,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
|||||||
self.handle_response(parent_lookup, cx, response, ResponseType::Block);
|
self.handle_response(parent_lookup, cx, response, ResponseType::Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_parent_blob(
|
fn request_parent_blobs(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut parent_lookup: ParentLookup<T>,
|
mut parent_lookup: ParentLookup<T>,
|
||||||
cx: &mut SyncNetworkContext<T>,
|
cx: &mut SyncNetworkContext<T>,
|
||||||
@@ -1498,19 +1367,7 @@ fn handle_block_lookup_verify_error<T: BeaconChainTypes>(
|
|||||||
log: &Logger,
|
log: &Logger,
|
||||||
) -> ShouldRemoveLookup {
|
) -> ShouldRemoveLookup {
|
||||||
let msg = if matches!(e, LookupVerifyError::BenignFailure) {
|
let msg = if matches!(e, LookupVerifyError::BenignFailure) {
|
||||||
match response_type {
|
request_ref.remove_peer_if_useless(&peer_id, response_type);
|
||||||
// Only remove a potential peer if there are better options
|
|
||||||
ResponseType::Block => {
|
|
||||||
request_ref
|
|
||||||
.block_request_state
|
|
||||||
.remove_peer_if_useless(&peer_id);
|
|
||||||
}
|
|
||||||
ResponseType::Blob => {
|
|
||||||
request_ref
|
|
||||||
.blob_request_state
|
|
||||||
.remove_peer_if_useless(&peer_id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
"peer could not response to request"
|
"peer could not response to request"
|
||||||
} else {
|
} else {
|
||||||
let msg = e.into();
|
let msg = e.into();
|
||||||
@@ -1580,3 +1437,83 @@ fn retry_request_after_failure<T: BeaconChainTypes>(
|
|||||||
}
|
}
|
||||||
ShouldRemoveLookup::False
|
ShouldRemoveLookup::False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_remove_disconnected_peer<T: BeaconChainTypes>(
|
||||||
|
id: &mut Option<Id>,
|
||||||
|
response_type: ResponseType,
|
||||||
|
peer_id: &PeerId,
|
||||||
|
cx: &mut SyncNetworkContext<T>,
|
||||||
|
req: &mut SingleBlockLookup<SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS, T>,
|
||||||
|
log: &Logger,
|
||||||
|
) -> ShouldRemoveLookup {
|
||||||
|
id
|
||||||
|
.as_mut()
|
||||||
|
.filter(|_| req.check_peer_disconnected(peer_id, response_type)
|
||||||
|
.is_err())
|
||||||
|
.map(|block_id| {
|
||||||
|
trace!(log, "Single lookup failed on peer disconnection"; "block_root" => ?req.requested_block_root, "response_type" => ?response_type);
|
||||||
|
retry_request_after_failure(block_id, req, response_type, peer_id, cx, log)
|
||||||
|
})
|
||||||
|
.unwrap_or(ShouldRemoveLookup::False)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_remove_failed_lookup<T: BeaconChainTypes>(
|
||||||
|
id: &mut Option<Id>,
|
||||||
|
response_type: ResponseType,
|
||||||
|
target_id: Id,
|
||||||
|
msg: &'static str,
|
||||||
|
peer_id: &PeerId,
|
||||||
|
cx: &mut SyncNetworkContext<T>,
|
||||||
|
req: &mut SingleBlockLookup<SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS, T>,
|
||||||
|
log: &Logger,
|
||||||
|
) -> ShouldRemoveLookup {
|
||||||
|
id
|
||||||
|
.as_mut()
|
||||||
|
.filter(|id| **id == target_id)
|
||||||
|
.map(|id| {
|
||||||
|
req.register_failure_downloading(response_type);
|
||||||
|
trace!(log, "Single lookup failed"; "block" => %req.requested_block_root, "error" => msg, "response_type" => ?response_type);
|
||||||
|
retry_request_after_failure(id, req, response_type, peer_id, cx, log)
|
||||||
|
})
|
||||||
|
.unwrap_or(ShouldRemoveLookup::False)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_remove_missing_components<T: BeaconChainTypes>(
|
||||||
|
request_ref: &mut SingleBlockLookup<SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS, T>,
|
||||||
|
response_type: ResponseType,
|
||||||
|
blob_id_ref: &mut Option<Id>,
|
||||||
|
cx: &mut SyncNetworkContext<T>,
|
||||||
|
log: &Logger,
|
||||||
|
) -> ShouldRemoveLookup {
|
||||||
|
request_ref.set_component_processed(response_type);
|
||||||
|
|
||||||
|
// If we get a missing component response after processing both a blob and a block response, the
|
||||||
|
// blobs must be what are missing.
|
||||||
|
if request_ref.both_components_processed() {
|
||||||
|
let Ok(blob_peer) = request_ref.processing_peer(ResponseType::Blob) else {
|
||||||
|
return ShouldRemoveLookup::False;
|
||||||
|
};
|
||||||
|
if let PeerShouldHave::BlockAndBlobs(blob_peer) = blob_peer {
|
||||||
|
cx.report_peer(
|
||||||
|
blob_peer,
|
||||||
|
PeerAction::MidToleranceError,
|
||||||
|
"single_block_failure",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
request_ref.remove_peer_if_useless(blob_peer.as_peer_id(), ResponseType::Blob);
|
||||||
|
if let Some(blob_id_ref) = blob_id_ref {
|
||||||
|
if !request_ref.awaiting_download(ResponseType::Blob) {
|
||||||
|
// Try it again if possible.
|
||||||
|
return retry_request_after_failure(
|
||||||
|
blob_id_ref,
|
||||||
|
request_ref,
|
||||||
|
ResponseType::Blob,
|
||||||
|
blob_peer.as_peer_id(),
|
||||||
|
cx,
|
||||||
|
log,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShouldRemoveLookup::False
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ use crate::sync::{
|
|||||||
};
|
};
|
||||||
use beacon_chain::blob_verification::AsBlock;
|
use beacon_chain::blob_verification::AsBlock;
|
||||||
use beacon_chain::blob_verification::BlockWrapper;
|
use beacon_chain::blob_verification::BlockWrapper;
|
||||||
use beacon_chain::data_availability_checker::{AvailabilityCheckError, DataAvailabilityChecker};
|
use beacon_chain::data_availability_checker::DataAvailabilityChecker;
|
||||||
use beacon_chain::BeaconChainTypes;
|
use beacon_chain::BeaconChainTypes;
|
||||||
use lighthouse_network::PeerId;
|
use lighthouse_network::PeerId;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use store::Hash256;
|
use store::Hash256;
|
||||||
use strum::IntoStaticStr;
|
use strum::IntoStaticStr;
|
||||||
use types::blob_sidecar::FixedBlobSidecarList;
|
use types::blob_sidecar::FixedBlobSidecarList;
|
||||||
use types::{BlobSidecar, EthSpec, SignedBeaconBlock};
|
use types::{BlobSidecar, SignedBeaconBlock};
|
||||||
|
|
||||||
/// How many attempts we try to find a parent of a block before we give up trying.
|
/// How many attempts we try to find a parent of a block before we give up trying.
|
||||||
pub(crate) const PARENT_FAIL_TOLERANCE: u8 = 5;
|
pub(crate) const PARENT_FAIL_TOLERANCE: u8 = 5;
|
||||||
|
|||||||
@@ -29,6 +29,44 @@ pub struct SingleBlockLookup<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> {
|
|||||||
pub unknown_parent_components: Option<UnknownParentComponents<T::EthSpec>>,
|
pub unknown_parent_components: Option<UnknownParentComponents<T::EthSpec>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS, T> {
|
||||||
|
pub(crate) fn register_failure_downloading(&mut self, response_type: ResponseType) {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.block_request_state.register_failure_downloading(),
|
||||||
|
ResponseType::Blob => self.blob_request_state.register_failure_downloading(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS, T> {
|
||||||
|
pub(crate) fn awaiting_download(&mut self, response_type: ResponseType) -> bool {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => {
|
||||||
|
matches!(self.block_request_state.state, State::AwaitingDownload)
|
||||||
|
}
|
||||||
|
ResponseType::Blob => matches!(self.blob_request_state.state, State::AwaitingDownload),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn remove_peer_if_useless(&mut self, peer_id: &PeerId, response_type: ResponseType) {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.block_request_state.remove_peer_if_useless(peer_id),
|
||||||
|
ResponseType::Blob => self.blob_request_state.remove_peer_if_useless(peer_id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn check_peer_disconnected(
|
||||||
|
&mut self,
|
||||||
|
peer_id: &PeerId,
|
||||||
|
response_type: ResponseType,
|
||||||
|
) -> Result<(), ()> {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.block_request_state.check_peer_disconnected(peer_id),
|
||||||
|
ResponseType::Blob => self.blob_request_state.check_peer_disconnected(peer_id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct UnknownParentComponents<E: EthSpec> {
|
pub struct UnknownParentComponents<E: EthSpec> {
|
||||||
pub downloaded_block: Option<Arc<SignedBeaconBlock<E>>>,
|
pub downloaded_block: Option<Arc<SignedBeaconBlock<E>>>,
|
||||||
@@ -317,41 +355,17 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
|
|||||||
self.block_request_state.state,
|
self.block_request_state.state,
|
||||||
State::AwaitingDownload
|
State::AwaitingDownload
|
||||||
));
|
));
|
||||||
if self.block_request_state.failed_attempts() >= MAX_ATTEMPTS {
|
let request = BlocksByRootRequest {
|
||||||
|
block_roots: VariableList::from(vec![self.requested_block_root]),
|
||||||
|
};
|
||||||
|
let response_type = ResponseType::Block;
|
||||||
|
if self.too_many_attempts(response_type) {
|
||||||
Err(LookupRequestError::TooManyAttempts {
|
Err(LookupRequestError::TooManyAttempts {
|
||||||
cannot_process: self.block_request_state.failed_processing
|
cannot_process: self.cannot_process(response_type),
|
||||||
>= self.block_request_state.failed_downloading,
|
|
||||||
})
|
})
|
||||||
} else if let Some(&peer_id) = self
|
} else if let Some(peer_id) = self.get_peer(response_type) {
|
||||||
.block_request_state
|
self.add_used_peer(peer_id, response_type);
|
||||||
.available_peers
|
Ok(Some((peer_id.to_peer_id(), request)))
|
||||||
.iter()
|
|
||||||
.choose(&mut rand::thread_rng())
|
|
||||||
{
|
|
||||||
let request = BlocksByRootRequest {
|
|
||||||
block_roots: VariableList::from(vec![self.requested_block_root]),
|
|
||||||
};
|
|
||||||
self.block_request_state.used_peers.insert(peer_id);
|
|
||||||
let peer_source = PeerShouldHave::BlockAndBlobs(peer_id);
|
|
||||||
self.block_request_state.state = State::Downloading {
|
|
||||||
peer_id: peer_source,
|
|
||||||
};
|
|
||||||
Ok(Some((peer_id, request)))
|
|
||||||
} else if let Some(&peer_id) = self
|
|
||||||
.block_request_state
|
|
||||||
.potential_peers
|
|
||||||
.iter()
|
|
||||||
.choose(&mut rand::thread_rng())
|
|
||||||
{
|
|
||||||
let request = BlocksByRootRequest {
|
|
||||||
block_roots: VariableList::from(vec![self.requested_block_root]),
|
|
||||||
};
|
|
||||||
self.block_request_state.used_peers.insert(peer_id);
|
|
||||||
let peer_source = PeerShouldHave::Neither(peer_id);
|
|
||||||
self.block_request_state.state = State::Downloading {
|
|
||||||
peer_id: peer_source,
|
|
||||||
};
|
|
||||||
Ok(Some((peer_id, request)))
|
|
||||||
} else {
|
} else {
|
||||||
Err(LookupRequestError::NoPeers)
|
Err(LookupRequestError::NoPeers)
|
||||||
}
|
}
|
||||||
@@ -370,46 +384,92 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
|
|||||||
self.blob_request_state.state,
|
self.blob_request_state.state,
|
||||||
State::AwaitingDownload
|
State::AwaitingDownload
|
||||||
));
|
));
|
||||||
if self.blob_request_state.failed_attempts() >= MAX_ATTEMPTS {
|
let request = BlobsByRootRequest {
|
||||||
|
blob_ids: VariableList::from(self.requested_ids.clone()),
|
||||||
|
};
|
||||||
|
let response_type = ResponseType::Blob;
|
||||||
|
if self.too_many_attempts(response_type) {
|
||||||
Err(LookupRequestError::TooManyAttempts {
|
Err(LookupRequestError::TooManyAttempts {
|
||||||
cannot_process: self.blob_request_state.failed_processing
|
cannot_process: self.cannot_process(response_type),
|
||||||
>= self.blob_request_state.failed_downloading,
|
|
||||||
})
|
})
|
||||||
} else if let Some(&peer_id) = self
|
} else if let Some(peer_id) = self.get_peer(response_type) {
|
||||||
.blob_request_state
|
self.add_used_peer(peer_id, response_type);
|
||||||
.available_peers
|
Ok(Some((peer_id.to_peer_id(), request)))
|
||||||
.iter()
|
|
||||||
.choose(&mut rand::thread_rng())
|
|
||||||
{
|
|
||||||
let request = BlobsByRootRequest {
|
|
||||||
blob_ids: VariableList::from(self.requested_ids.clone()),
|
|
||||||
};
|
|
||||||
self.blob_request_state.used_peers.insert(peer_id);
|
|
||||||
let peer_source = PeerShouldHave::BlockAndBlobs(peer_id);
|
|
||||||
self.blob_request_state.state = State::Downloading {
|
|
||||||
peer_id: peer_source,
|
|
||||||
};
|
|
||||||
Ok(Some((peer_id, request)))
|
|
||||||
} else if let Some(&peer_id) = self
|
|
||||||
.blob_request_state
|
|
||||||
.potential_peers
|
|
||||||
.iter()
|
|
||||||
.choose(&mut rand::thread_rng())
|
|
||||||
{
|
|
||||||
let request = BlobsByRootRequest {
|
|
||||||
blob_ids: VariableList::from(self.requested_ids.clone()),
|
|
||||||
};
|
|
||||||
self.blob_request_state.used_peers.insert(peer_id);
|
|
||||||
let peer_source = PeerShouldHave::Neither(peer_id);
|
|
||||||
self.blob_request_state.state = State::Downloading {
|
|
||||||
peer_id: peer_source,
|
|
||||||
};
|
|
||||||
Ok(Some((peer_id, request)))
|
|
||||||
} else {
|
} else {
|
||||||
Err(LookupRequestError::NoPeers)
|
Err(LookupRequestError::NoPeers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn too_many_attempts(&self, response_type: ResponseType) -> bool {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.block_request_state.failed_attempts() >= MAX_ATTEMPTS,
|
||||||
|
ResponseType::Blob => self.blob_request_state.failed_attempts() >= MAX_ATTEMPTS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cannot_process(&self, response_type: ResponseType) -> bool {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => {
|
||||||
|
self.block_request_state.failed_processing
|
||||||
|
>= self.block_request_state.failed_downloading
|
||||||
|
}
|
||||||
|
ResponseType::Blob => {
|
||||||
|
self.blob_request_state.failed_processing
|
||||||
|
>= self.blob_request_state.failed_downloading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_peer(&self, response_type: ResponseType) -> Option<PeerShouldHave> {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self
|
||||||
|
.block_request_state
|
||||||
|
.available_peers
|
||||||
|
.iter()
|
||||||
|
.choose(&mut rand::thread_rng())
|
||||||
|
.copied()
|
||||||
|
.map(PeerShouldHave::BlockAndBlobs)
|
||||||
|
.or(self
|
||||||
|
.block_request_state
|
||||||
|
.potential_peers
|
||||||
|
.iter()
|
||||||
|
.choose(&mut rand::thread_rng())
|
||||||
|
.copied()
|
||||||
|
.map(PeerShouldHave::Neither)),
|
||||||
|
ResponseType::Blob => self
|
||||||
|
.blob_request_state
|
||||||
|
.available_peers
|
||||||
|
.iter()
|
||||||
|
.choose(&mut rand::thread_rng())
|
||||||
|
.copied()
|
||||||
|
.map(PeerShouldHave::BlockAndBlobs)
|
||||||
|
.or(self
|
||||||
|
.blob_request_state
|
||||||
|
.potential_peers
|
||||||
|
.iter()
|
||||||
|
.choose(&mut rand::thread_rng())
|
||||||
|
.copied()
|
||||||
|
.map(PeerShouldHave::Neither)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_used_peer(&mut self, peer_id: PeerShouldHave, response_type: ResponseType) {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => {
|
||||||
|
self.block_request_state
|
||||||
|
.used_peers
|
||||||
|
.insert(peer_id.to_peer_id());
|
||||||
|
self.block_request_state.state = State::Downloading { peer_id };
|
||||||
|
}
|
||||||
|
ResponseType::Blob => {
|
||||||
|
self.blob_request_state
|
||||||
|
.used_peers
|
||||||
|
.insert(peer_id.to_peer_id());
|
||||||
|
self.blob_request_state.state = State::Downloading { peer_id };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_peer_if_useful(
|
pub fn add_peer_if_useful(
|
||||||
&mut self,
|
&mut self,
|
||||||
block_root: &Hash256,
|
block_root: &Hash256,
|
||||||
@@ -444,6 +504,17 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
|
|||||||
ResponseType::Blob => self.blob_request_state.peer(),
|
ResponseType::Blob => self.blob_request_state.peer(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn both_components_processed(&self) -> bool {
|
||||||
|
self.block_request_state.component_processed && self.block_request_state.component_processed
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_component_processed(&mut self, response_type: ResponseType) {
|
||||||
|
match response_type {
|
||||||
|
ResponseType::Block => self.block_request_state.component_processed = true,
|
||||||
|
ResponseType::Blob => self.blob_request_state.component_processed = true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const MAX_ATTEMPTS: u8> SingleLookupRequestState<MAX_ATTEMPTS> {
|
impl<const MAX_ATTEMPTS: u8> SingleLookupRequestState<MAX_ATTEMPTS> {
|
||||||
@@ -585,12 +656,15 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use beacon_chain::builder::Witness;
|
use beacon_chain::builder::Witness;
|
||||||
use beacon_chain::eth1_chain::CachingEth1Backend;
|
use beacon_chain::eth1_chain::CachingEth1Backend;
|
||||||
|
use slog::Logger;
|
||||||
|
use sloggers::null::NullLoggerBuilder;
|
||||||
|
use sloggers::Build;
|
||||||
use slot_clock::{SlotClock, TestingSlotClock};
|
use slot_clock::{SlotClock, TestingSlotClock};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use store::MemoryStore;
|
use store::{HotColdDB, MemoryStore, StoreConfig};
|
||||||
use types::{
|
use types::{
|
||||||
test_utils::{SeedableRng, TestRandom, XorShiftRng},
|
test_utils::{SeedableRng, TestRandom, XorShiftRng},
|
||||||
EthSpec, MinimalEthSpec as E, SignedBeaconBlock, Slot,
|
ChainSpec, EthSpec, MinimalEthSpec as E, SignedBeaconBlock, Slot,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn rand_block() -> SignedBeaconBlock<E> {
|
fn rand_block() -> SignedBeaconBlock<E> {
|
||||||
@@ -614,7 +688,13 @@ mod tests {
|
|||||||
Duration::from_secs(0),
|
Duration::from_secs(0),
|
||||||
Duration::from_secs(spec.seconds_per_slot),
|
Duration::from_secs(spec.seconds_per_slot),
|
||||||
);
|
);
|
||||||
let da_checker = Arc::new(DataAvailabilityChecker::new(slot_clock, None, spec));
|
let log = NullLoggerBuilder.build().expect("logger should build");
|
||||||
|
let store = HotColdDB::open_ephemeral(StoreConfig::default(), ChainSpec::minimal(), log)
|
||||||
|
.expect("store");
|
||||||
|
let da_checker = Arc::new(
|
||||||
|
DataAvailabilityChecker::new(slot_clock, None, store.into(), spec)
|
||||||
|
.expect("data availability checker"),
|
||||||
|
);
|
||||||
let mut sl =
|
let mut sl =
|
||||||
SingleBlockLookup::<4, T>::new(block.canonical_root(), None, peer_id, da_checker);
|
SingleBlockLookup::<4, T>::new(block.canonical_root(), None, peer_id, da_checker);
|
||||||
sl.request_block().unwrap();
|
sl.request_block().unwrap();
|
||||||
@@ -632,8 +712,14 @@ mod tests {
|
|||||||
Duration::from_secs(0),
|
Duration::from_secs(0),
|
||||||
Duration::from_secs(spec.seconds_per_slot),
|
Duration::from_secs(spec.seconds_per_slot),
|
||||||
);
|
);
|
||||||
|
let log = NullLoggerBuilder.build().expect("logger should build");
|
||||||
|
let store = HotColdDB::open_ephemeral(StoreConfig::default(), ChainSpec::minimal(), log)
|
||||||
|
.expect("store");
|
||||||
|
|
||||||
let da_checker = Arc::new(DataAvailabilityChecker::new(slot_clock, None, spec));
|
let da_checker = Arc::new(
|
||||||
|
DataAvailabilityChecker::new(slot_clock, None, store.into(), spec)
|
||||||
|
.expect("data availability checker"),
|
||||||
|
);
|
||||||
|
|
||||||
let mut sl = SingleBlockLookup::<FAILURES, T>::new(
|
let mut sl = SingleBlockLookup::<FAILURES, T>::new(
|
||||||
block.canonical_root(),
|
block.canonical_root(),
|
||||||
|
|||||||
@@ -1704,8 +1704,8 @@ mod deneb_only {
|
|||||||
.block_response_triggering_process()
|
.block_response_triggering_process()
|
||||||
.invalid_block_processed()
|
.invalid_block_processed()
|
||||||
.expect_penalty()
|
.expect_penalty()
|
||||||
|
.expect_blobs_request()
|
||||||
.expect_block_request()
|
.expect_block_request()
|
||||||
.expect_no_blobs_request()
|
|
||||||
.blobs_response()
|
.blobs_response()
|
||||||
.missing_components_from_blob_request()
|
.missing_components_from_blob_request()
|
||||||
.expect_no_penalty()
|
.expect_no_penalty()
|
||||||
@@ -1726,7 +1726,7 @@ mod deneb_only {
|
|||||||
.invalid_blob_processed()
|
.invalid_blob_processed()
|
||||||
.expect_penalty()
|
.expect_penalty()
|
||||||
.expect_blobs_request()
|
.expect_blobs_request()
|
||||||
.expect_no_block_request();
|
.expect_block_request();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1881,8 +1881,8 @@ mod deneb_only {
|
|||||||
.block_response_triggering_process()
|
.block_response_triggering_process()
|
||||||
.invalid_block_processed()
|
.invalid_block_processed()
|
||||||
.expect_penalty()
|
.expect_penalty()
|
||||||
|
.expect_blobs_request()
|
||||||
.expect_block_request()
|
.expect_block_request()
|
||||||
.expect_no_blobs_request()
|
|
||||||
.blobs_response()
|
.blobs_response()
|
||||||
.missing_components_from_blob_request()
|
.missing_components_from_blob_request()
|
||||||
.expect_no_penalty()
|
.expect_no_penalty()
|
||||||
@@ -1903,7 +1903,7 @@ mod deneb_only {
|
|||||||
.invalid_blob_processed()
|
.invalid_blob_processed()
|
||||||
.expect_penalty()
|
.expect_penalty()
|
||||||
.expect_blobs_request()
|
.expect_blobs_request()
|
||||||
.expect_no_block_request();
|
.expect_block_request();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ pub struct SyncNetworkContext<T: BeaconChainTypes> {
|
|||||||
/// Small enumeration to make dealing with block and blob requests easier.
|
/// Small enumeration to make dealing with block and blob requests easier.
|
||||||
pub enum BlockOrBlob<T: EthSpec> {
|
pub enum BlockOrBlob<T: EthSpec> {
|
||||||
Block(Option<Arc<SignedBeaconBlock<T>>>),
|
Block(Option<Arc<SignedBeaconBlock<T>>>),
|
||||||
Sidecar(Option<Arc<BlobSidecar<T>>>),
|
Blob(Option<Arc<BlobSidecar<T>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<Option<Arc<SignedBeaconBlock<T>>>> for BlockOrBlob<T> {
|
impl<T: EthSpec> From<Option<Arc<SignedBeaconBlock<T>>>> for BlockOrBlob<T> {
|
||||||
@@ -81,7 +81,7 @@ impl<T: EthSpec> From<Option<Arc<SignedBeaconBlock<T>>>> for BlockOrBlob<T> {
|
|||||||
|
|
||||||
impl<T: EthSpec> From<Option<Arc<BlobSidecar<T>>>> for BlockOrBlob<T> {
|
impl<T: EthSpec> From<Option<Arc<BlobSidecar<T>>>> for BlockOrBlob<T> {
|
||||||
fn from(blob: Option<Arc<BlobSidecar<T>>>) -> Self {
|
fn from(blob: Option<Arc<BlobSidecar<T>>>) -> Self {
|
||||||
BlockOrBlob::Sidecar(blob)
|
BlockOrBlob::Blob(blob)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
|||||||
let info = &mut req.block_blob_info;
|
let info = &mut req.block_blob_info;
|
||||||
match block_or_blob {
|
match block_or_blob {
|
||||||
BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block),
|
BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block),
|
||||||
BlockOrBlob::Sidecar(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar),
|
BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar),
|
||||||
}
|
}
|
||||||
if info.is_finished() {
|
if info.is_finished() {
|
||||||
// If the request is finished, dequeue everything
|
// If the request is finished, dequeue everything
|
||||||
@@ -389,7 +389,7 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
|||||||
let (_, info) = entry.get_mut();
|
let (_, info) = entry.get_mut();
|
||||||
match block_or_blob {
|
match block_or_blob {
|
||||||
BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block),
|
BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block),
|
||||||
BlockOrBlob::Sidecar(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar),
|
BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar),
|
||||||
}
|
}
|
||||||
if info.is_finished() {
|
if info.is_finished() {
|
||||||
// If the request is finished, dequeue everything
|
// If the request is finished, dequeue everything
|
||||||
|
|||||||
Reference in New Issue
Block a user