mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-07-02 19:21:37 +00:00
feat: leverage type-safe /p2p
in multiaddr
This updates `multiaddr` to version `0.19`. Depends-On: #3656. Depends-On: https://github.com/multiformats/rust-multiaddr/pull/83. Resolves: #4039. Pull-Request: #4037.
This commit is contained in:
@ -22,7 +22,6 @@
|
||||
use crate::ConnectionId;
|
||||
use libp2p_core::connection::Endpoint;
|
||||
use libp2p_core::multiaddr::Protocol;
|
||||
use libp2p_core::multihash::Multihash;
|
||||
use libp2p_core::Multiaddr;
|
||||
use libp2p_identity::PeerId;
|
||||
use std::num::NonZeroU8;
|
||||
@ -81,9 +80,21 @@ impl DialOpts {
|
||||
WithoutPeerId {}
|
||||
}
|
||||
|
||||
/// Get the [`PeerId`] specified in a [`DialOpts`] if any.
|
||||
/// Retrieves the [`PeerId`] from the [`DialOpts`] if specified or otherwise tries to extract it
|
||||
/// from the multihash in the `/p2p` part of the address, if present.
|
||||
pub fn get_peer_id(&self) -> Option<PeerId> {
|
||||
self.peer_id
|
||||
if let Some(peer_id) = self.peer_id {
|
||||
return Some(peer_id);
|
||||
}
|
||||
|
||||
let first_address = self.addresses.first()?;
|
||||
let last_protocol = first_address.iter().last()?;
|
||||
|
||||
if let Protocol::P2p(p) = last_protocol {
|
||||
return Some(p);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Get the [`ConnectionId`] of this dial attempt.
|
||||
@ -94,40 +105,6 @@ impl DialOpts {
|
||||
self.connection_id
|
||||
}
|
||||
|
||||
/// Retrieves the [`PeerId`] from the [`DialOpts`] if specified or otherwise tries to parse it
|
||||
/// from the multihash in the `/p2p` part of the address, if present.
|
||||
///
|
||||
/// Note: A [`Multiaddr`] with something else other than a [`PeerId`] within the `/p2p` protocol is invalid as per specification.
|
||||
/// Unfortunately, we are not making good use of the type system here.
|
||||
/// Really, this function should be merged with [`DialOpts::get_peer_id`] above.
|
||||
/// If it weren't for the parsing error, the function signatures would be the same.
|
||||
///
|
||||
/// See <https://github.com/multiformats/rust-multiaddr/issues/73>.
|
||||
pub(crate) fn get_or_parse_peer_id(&self) -> Result<Option<PeerId>, Multihash> {
|
||||
if let Some(peer_id) = self.peer_id {
|
||||
return Ok(Some(peer_id));
|
||||
}
|
||||
|
||||
let first_address = match self.addresses.first() {
|
||||
Some(first_address) => first_address,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let maybe_peer_id = first_address
|
||||
.iter()
|
||||
.last()
|
||||
.and_then(|p| {
|
||||
if let Protocol::P2p(ma) = p {
|
||||
Some(PeerId::try_from(ma))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
Ok(maybe_peer_id)
|
||||
}
|
||||
|
||||
pub(crate) fn get_addresses(&self) -> Vec<Multiaddr> {
|
||||
self.addresses.clone()
|
||||
}
|
||||
|
@ -136,7 +136,6 @@ use futures::{prelude::*, stream::FusedStream};
|
||||
use libp2p_core::{
|
||||
connection::ConnectedPoint,
|
||||
multiaddr,
|
||||
multihash::Multihash,
|
||||
muxing::StreamMuxerBox,
|
||||
transport::{self, ListenerId, TransportError, TransportEvent},
|
||||
Endpoint, Multiaddr, Transport,
|
||||
@ -415,9 +414,7 @@ where
|
||||
pub fn dial(&mut self, opts: impl Into<DialOpts>) -> Result<(), DialError> {
|
||||
let dial_opts = opts.into();
|
||||
|
||||
let peer_id = dial_opts
|
||||
.get_or_parse_peer_id()
|
||||
.map_err(DialError::InvalidPeerId)?;
|
||||
let peer_id = dial_opts.get_peer_id();
|
||||
let condition = dial_opts.peer_condition();
|
||||
let connection_id = dial_opts.connection_id();
|
||||
|
||||
@ -1008,11 +1005,11 @@ where
|
||||
match event {
|
||||
ToSwarm::GenerateEvent(event) => return Some(SwarmEvent::Behaviour(event)),
|
||||
ToSwarm::Dial { opts } => {
|
||||
let peer_id = opts.get_or_parse_peer_id();
|
||||
let peer_id = opts.get_peer_id();
|
||||
let connection_id = opts.connection_id();
|
||||
if let Ok(()) = self.dial(opts) {
|
||||
return Some(SwarmEvent::Dialing {
|
||||
peer_id: peer_id.ok().flatten(),
|
||||
peer_id,
|
||||
connection_id,
|
||||
});
|
||||
}
|
||||
@ -1519,8 +1516,6 @@ pub enum DialError {
|
||||
DialPeerConditionFalse(dial_opts::PeerCondition),
|
||||
/// Pending connection attempt has been aborted.
|
||||
Aborted,
|
||||
/// The provided peer identity is invalid.
|
||||
InvalidPeerId(Multihash),
|
||||
/// The peer identity obtained on the connection did not match the one that was expected.
|
||||
WrongPeerId {
|
||||
obtained: PeerId,
|
||||
@ -1561,9 +1556,6 @@ impl fmt::Display for DialError {
|
||||
f,
|
||||
"Dial error: Pending connection attempt has been aborted."
|
||||
),
|
||||
DialError::InvalidPeerId(multihash) => {
|
||||
write!(f, "Dial error: multihash {multihash:?} is not a PeerId")
|
||||
}
|
||||
DialError::WrongPeerId { obtained, endpoint } => write!(
|
||||
f,
|
||||
"Dial error: Unexpected peer ID {obtained} at {endpoint:?}."
|
||||
@ -1604,7 +1596,6 @@ impl error::Error for DialError {
|
||||
DialError::NoAddresses => None,
|
||||
DialError::DialPeerConditionFalse(_) => None,
|
||||
DialError::Aborted => None,
|
||||
DialError::InvalidPeerId { .. } => None,
|
||||
DialError::WrongPeerId { .. } => None,
|
||||
DialError::Transport(_) => None,
|
||||
DialError::Denied { cause } => Some(cause),
|
||||
@ -1763,14 +1754,15 @@ fn p2p_addr(peer: Option<PeerId>, addr: Multiaddr) -> Result<Multiaddr, Multiadd
|
||||
None => return Ok(addr),
|
||||
};
|
||||
|
||||
if let Some(multiaddr::Protocol::P2p(hash)) = addr.iter().last() {
|
||||
if &hash != peer.as_ref() {
|
||||
if let Some(multiaddr::Protocol::P2p(peer_id)) = addr.iter().last() {
|
||||
if peer_id != peer {
|
||||
return Err(addr);
|
||||
}
|
||||
Ok(addr)
|
||||
} else {
|
||||
Ok(addr.with(multiaddr::Protocol::P2p(peer.into())))
|
||||
|
||||
return Ok(addr);
|
||||
}
|
||||
|
||||
Ok(addr.with(multiaddr::Protocol::P2p(peer)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -2173,7 +2165,7 @@ mod tests {
|
||||
}));
|
||||
|
||||
let other_id = PeerId::random();
|
||||
let other_addr = address.with(multiaddr::Protocol::P2p(other_id.into()));
|
||||
let other_addr = address.with(multiaddr::Protocol::P2p(other_id));
|
||||
|
||||
swarm2.dial(other_addr.clone()).unwrap();
|
||||
|
||||
@ -2322,7 +2314,7 @@ mod tests {
|
||||
let failed_addresses = errors.into_iter().map(|(addr, _)| addr).collect::<Vec<_>>();
|
||||
let expected_addresses = addresses
|
||||
.into_iter()
|
||||
.map(|addr| addr.with(multiaddr::Protocol::P2p(target.into())))
|
||||
.map(|addr| addr.with(multiaddr::Protocol::P2p(target)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(expected_addresses, failed_addresses);
|
||||
|
Reference in New Issue
Block a user