mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 03:31:45 +00:00
Track request IDs in RangeBlockComponentsRequest (#6998)
Part of - https://github.com/sigp/lighthouse/issues/6258 `RangeBlockComponentsRequest` handles a set of by_range requests. It's quite lose on these requests, not tracking them by ID. We want to implement individual request retries, so we must make `RangeBlockComponentsRequest` aware of its requests IDs. We don't want the result of a prior by_range request to affect the state of a future retry. Lookup sync uses this mechanism. Now `RangeBlockComponentsRequest` tracks: ```rust pub struct RangeBlockComponentsRequest<E: EthSpec> { blocks_request: ByRangeRequest<BlocksByRangeRequestId, Vec<Arc<SignedBeaconBlock<E>>>>, block_data_request: RangeBlockDataRequest<E>, } enum RangeBlockDataRequest<E: EthSpec> { NoData, Blobs(ByRangeRequest<BlobsByRangeRequestId, Vec<Arc<BlobSidecar<E>>>>), DataColumns { requests: HashMap< DataColumnsByRangeRequestId, ByRangeRequest<DataColumnsByRangeRequestId, DataColumnSidecarList<E>>, >, expected_custody_columns: Vec<ColumnIndex>, }, } enum ByRangeRequest<I: PartialEq + std::fmt::Display, T> { Active(I), Complete(T), } ``` I have merged `is_finished` and `Into_responses` into the same function. Otherwise, we need to duplicate the logic to figure out if the requests are done.
This commit is contained in:
@@ -218,9 +218,18 @@ pub struct SyncNetworkContext<T: BeaconChainTypes> {
|
||||
|
||||
/// Small enumeration to make dealing with block and blob requests easier.
|
||||
pub enum RangeBlockComponent<E: EthSpec> {
|
||||
Block(RpcResponseResult<Vec<Arc<SignedBeaconBlock<E>>>>),
|
||||
Blob(RpcResponseResult<Vec<Arc<BlobSidecar<E>>>>),
|
||||
CustodyColumns(RpcResponseResult<Vec<Arc<DataColumnSidecar<E>>>>),
|
||||
Block(
|
||||
BlocksByRangeRequestId,
|
||||
RpcResponseResult<Vec<Arc<SignedBeaconBlock<E>>>>,
|
||||
),
|
||||
Blob(
|
||||
BlobsByRangeRequestId,
|
||||
RpcResponseResult<Vec<Arc<BlobSidecar<E>>>>,
|
||||
),
|
||||
CustodyColumns(
|
||||
DataColumnsByRangeRequestId,
|
||||
RpcResponseResult<Vec<Arc<DataColumnSidecar<E>>>>,
|
||||
),
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
@@ -386,7 +395,16 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
requester,
|
||||
};
|
||||
|
||||
let _blocks_req_id = self.send_blocks_by_range_request(peer_id, request.clone(), id)?;
|
||||
// Compute custody column peers before sending the blocks_by_range request. If we don't have
|
||||
// enough peers, error here.
|
||||
let data_column_requests = if matches!(batch_type, ByRangeRequestType::BlocksAndColumns) {
|
||||
let column_indexes = self.network_globals().sampling_columns.clone();
|
||||
Some(self.make_columns_by_range_requests(request.clone(), &column_indexes)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let blocks_req_id = self.send_blocks_by_range_request(peer_id, request.clone(), id)?;
|
||||
|
||||
let blobs_req_id = if matches!(batch_type, ByRangeRequestType::BlocksAndBlobs) {
|
||||
Some(self.send_blobs_by_range_request(
|
||||
@@ -401,35 +419,27 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
None
|
||||
};
|
||||
|
||||
let (expects_columns, data_column_requests) =
|
||||
if matches!(batch_type, ByRangeRequestType::BlocksAndColumns) {
|
||||
let column_indexes = self.network_globals().sampling_columns.clone();
|
||||
let data_column_requests = self
|
||||
.make_columns_by_range_requests(request, &column_indexes)?
|
||||
.into_iter()
|
||||
.map(|(peer_id, columns_by_range_request)| {
|
||||
self.send_data_columns_by_range_request(
|
||||
peer_id,
|
||||
columns_by_range_request,
|
||||
id,
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let data_columns = if let Some(data_column_requests) = data_column_requests {
|
||||
let data_column_requests = data_column_requests
|
||||
.into_iter()
|
||||
.map(|(peer_id, columns_by_range_request)| {
|
||||
self.send_data_columns_by_range_request(peer_id, columns_by_range_request, id)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
(
|
||||
Some(column_indexes.into_iter().collect::<Vec<_>>()),
|
||||
Some(data_column_requests),
|
||||
)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
Some((
|
||||
data_column_requests,
|
||||
self.network_globals()
|
||||
.sampling_columns
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let expected_blobs = blobs_req_id.is_some();
|
||||
let info = RangeBlockComponentsRequest::new(
|
||||
expected_blobs,
|
||||
expects_columns,
|
||||
data_column_requests.map(|items| items.len()),
|
||||
);
|
||||
let info = RangeBlockComponentsRequest::new(blocks_req_id, blobs_req_id, data_columns);
|
||||
self.components_by_range_requests.insert(id, info);
|
||||
|
||||
Ok(id.id)
|
||||
@@ -484,28 +494,33 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
if let Err(e) = {
|
||||
let request = entry.get_mut();
|
||||
match range_block_component {
|
||||
RangeBlockComponent::Block(resp) => resp.map(|(blocks, _)| {
|
||||
request.add_blocks(blocks);
|
||||
RangeBlockComponent::Block(req_id, resp) => resp.and_then(|(blocks, _)| {
|
||||
request
|
||||
.add_blocks(req_id, blocks)
|
||||
.map_err(RpcResponseError::BlockComponentCouplingError)
|
||||
}),
|
||||
RangeBlockComponent::Blob(resp) => resp.map(|(blobs, _)| {
|
||||
request.add_blobs(blobs);
|
||||
}),
|
||||
RangeBlockComponent::CustodyColumns(resp) => resp.map(|(custody_columns, _)| {
|
||||
request.add_custody_columns(custody_columns);
|
||||
RangeBlockComponent::Blob(req_id, resp) => resp.and_then(|(blobs, _)| {
|
||||
request
|
||||
.add_blobs(req_id, blobs)
|
||||
.map_err(RpcResponseError::BlockComponentCouplingError)
|
||||
}),
|
||||
RangeBlockComponent::CustodyColumns(req_id, resp) => {
|
||||
resp.and_then(|(custody_columns, _)| {
|
||||
request
|
||||
.add_custody_columns(req_id, custody_columns)
|
||||
.map_err(RpcResponseError::BlockComponentCouplingError)
|
||||
})
|
||||
}
|
||||
}
|
||||
} {
|
||||
entry.remove();
|
||||
return Some(Err(e));
|
||||
}
|
||||
|
||||
if entry.get_mut().is_finished() {
|
||||
if let Some(blocks_result) = entry.get().responses(&self.chain.spec) {
|
||||
entry.remove();
|
||||
// If the request is finished, dequeue everything
|
||||
let request = entry.remove();
|
||||
let blocks = request
|
||||
.into_responses(&self.chain.spec)
|
||||
.map_err(RpcResponseError::BlockComponentCouplingError);
|
||||
Some(blocks)
|
||||
Some(blocks_result.map_err(RpcResponseError::BlockComponentCouplingError))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user