Skip to content

Commit fd7b5ac

Browse files
refactor(request-response): don't use upgrade infrastructure
This patch refactors `libp2p-request-response` to not use the "upgrade infrastructure" provided by `libp2p-swarm`. Instead, we directly convert the negotiated streams into futures that read and write the messages. Related: #3268. Related: #2863. Pull-Request: #3914. Co-authored-by: Yiannis Marangos <[email protected]>
1 parent fc6efaf commit fd7b5ac

File tree

16 files changed

+1030
-330
lines changed

16 files changed

+1030
-330
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/file-sharing/src/network.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use libp2p::{
88
identity, kad,
99
multiaddr::Protocol,
1010
noise,
11-
request_response::{self, ProtocolSupport, RequestId, ResponseChannel},
11+
request_response::{self, OutboundRequestId, ProtocolSupport, ResponseChannel},
1212
swarm::{NetworkBehaviour, Swarm, SwarmEvent},
1313
tcp, yamux, PeerId,
1414
};
@@ -175,7 +175,7 @@ pub(crate) struct EventLoop {
175175
pending_start_providing: HashMap<kad::QueryId, oneshot::Sender<()>>,
176176
pending_get_providers: HashMap<kad::QueryId, oneshot::Sender<HashSet<PeerId>>>,
177177
pending_request_file:
178-
HashMap<RequestId, oneshot::Sender<Result<Vec<u8>, Box<dyn Error + Send>>>>,
178+
HashMap<OutboundRequestId, oneshot::Sender<Result<Vec<u8>, Box<dyn Error + Send>>>>,
179179
}
180180

181181
impl EventLoop {

protocols/autonat/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## 0.12.0 - unreleased
22

3+
- Remove `Clone`, `PartialEq` and `Eq` implementations on `Event` and its sub-structs.
4+
The `Event` also contains errors which are not clonable or comparable.
5+
See [PR 3914](https://github.com/libp2p/rust-libp2p/pull/3914).
36

47
## 0.11.0
58

protocols/autonat/src/behaviour.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use instant::Instant;
3232
use libp2p_core::{multiaddr::Protocol, ConnectedPoint, Endpoint, Multiaddr};
3333
use libp2p_identity::PeerId;
3434
use libp2p_request_response::{
35-
self as request_response, ProtocolSupport, RequestId, ResponseChannel,
35+
self as request_response, InboundRequestId, OutboundRequestId, ProtocolSupport, ResponseChannel,
3636
};
3737
use libp2p_swarm::{
3838
behaviour::{
@@ -133,7 +133,7 @@ impl ProbeId {
133133
}
134134

135135
/// Event produced by [`Behaviour`].
136-
#[derive(Debug, Clone, PartialEq, Eq)]
136+
#[derive(Debug)]
137137
pub enum Event {
138138
/// Event on an inbound probe.
139139
InboundProbe(InboundProbeEvent),
@@ -187,14 +187,14 @@ pub struct Behaviour {
187187
PeerId,
188188
(
189189
ProbeId,
190-
RequestId,
190+
InboundRequestId,
191191
Vec<Multiaddr>,
192192
ResponseChannel<DialResponse>,
193193
),
194194
>,
195195

196196
// Ongoing outbound probes and mapped to the inner request id.
197-
ongoing_outbound: HashMap<RequestId, ProbeId>,
197+
ongoing_outbound: HashMap<OutboundRequestId, ProbeId>,
198198

199199
// Connected peers with the observed address of each connection.
200200
// If the endpoint of a connection is relayed or not global (in case of Config::only_global_ips),
@@ -220,9 +220,11 @@ pub struct Behaviour {
220220
impl Behaviour {
221221
pub fn new(local_peer_id: PeerId, config: Config) -> Self {
222222
let protocols = iter::once((DEFAULT_PROTOCOL_NAME, ProtocolSupport::Full));
223-
let mut cfg = request_response::Config::default();
224-
cfg.set_request_timeout(config.timeout);
225-
let inner = request_response::Behaviour::with_codec(AutoNatCodec, protocols, cfg);
223+
let inner = request_response::Behaviour::with_codec(
224+
AutoNatCodec,
225+
protocols,
226+
request_response::Config::default().with_request_timeout(config.timeout),
227+
);
226228
Self {
227229
local_peer_id,
228230
inner,

protocols/autonat/src/behaviour/as_client.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use futures_timer::Delay;
2929
use instant::Instant;
3030
use libp2p_core::Multiaddr;
3131
use libp2p_identity::PeerId;
32-
use libp2p_request_response::{self as request_response, OutboundFailure, RequestId};
32+
use libp2p_request_response::{self as request_response, OutboundFailure, OutboundRequestId};
3333
use libp2p_swarm::{ConnectionId, ListenAddresses, ToSwarm};
3434
use rand::{seq::SliceRandom, thread_rng};
3535
use std::{
@@ -39,7 +39,7 @@ use std::{
3939
};
4040

4141
/// Outbound probe failed or was aborted.
42-
#[derive(Debug, Clone, PartialEq, Eq)]
42+
#[derive(Debug)]
4343
pub enum OutboundProbeError {
4444
/// Probe was aborted because no server is known, or all servers
4545
/// are throttled through [`Config::throttle_server_period`].
@@ -53,7 +53,7 @@ pub enum OutboundProbeError {
5353
Response(ResponseError),
5454
}
5555

56-
#[derive(Debug, Clone, PartialEq, Eq)]
56+
#[derive(Debug)]
5757
pub enum OutboundProbeEvent {
5858
/// A dial-back request was sent to a remote peer.
5959
Request {
@@ -91,7 +91,7 @@ pub(crate) struct AsClient<'a> {
9191
pub(crate) throttled_servers: &'a mut Vec<(PeerId, Instant)>,
9292
pub(crate) nat_status: &'a mut NatStatus,
9393
pub(crate) confidence: &'a mut usize,
94-
pub(crate) ongoing_outbound: &'a mut HashMap<RequestId, ProbeId>,
94+
pub(crate) ongoing_outbound: &'a mut HashMap<OutboundRequestId, ProbeId>,
9595
pub(crate) last_probe: &'a mut Option<Instant>,
9696
pub(crate) schedule_probe: &'a mut Delay,
9797
pub(crate) listen_addresses: &'a ListenAddresses,
@@ -117,7 +117,7 @@ impl<'a> HandleInnerEvent for AsClient<'a> {
117117
let probe_id = self
118118
.ongoing_outbound
119119
.remove(&request_id)
120-
.expect("RequestId exists.");
120+
.expect("OutboundRequestId exists.");
121121

122122
let event = match response.result.clone() {
123123
Ok(address) => OutboundProbeEvent::Response {

protocols/autonat/src/behaviour/as_server.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use instant::Instant;
2626
use libp2p_core::{multiaddr::Protocol, Multiaddr};
2727
use libp2p_identity::PeerId;
2828
use libp2p_request_response::{
29-
self as request_response, InboundFailure, RequestId, ResponseChannel,
29+
self as request_response, InboundFailure, InboundRequestId, ResponseChannel,
3030
};
3131
use libp2p_swarm::{
3232
dial_opts::{DialOpts, PeerCondition},
@@ -38,15 +38,15 @@ use std::{
3838
};
3939

4040
/// Inbound probe failed.
41-
#[derive(Debug, Clone, PartialEq, Eq)]
41+
#[derive(Debug)]
4242
pub enum InboundProbeError {
4343
/// Receiving the dial-back request or sending a response failed.
4444
InboundRequest(InboundFailure),
4545
/// We refused or failed to dial the client.
4646
Response(ResponseError),
4747
}
4848

49-
#[derive(Debug, Clone, PartialEq, Eq)]
49+
#[derive(Debug)]
5050
pub enum InboundProbeEvent {
5151
/// A dial-back request was received from a remote peer.
5252
Request {
@@ -85,7 +85,7 @@ pub(crate) struct AsServer<'a> {
8585
PeerId,
8686
(
8787
ProbeId,
88-
RequestId,
88+
InboundRequestId,
8989
Vec<Multiaddr>,
9090
ResponseChannel<DialResponse>,
9191
),

protocols/autonat/tests/test_client.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ async fn test_auto_probe() {
6161
match client.next_behaviour_event().await {
6262
Event::OutboundProbe(OutboundProbeEvent::Error { peer, error, .. }) => {
6363
assert!(peer.is_none());
64-
assert_eq!(error, OutboundProbeError::NoAddresses);
64+
assert!(matches!(error, OutboundProbeError::NoAddresses));
6565
}
6666
other => panic!("Unexpected behaviour event: {other:?}."),
6767
}
@@ -181,10 +181,10 @@ async fn test_confidence() {
181181
peer,
182182
error,
183183
} if !test_public => {
184-
assert_eq!(
184+
assert!(matches!(
185185
error,
186186
OutboundProbeError::Response(ResponseError::DialError)
187-
);
187+
));
188188
(peer.unwrap(), probe_id)
189189
}
190190
other => panic!("Unexpected Outbound Event: {other:?}"),
@@ -261,7 +261,7 @@ async fn test_throttle_server_period() {
261261
match client.next_behaviour_event().await {
262262
Event::OutboundProbe(OutboundProbeEvent::Error { peer, error, .. }) => {
263263
assert!(peer.is_none());
264-
assert_eq!(error, OutboundProbeError::NoServer);
264+
assert!(matches!(error, OutboundProbeError::NoServer));
265265
}
266266
other => panic!("Unexpected behaviour event: {other:?}."),
267267
}

protocols/autonat/tests/test_server.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,10 @@ async fn test_dial_error() {
168168
}) => {
169169
assert_eq!(probe_id, request_probe_id);
170170
assert_eq!(peer, client_id);
171-
assert_eq!(error, InboundProbeError::Response(ResponseError::DialError));
171+
assert!(matches!(
172+
error,
173+
InboundProbeError::Response(ResponseError::DialError)
174+
));
172175
}
173176
other => panic!("Unexpected behaviour event: {other:?}."),
174177
}
@@ -252,10 +255,10 @@ async fn test_throttle_peer_max() {
252255
}) => {
253256
assert_eq!(client_id, peer);
254257
assert_ne!(first_probe_id, probe_id);
255-
assert_eq!(
258+
assert!(matches!(
256259
error,
257260
InboundProbeError::Response(ResponseError::DialRefused)
258-
)
261+
));
259262
}
260263
other => panic!("Unexpected behaviour event: {other:?}."),
261264
};

protocols/rendezvous/src/client.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use futures::stream::FuturesUnordered;
2626
use futures::stream::StreamExt;
2727
use libp2p_core::{Endpoint, Multiaddr, PeerRecord};
2828
use libp2p_identity::{Keypair, PeerId, SigningError};
29-
use libp2p_request_response::{ProtocolSupport, RequestId};
29+
use libp2p_request_response::{OutboundRequestId, ProtocolSupport};
3030
use libp2p_swarm::{
3131
ConnectionDenied, ConnectionId, ExternalAddresses, FromSwarm, NetworkBehaviour, THandler,
3232
THandlerInEvent, THandlerOutEvent, ToSwarm,
@@ -41,8 +41,8 @@ pub struct Behaviour {
4141

4242
keypair: Keypair,
4343

44-
waiting_for_register: HashMap<RequestId, (PeerId, Namespace)>,
45-
waiting_for_discovery: HashMap<RequestId, (PeerId, Option<Namespace>)>,
44+
waiting_for_register: HashMap<OutboundRequestId, (PeerId, Namespace)>,
45+
waiting_for_discovery: HashMap<OutboundRequestId, (PeerId, Option<Namespace>)>,
4646

4747
/// Hold addresses of all peers that we have discovered so far.
4848
///
@@ -336,7 +336,7 @@ impl NetworkBehaviour for Behaviour {
336336
}
337337

338338
impl Behaviour {
339-
fn event_for_outbound_failure(&mut self, req_id: &RequestId) -> Option<Event> {
339+
fn event_for_outbound_failure(&mut self, req_id: &OutboundRequestId) -> Option<Event> {
340340
if let Some((rendezvous_node, namespace)) = self.waiting_for_register.remove(req_id) {
341341
return Some(Event::RegisterFailed {
342342
rendezvous_node,
@@ -356,7 +356,11 @@ impl Behaviour {
356356
None
357357
}
358358

359-
fn handle_response(&mut self, request_id: &RequestId, response: Message) -> Option<Event> {
359+
fn handle_response(
360+
&mut self,
361+
request_id: &OutboundRequestId,
362+
response: Message,
363+
) -> Option<Event> {
360364
match response {
361365
RegisterResponse(Ok(ttl)) => {
362366
if let Some((rendezvous_node, namespace)) =

protocols/request-response/CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
- Remove `request_response::Config::set_connection_keep_alive` in favor of `SwarmBuilder::idle_connection_timeout`.
44
See [PR 4679](https://github.com/libp2p/rust-libp2p/pull/4679).
5-
5+
- Allow at most 100 concurrent inbound + outbound streams per instance of `request_response::Behaviour`.
6+
This limit is configurable via `Config::with_max_concurrent_streams`.
7+
See [PR 3914](https://github.com/libp2p/rust-libp2p/pull/3914).
8+
- Report IO failures on inbound and outbound streams.
9+
See [PR 3914](https://github.com/libp2p/rust-libp2p/pull/3914).
10+
- Introduce dedicated types for `InboundRequestId` and `OutboundRequestId`.
11+
See [PR 3914](https://github.com/libp2p/rust-libp2p/pull/3914).
612
- Keep peer addresses in `HashSet` instead of `SmallVec` to prevent adding duplicate addresses.
713
See [PR 4700](https://github.com/libp2p/rust-libp2p/pull/4700).
814

0 commit comments

Comments
 (0)