mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 10:01:25 +00:00
{core,swarm}/: Don't require Transport: Clone
and take &mut
(#2529)
Previously `libp2p-swarm` required a `Transport` to be `Clone`. Methods on `Transport`, e.g. `Transport::dial` would take ownership, requiring e.g. a `Clone::clone` before calling `Transport::dial`. The requirement of `Transport` to be `Clone` is no longer needed in `libp2p-swarm`. E.g. concurrent dialing can be done without a clone per dial. This commit removes the requirement of `Clone` for `Transport` in `libp2p-swarm`. As a follow-up methods on `Transport` no longer take ownership, but instead a mutable reference (`&mut self`). On the one hand this simplifies `libp2p-swarm`, on the other it simplifies implementations of `Transport`.
This commit is contained in:
@ -91,7 +91,7 @@ use libp2p_core::{
|
||||
muxing::StreamMuxerBox,
|
||||
transport::{self, TransportError},
|
||||
upgrade::ProtocolName,
|
||||
Executor, Multiaddr, Negotiated, PeerId, Transport,
|
||||
Endpoint, Executor, Multiaddr, Negotiated, PeerId, Transport,
|
||||
};
|
||||
use registry::{AddressIntoIter, Addresses};
|
||||
use smallvec::SmallVec;
|
||||
@ -502,9 +502,33 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
let dials = addresses
|
||||
.map(|a| match p2p_addr(peer_id, a) {
|
||||
Ok(address) => {
|
||||
let dial = match role_override {
|
||||
Endpoint::Dialer => self.listeners.transport_mut().dial(address.clone()),
|
||||
Endpoint::Listener => self
|
||||
.listeners
|
||||
.transport_mut()
|
||||
.dial_as_listener(address.clone()),
|
||||
};
|
||||
match dial {
|
||||
Ok(fut) => fut
|
||||
.map(|r| (address, r.map_err(|e| TransportError::Other(e))))
|
||||
.boxed(),
|
||||
Err(err) => futures::future::ready((address, Err(err))).boxed(),
|
||||
}
|
||||
}
|
||||
Err(address) => futures::future::ready((
|
||||
address.clone(),
|
||||
Err(TransportError::MultiaddrNotSupported(address)),
|
||||
))
|
||||
.boxed(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
match self.pool.add_outgoing(
|
||||
self.listeners.transport().clone(),
|
||||
addresses,
|
||||
dials,
|
||||
peer_id,
|
||||
handler,
|
||||
role_override,
|
||||
@ -1527,6 +1551,32 @@ impl NetworkInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures a given `Multiaddr` is a `/p2p/...` address for the given peer.
|
||||
///
|
||||
/// If the given address is already a `p2p` address for the given peer,
|
||||
/// i.e. the last encapsulated protocol is `/p2p/<peer-id>`, this is a no-op.
|
||||
///
|
||||
/// If the given address is already a `p2p` address for a different peer
|
||||
/// than the one given, the given `Multiaddr` is returned as an `Err`.
|
||||
///
|
||||
/// If the given address is not yet a `p2p` address for the given peer,
|
||||
/// the `/p2p/<peer-id>` protocol is appended to the returned address.
|
||||
fn p2p_addr(peer: Option<PeerId>, addr: Multiaddr) -> Result<Multiaddr, Multiaddr> {
|
||||
let peer = match peer {
|
||||
Some(p) => p,
|
||||
None => return Ok(addr),
|
||||
};
|
||||
|
||||
if let Some(Protocol::P2p(hash)) = addr.iter().last() {
|
||||
if &hash != peer.as_ref() {
|
||||
return Err(addr);
|
||||
}
|
||||
Ok(addr)
|
||||
} else {
|
||||
Ok(addr.with(Protocol::P2p(peer.into())))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
Reference in New Issue
Block a user