feat: allow connecting using /Multiaddr/p2p/PeerId addresses
Signed-off-by: ljedrz <ljedrz@gmail.com>
This commit is contained in:
parent
47322befb7
commit
cc12650d17
@ -1,5 +1,5 @@
|
||||
use super::support::{with_ipfs, StringError};
|
||||
use ipfs::{Ipfs, IpfsTypes, Multiaddr};
|
||||
use ipfs::{p2p::ConnectionTarget, Ipfs, IpfsTypes, Multiaddr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
@ -7,14 +7,18 @@ use warp::{query, Filter};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ConnectQuery {
|
||||
arg: Multiaddr,
|
||||
arg: String,
|
||||
}
|
||||
|
||||
async fn connect_query<T: IpfsTypes>(
|
||||
ipfs: Ipfs<T>,
|
||||
query: ConnectQuery,
|
||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||
ipfs.connect(query.arg)
|
||||
let target = query
|
||||
.arg
|
||||
.parse::<ConnectionTarget>()
|
||||
.map_err(|e| warp::reject::custom(StringError::from(e)))?;
|
||||
ipfs.connect(target)
|
||||
.await
|
||||
.map_err(|e| warp::reject::custom(StringError::from(e)))?;
|
||||
let response: &[&str] = &[];
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::subscription::{SubscriptionFuture, SubscriptionRegistry};
|
||||
use anyhow::anyhow;
|
||||
use core::task::{Context, Poll};
|
||||
use libp2p::core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId};
|
||||
use libp2p::swarm::protocols_handler::{
|
||||
@ -6,6 +7,7 @@ use libp2p::swarm::protocols_handler::{
|
||||
};
|
||||
use libp2p::swarm::{self, DialPeerCondition, NetworkBehaviour, PollParameters, Swarm};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
/// A description of currently active connection.
|
||||
@ -23,6 +25,7 @@ pub struct Connection {
|
||||
pub enum ConnectionTarget {
|
||||
Addr(Multiaddr),
|
||||
PeerId(PeerId),
|
||||
PeerIdWithAddr(PeerId, Multiaddr),
|
||||
}
|
||||
|
||||
impl From<Multiaddr> for ConnectionTarget {
|
||||
@ -37,6 +40,33 @@ impl From<PeerId> for ConnectionTarget {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ConnectionTarget {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.contains("/p2p/") {
|
||||
let mut iter = s.split("/p2p/");
|
||||
|
||||
let addr = iter
|
||||
.next()
|
||||
.ok_or_else(|| anyhow!("missing Multiaddr part of the address"))?
|
||||
.parse::<Multiaddr>()?;
|
||||
let peer_id = iter
|
||||
.next()
|
||||
.ok_or_else(|| anyhow!("missing PeerId part of the address"))?
|
||||
.parse::<PeerId>()?;
|
||||
|
||||
Ok(ConnectionTarget::PeerIdWithAddr(peer_id, addr))
|
||||
} else if s.contains('/') {
|
||||
let addr = s.parse::<Multiaddr>()?;
|
||||
Ok(ConnectionTarget::Addr(addr))
|
||||
} else {
|
||||
let peer_id = s.parse::<PeerId>()?;
|
||||
Ok(ConnectionTarget::PeerId(peer_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Disconnected will use banning to disconnect a node. Disconnecting a single peer connection is
|
||||
/// not supported at the moment.
|
||||
pub struct Disconnector {
|
||||
@ -105,6 +135,9 @@ impl SwarmApi {
|
||||
let will_attempt_connection = match target {
|
||||
ConnectionTarget::PeerId(ref id) => self.connected_peers.get(id).is_none(),
|
||||
ConnectionTarget::Addr(ref addr) => !self.connections.contains_key(addr),
|
||||
ConnectionTarget::PeerIdWithAddr(ref id, ref addr) => {
|
||||
self.connected_peers.get(id).is_none() || !self.connections.contains_key(addr)
|
||||
}
|
||||
};
|
||||
|
||||
if !will_attempt_connection {
|
||||
@ -113,6 +146,14 @@ impl SwarmApi {
|
||||
|
||||
trace!("Connecting to {:?}", target);
|
||||
|
||||
// convert the ConnectionTarget to the actual dial method so that it's easier
|
||||
// to handle the subscription we'll be creating.
|
||||
let target = if let ConnectionTarget::PeerIdWithAddr(_id, addr) = target {
|
||||
ConnectionTarget::Addr(addr)
|
||||
} else {
|
||||
target
|
||||
};
|
||||
|
||||
let subscription = self
|
||||
.connect_registry
|
||||
.create_subscription(target.clone().into(), None);
|
||||
@ -123,6 +164,7 @@ impl SwarmApi {
|
||||
peer_id,
|
||||
condition: DialPeerCondition::Disconnected,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
});
|
||||
|
||||
Some(subscription)
|
||||
@ -277,6 +319,26 @@ mod tests {
|
||||
use libp2p::identity::Keypair;
|
||||
use libp2p::swarm::Swarm;
|
||||
|
||||
#[test]
|
||||
fn connection_targets() {
|
||||
let peer_id = "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ";
|
||||
let multiaddr = "/ip4/104.131.131.82/tcp/4001";
|
||||
let both = format!("{}/p2p/{}", multiaddr, peer_id);
|
||||
|
||||
assert!(matches!(
|
||||
peer_id.parse().unwrap(),
|
||||
ConnectionTarget::PeerId(_)
|
||||
));
|
||||
assert!(matches!(
|
||||
multiaddr.parse().unwrap(),
|
||||
ConnectionTarget::Addr(_)
|
||||
));
|
||||
assert!(matches!(
|
||||
both.parse().unwrap(),
|
||||
ConnectionTarget::PeerIdWithAddr(..)
|
||||
));
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn swarm_api() {
|
||||
let (peer1_id, trans) = mk_transport();
|
||||
|
Loading…
Reference in New Issue
Block a user