feat: extended Multiaddr wrapper error handling
Signed-off-by: ljedrz <ljedrz@gmail.com>
This commit is contained in:
parent
10639a614a
commit
dcae04f6e2
@ -1,16 +1,25 @@
|
||||
use libp2p::{multiaddr::Protocol, Multiaddr, PeerId};
|
||||
use std::{convert::TryFrom, fmt, str::FromStr};
|
||||
use libp2p::{
|
||||
multiaddr::{self, Protocol},
|
||||
Multiaddr, PeerId,
|
||||
};
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
fmt,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
/// An error that can be thrown when converting to `MultiaddrWithPeerId` and
|
||||
/// `MultiaddrWithoutPeerId`.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub enum MultiaddrWrapperError {
|
||||
/// The source `Multiaddr` unexpectedly contains `Protocol::P2p`.
|
||||
ContainsProtocolP2p,
|
||||
/// The provided `Multiaddr` is invalid.
|
||||
InvalidMultiaddr,
|
||||
/// The `Protocol::P2p` is missing from the source `Multiaddr`.
|
||||
MissingProtocolP2p,
|
||||
InvalidMultiaddr(multiaddr::Error),
|
||||
/// The `PeerId` created based on the `Protocol::P2p` is invalid.
|
||||
InvalidPeerId,
|
||||
/// The `Protocol::P2p` is unexpectedly missing from the source `Multiaddr`.
|
||||
MissingProtocolP2p,
|
||||
}
|
||||
|
||||
impl fmt::Display for MultiaddrWrapperError {
|
||||
@ -25,13 +34,15 @@ impl std::error::Error for MultiaddrWrapperError {}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct MultiaddrWithoutPeerId(Multiaddr);
|
||||
|
||||
impl From<Multiaddr> for MultiaddrWithoutPeerId {
|
||||
fn from(addr: Multiaddr) -> Self {
|
||||
Self(
|
||||
addr.into_iter()
|
||||
.filter(|p| !matches!(p, Protocol::P2p(_)))
|
||||
.collect(),
|
||||
)
|
||||
impl TryFrom<Multiaddr> for MultiaddrWithoutPeerId {
|
||||
type Error = MultiaddrWrapperError;
|
||||
|
||||
fn try_from(addr: Multiaddr) -> Result<Self, Self::Error> {
|
||||
if addr.iter().any(|p| matches!(p, Protocol::P2p(_))) {
|
||||
Err(MultiaddrWrapperError::ContainsProtocolP2p)
|
||||
} else {
|
||||
Ok(Self(addr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,8 +65,8 @@ impl FromStr for MultiaddrWithoutPeerId {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let multiaddr = s
|
||||
.parse::<Multiaddr>()
|
||||
.map_err(|_| MultiaddrWrapperError::InvalidMultiaddr)?;
|
||||
Ok(multiaddr.into())
|
||||
.map_err(MultiaddrWrapperError::InvalidMultiaddr)?;
|
||||
multiaddr.try_into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +106,7 @@ impl FromStr for MultiaddrWithPeerId {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let multiaddr = s
|
||||
.parse::<Multiaddr>()
|
||||
.map_err(|_| MultiaddrWrapperError::InvalidMultiaddr)?;
|
||||
.map_err(MultiaddrWrapperError::InvalidMultiaddr)?;
|
||||
Self::try_from(multiaddr)
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use libp2p::swarm::protocols_handler::{
|
||||
};
|
||||
use libp2p::swarm::{self, NetworkBehaviour, PollParameters, Swarm};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::convert::TryInto;
|
||||
use std::time::Duration;
|
||||
|
||||
/// A description of currently active connection.
|
||||
@ -154,18 +155,17 @@ impl NetworkBehaviour for SwarmApi {
|
||||
) {
|
||||
// TODO: could be that the connection is not yet fully established at this point
|
||||
trace!("inject_connected {} {:?}", peer_id, cp);
|
||||
let addr = connection_point_addr(cp).to_owned();
|
||||
let addr: MultiaddrWithoutPeerId = connection_point_addr(cp).to_owned().try_into().unwrap();
|
||||
|
||||
self.peers.insert(peer_id.clone());
|
||||
let connections = self.connected_peers.entry(peer_id.clone()).or_default();
|
||||
connections.push(addr.clone().into());
|
||||
connections.push(addr.clone());
|
||||
|
||||
self.connections
|
||||
.insert(addr.clone().into(), peer_id.clone());
|
||||
self.connections.insert(addr.clone(), peer_id.clone());
|
||||
|
||||
if let ConnectedPoint::Dialer { .. } = cp {
|
||||
let addr = MultiaddrWithPeerId {
|
||||
multiaddr: addr.into(),
|
||||
multiaddr: addr,
|
||||
peer_id: peer_id.clone(),
|
||||
};
|
||||
|
||||
@ -185,7 +185,7 @@ impl NetworkBehaviour for SwarmApi {
|
||||
cp: &ConnectedPoint,
|
||||
) {
|
||||
trace!("inject_connection_closed {} {:?}", peer_id, cp);
|
||||
let closed_addr = connection_point_addr(cp).to_owned().into();
|
||||
let closed_addr = connection_point_addr(cp).to_owned().try_into().unwrap();
|
||||
|
||||
let became_empty = if let Some(connections) = self.connected_peers.get_mut(peer_id) {
|
||||
if let Some(index) = connections.iter().position(|addr| *addr == closed_addr) {
|
||||
@ -223,9 +223,8 @@ impl NetworkBehaviour for SwarmApi {
|
||||
error: &dyn std::error::Error,
|
||||
) {
|
||||
trace!("inject_addr_reach_failure {} {}", addr, error);
|
||||
if let Some(peer_id) = peer_id {
|
||||
let ma: MultiaddrWithoutPeerId = addr.clone().into();
|
||||
let addr = MultiaddrWithPeerId::from((ma, peer_id.to_owned()));
|
||||
if peer_id.is_some() {
|
||||
let addr: MultiaddrWithPeerId = addr.clone().try_into().unwrap();
|
||||
self.connect_registry
|
||||
.finish_subscription(addr.into(), Err(error.to_string()));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user