Allow custody by root requests to have no peers (#6417)

* Allow custody by root requests to have no peers
This commit is contained in:
Lion - dapplion
2024-09-23 14:49:23 -04:00
committed by GitHub
parent b619f1ab5c
commit 012e7e7bfa
3 changed files with 121 additions and 53 deletions

View File

@@ -15,6 +15,7 @@ use crate::sync::block_lookups::SingleLookupId;
use crate::sync::network_context::requests::BlobsByRootSingleBlockRequest;
use beacon_chain::block_verification_types::RpcBlock;
use beacon_chain::{BeaconChain, BeaconChainTypes, BlockProcessStatus, EngineState};
use custody::CustodyRequestResult;
use fnv::FnvHashMap;
use lighthouse_network::rpc::methods::{BlobsByRangeRequest, DataColumnsByRangeRequest};
use lighthouse_network::rpc::{BlocksByRangeRequest, GoodbyeReason, RPCError};
@@ -69,6 +70,8 @@ pub enum RpcEvent<T> {
pub type RpcResponseResult<T> = Result<(T, Duration), RpcResponseError>;
pub type CustodyByRootResult<T> = Result<(DataColumnSidecarList<T>, PeerGroup), RpcResponseError>;
#[derive(Debug)]
pub enum RpcResponseError {
RpcError(RPCError),
@@ -915,6 +918,32 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
.insert(id, (sender_id, info));
}
/// Attempt to make progress on all custody_by_root requests. Some request may be stale waiting
/// for custody peers. Returns a Vec of results as zero or more requests may fail in this
/// attempt.
pub fn continue_custody_by_root_requests(
&mut self,
) -> Vec<(CustodyRequester, CustodyByRootResult<T::EthSpec>)> {
let ids = self
.custody_by_root_requests
.keys()
.copied()
.collect::<Vec<_>>();
// Need to collect ids and results in separate steps to re-borrow self.
ids.into_iter()
.filter_map(|id| {
let mut request = self
.custody_by_root_requests
.remove(&id)
.expect("key of hashmap");
let result = request.continue_requests(self);
self.handle_custody_by_root_result(id, request, result)
.map(|result| (id, result))
})
.collect()
}
// Request handlers
pub fn on_single_block_response(
@@ -1069,7 +1098,7 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
req_id: DataColumnsByRootRequestId,
peer_id: PeerId,
resp: RpcResponseResult<Vec<Arc<DataColumnSidecar<T::EthSpec>>>>,
) -> Option<Result<(DataColumnSidecarList<T::EthSpec>, PeerGroup), RpcResponseError>> {
) -> Option<CustodyByRootResult<T::EthSpec>> {
// Note: need to remove the request to borrow self again below. Otherwise we can't
// do nested requests
let Some(mut request) = self.custody_by_root_requests.remove(&id.requester) else {
@@ -1078,28 +1107,35 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
return None;
};
let result = request
.on_data_column_downloaded(peer_id, req_id, resp, self)
let result = request.on_data_column_downloaded(peer_id, req_id, resp, self);
self.handle_custody_by_root_result(id.requester, request, result)
}
fn handle_custody_by_root_result(
&mut self,
id: CustodyRequester,
request: ActiveCustodyRequest<T>,
result: CustodyRequestResult<T::EthSpec>,
) -> Option<CustodyByRootResult<T::EthSpec>> {
let result = result
.map_err(RpcResponseError::CustodyRequestError)
.transpose();
// Convert a result from internal format of `ActiveCustodyRequest` (error first to use ?) to
// an Option first to use in an `if let Some() { act on result }` block.
if let Some(result) = result {
match result.as_ref() {
Ok((columns, peer_group)) => {
debug!(self.log, "Custody request success, removing"; "id" => ?id, "count" => columns.len(), "peers" => ?peer_group)
}
Err(e) => {
debug!(self.log, "Custody request failure, removing"; "id" => ?id, "error" => ?e)
}
match result.as_ref() {
Some(Ok((columns, peer_group))) => {
debug!(self.log, "Custody request success, removing"; "id" => ?id, "count" => columns.len(), "peers" => ?peer_group)
}
Some(Err(e)) => {
debug!(self.log, "Custody request failure, removing"; "id" => ?id, "error" => ?e)
}
None => {
self.custody_by_root_requests.insert(id, request);
}
Some(result)
} else {
self.custody_by_root_requests.insert(id.requester, request);
None
}
result
}
pub fn send_block_for_processing(