mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-01 06:37:56 +00:00
client/network: Use request response for block requests (#7478)
* client/network: Add scaffolding for finality req to use req resp #sc * client/network/src/finality_requests: Remove * client/network/src/behaviour: Pass request id down to sync * client/network: Use request response for block requests * client/network: Move handler logic into *_*_handler.rs * client/network: Track ongoing finality requests in protocol.rs * client/network: Remove commented out finalization initialization * client/network: Add docs for request handlers * client/network/finality_request_handler: Log errors * client/network/block_request_handler: Log errors * client/network: Format * client/network: Handle block request failure * protocols/network: Fix tests * client/network/src/behaviour: Handle request sending errors * client/network: Move response handling into custom method * client/network/protocol: Handle block response errors * client/network/protocol: Remove tracking of obsolete requests * client/network/protocol: Remove block request start time tracking This will be handled generically via request-responses. * client/network/protocol: Refactor on_*_request_started * client/network: Pass protocol config instead of protocol name * client/network: Pass protocol config in tests * client/network/config: Document request response configs * client/network/src/_request_handler: Document protocol config gen * client/network/src/protocol: Document Peer request values * client/network: Rework request response to always use oneshot * client/network: Unified metric reporting for all request protocols * client/network: Move protobuf parsing into protocol.rs * client/network/src/protocol: Return pending events after poll * client/network: Improve error handling and documentation * client/network/behaviour: Remove outdated error types * Update client/network/src/block_request_handler.rs Co-authored-by: Ashley <ashley.ruglys@gmail.com> * Update client/network/src/finality_request_handler.rs Co-authored-by: Ashley <ashley.ruglys@gmail.com> * client/network/protocol: Reduce reputation on timeout * client/network/protocol: Refine reputation changes * client/network/block_request_handler: Set and explain queue length * client/service: Deny block requests when light client * client/service: Fix role matching * client: Enforce line width * client/network/request_responses: Fix unit tests * client/network: Expose time to build response via metrics * client/network/request_responses: Fix early connection closed error * client/network/protocol: Fix line length * client/network/protocol: Disconnect on most request failures * client/network/protocol: Disconnect peer when oneshot is canceled * client/network/protocol: Disconnect peer even when connection closed * client/network/protocol: Remove debugging log line * client/network/request_response: Use Clone::clone for error * client/network/request_response: Remove outdated comment With libp2p v0.33.0 libp2p-request-response properly sends inbound failures on connections being closed. Co-authored-by: Addie Wagenknecht <addie@nortd.com> Co-authored-by: Ashley <ashley.ruglys@gmail.com>
This commit is contained in:
@@ -38,7 +38,7 @@ use crate::{
|
||||
NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer,
|
||||
},
|
||||
on_demand_layer::AlwaysBadChecker,
|
||||
light_client_handler, block_requests,
|
||||
light_client_handler,
|
||||
protocol::{
|
||||
self,
|
||||
NotifsHandlerError,
|
||||
@@ -94,7 +94,6 @@ use std::{
|
||||
},
|
||||
task::Poll,
|
||||
};
|
||||
use wasm_timer::Instant;
|
||||
|
||||
pub use behaviour::{ResponseFailure, InboundFailure, RequestFailure, OutboundFailure};
|
||||
|
||||
@@ -287,10 +286,6 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
|
||||
params.network_config.client_version,
|
||||
params.network_config.node_name
|
||||
);
|
||||
let block_requests = {
|
||||
let config = block_requests::Config::new(¶ms.protocol_id);
|
||||
block_requests::BlockRequests::new(config, params.chain.clone())
|
||||
};
|
||||
let light_client_handler = {
|
||||
let config = light_client_handler::Config::new(¶ms.protocol_id);
|
||||
light_client_handler::LightClientHandler::new(
|
||||
@@ -329,9 +324,9 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
|
||||
params.role,
|
||||
user_agent,
|
||||
local_public,
|
||||
block_requests,
|
||||
light_client_handler,
|
||||
discovery_config,
|
||||
params.block_request_protocol_config,
|
||||
params.network_config.request_response_protocols,
|
||||
);
|
||||
|
||||
@@ -430,7 +425,6 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
|
||||
peers_notifications_sinks,
|
||||
metrics,
|
||||
boot_node_ids,
|
||||
pending_requests: HashMap::with_capacity(128),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1231,13 +1225,6 @@ pub struct NetworkWorker<B: BlockT + 'static, H: ExHashT> {
|
||||
metrics: Option<Metrics>,
|
||||
/// The `PeerId`'s of all boot nodes.
|
||||
boot_node_ids: Arc<HashSet<PeerId>>,
|
||||
/// Requests started using [`NetworkService::request`]. Includes the channel to send back the
|
||||
/// response, when the request has started, and the name of the protocol for diagnostic
|
||||
/// purposes.
|
||||
pending_requests: HashMap<
|
||||
behaviour::RequestId,
|
||||
(oneshot::Sender<Result<Vec<u8>, RequestFailure>>, Instant, String)
|
||||
>,
|
||||
/// For each peer and protocol combination, an object that allows sending notifications to
|
||||
/// that peer. Shared with the [`NetworkService`].
|
||||
peers_notifications_sinks: Arc<Mutex<HashMap<(PeerId, Cow<'static, str>), NotificationsSink>>>,
|
||||
@@ -1310,29 +1297,7 @@ impl<B: BlockT + 'static, H: ExHashT> Future for NetworkWorker<B, H> {
|
||||
ServiceToWorkerMsg::EventStream(sender) =>
|
||||
this.event_streams.push(sender),
|
||||
ServiceToWorkerMsg::Request { target, protocol, request, pending_response } => {
|
||||
// Calling `send_request` can fail immediately in some circumstances.
|
||||
// This is handled by sending back an error on the channel.
|
||||
match this.network_service.send_request(&target, &protocol, request) {
|
||||
Ok(request_id) => {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
metrics.requests_out_started_total
|
||||
.with_label_values(&[&protocol])
|
||||
.inc();
|
||||
}
|
||||
this.pending_requests.insert(
|
||||
request_id,
|
||||
(pending_response, Instant::now(), protocol.to_string())
|
||||
);
|
||||
},
|
||||
Err(behaviour::SendRequestError::NotConnected) => {
|
||||
let err = RequestFailure::Network(OutboundFailure::ConnectionClosed);
|
||||
let _ = pending_response.send(Err(err));
|
||||
},
|
||||
Err(behaviour::SendRequestError::UnknownProtocol) => {
|
||||
let err = RequestFailure::Network(OutboundFailure::UnsupportedProtocols);
|
||||
let _ = pending_response.send(Err(err));
|
||||
},
|
||||
}
|
||||
this.network_service.send_request(&target, &protocol, request, pending_response);
|
||||
},
|
||||
ServiceToWorkerMsg::DisconnectPeer(who) =>
|
||||
this.network_service.user_protocol_mut().disconnect_peer(&who),
|
||||
@@ -1396,51 +1361,37 @@ impl<B: BlockT + 'static, H: ExHashT> Future for NetworkWorker<B, H> {
|
||||
}
|
||||
}
|
||||
},
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::RequestFinished { request_id, result })) => {
|
||||
if let Some((send_back, started, protocol)) = this.pending_requests.remove(&request_id) {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
match &result {
|
||||
Ok(_) => {
|
||||
metrics.requests_out_success_total
|
||||
.with_label_values(&[&protocol])
|
||||
.observe(started.elapsed().as_secs_f64());
|
||||
}
|
||||
Err(err) => {
|
||||
let reason = match err {
|
||||
RequestFailure::Refused => "refused",
|
||||
RequestFailure::Network(OutboundFailure::DialFailure) =>
|
||||
"dial-failure",
|
||||
RequestFailure::Network(OutboundFailure::Timeout) =>
|
||||
"timeout",
|
||||
RequestFailure::Network(OutboundFailure::ConnectionClosed) =>
|
||||
"connection-closed",
|
||||
RequestFailure::Network(OutboundFailure::UnsupportedProtocols) =>
|
||||
"unsupported",
|
||||
};
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::RequestFinished {
|
||||
protocol, duration, result, ..
|
||||
})) => {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
match result {
|
||||
Ok(_) => {
|
||||
metrics.requests_out_success_total
|
||||
.with_label_values(&[&protocol])
|
||||
.observe(duration.as_secs_f64());
|
||||
}
|
||||
Err(err) => {
|
||||
let reason = match err {
|
||||
RequestFailure::NotConnected => "not-connected",
|
||||
RequestFailure::UnknownProtocol => "unknown-protocol",
|
||||
RequestFailure::Refused => "refused",
|
||||
RequestFailure::Obsolete => "obsolete",
|
||||
RequestFailure::Network(OutboundFailure::DialFailure) =>
|
||||
"dial-failure",
|
||||
RequestFailure::Network(OutboundFailure::Timeout) =>
|
||||
"timeout",
|
||||
RequestFailure::Network(OutboundFailure::ConnectionClosed) =>
|
||||
"connection-closed",
|
||||
RequestFailure::Network(OutboundFailure::UnsupportedProtocols) =>
|
||||
"unsupported",
|
||||
};
|
||||
|
||||
metrics.requests_out_failure_total
|
||||
.with_label_values(&[&protocol, reason])
|
||||
.inc();
|
||||
}
|
||||
metrics.requests_out_failure_total
|
||||
.with_label_values(&[&protocol, reason])
|
||||
.inc();
|
||||
}
|
||||
}
|
||||
let _ = send_back.send(result);
|
||||
} else {
|
||||
error!("Request not in pending_requests");
|
||||
}
|
||||
},
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::OpaqueRequestStarted { protocol, .. })) => {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
metrics.requests_out_started_total
|
||||
.with_label_values(&[&protocol])
|
||||
.inc();
|
||||
}
|
||||
},
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::OpaqueRequestFinished { protocol, request_duration, .. })) => {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
metrics.requests_out_success_total
|
||||
.with_label_values(&[&protocol])
|
||||
.observe(request_duration.as_secs_f64());
|
||||
}
|
||||
},
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::RandomKademliaStarted(protocol))) => {
|
||||
@@ -1567,11 +1518,11 @@ impl<B: BlockT + 'static, H: ExHashT> Future for NetworkWorker<B, H> {
|
||||
let reason = match cause {
|
||||
Some(ConnectionError::IO(_)) => "transport-error",
|
||||
Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A(
|
||||
EitherError::A(EitherError::A(EitherError::B(
|
||||
EitherError::A(PingFailure::Timeout))))))))) => "ping-timeout",
|
||||
EitherError::A(EitherError::B(EitherError::A(
|
||||
PingFailure::Timeout)))))))) => "ping-timeout",
|
||||
Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A(
|
||||
EitherError::A(EitherError::A(EitherError::A(
|
||||
NotifsHandlerError::SyncNotificationsClogged)))))))) => "sync-notifications-clogged",
|
||||
EitherError::A(EitherError::A(
|
||||
NotifsHandlerError::SyncNotificationsClogged))))))) => "sync-notifications-clogged",
|
||||
Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(_))) => "protocol-error",
|
||||
Some(ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout)) => "keep-alive-timeout",
|
||||
None => "actively-closed",
|
||||
|
||||
Reference in New Issue
Block a user