From a1cf027fb611143b3937846542905d077dda61ae Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 18 Sep 2020 14:40:49 +0200 Subject: [PATCH] feat: add the list of supported libp2p protocols to /id Signed-off-by: ljedrz --- examples/fetch_and_cat.rs | 2 +- examples/ipfs_bitswap_test.rs | 2 +- http/src/v0/id.rs | 5 ++++- src/lib.rs | 22 +++++++++++----------- src/p2p/behaviour.rs | 8 ++++++++ src/p2p/swarm.rs | 7 ++++++- tests/listening_addresses.rs | 2 +- 7 files changed, 32 insertions(+), 16 deletions(-) diff --git a/examples/fetch_and_cat.rs b/examples/fetch_and_cat.rs index ad2669b28..6e1d306fe 100644 --- a/examples/fetch_and_cat.rs +++ b/examples/fetch_and_cat.rs @@ -60,7 +60,7 @@ async fn main() { if let Some(target) = target { ipfs.connect(target).await.unwrap(); } else { - let (_, addresses) = ipfs.identity().await.unwrap(); + let (_, addresses, _) = ipfs.identity().await.unwrap(); assert!(!addresses.is_empty(), "Zero listening addresses"); eprintln!("Please connect an ipfs node having {} to:\n", path); diff --git a/examples/ipfs_bitswap_test.rs b/examples/ipfs_bitswap_test.rs index 36008db5a..42c3f8514 100644 --- a/examples/ipfs_bitswap_test.rs +++ b/examples/ipfs_bitswap_test.rs @@ -24,7 +24,7 @@ async fn main() { let data = b"block-want\n".to_vec().into_boxed_slice(); let wanted = Cid::new_v1(Codec::Raw, Sha2_256::digest(&data)); - let (public_key, addresses) = ipfs.identity().await.unwrap(); + let (public_key, addresses, _) = ipfs.identity().await.unwrap(); assert!(!addresses.is_empty(), "Zero listening addresses"); eprintln!("Please connect an ipfs node having {} to:\n", wanted); diff --git a/http/src/v0/id.rs b/http/src/v0/id.rs index 7e6cb7e34..1adc8d412 100644 --- a/http/src/v0/id.rs +++ b/http/src/v0/id.rs @@ -38,7 +38,7 @@ async fn identity_query( } match ipfs.identity().await { - Ok((public_key, addresses)) => { + Ok((public_key, addresses, protocols)) => { let peer_id = public_key.clone().into_peer_id(); let id = peer_id.to_string(); let public_key = Base64Pad.encode(public_key.into_protobuf_encoding()); @@ -51,6 +51,7 @@ async fn identity_query( addresses, agent_version: "rust-ipfs/0.1.0", protocol_version: "ipfs/0.1.0", + protocols, }; Ok(warp::reply::json(&response)) @@ -82,4 +83,6 @@ struct Response { agent_version: &'static str, // Multiaddr alike ipfs/0.1.0 ... not sure if there are plans to bump this anytime soon protocol_version: &'static str, + // the list of supported libp2p protocols + protocols: Vec, } diff --git a/src/lib.rs b/src/lib.rs index a1d318892..363ab2437 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -276,8 +276,8 @@ enum IpfsEvent { Connections(Channel>), /// Disconnect Disconnect(MultiaddrWithPeerId, Channel<()>), - /// Request background task to return the listened and external addresses - GetAddresses(OneshotSender>), + /// Request background task to return the node's identity information + Indentify(OneshotSender<(Vec, Vec)>), PubsubSubscribe(String, OneshotSender>), PubsubUnsubscribe(String, OneshotSender), PubsubPublish(String, Vec, OneshotSender<()>), @@ -721,15 +721,12 @@ impl Ipfs { /// The addresses are suffixed with the P2p protocol containing the node's PeerId. /// /// Public key can be converted to [`PeerId`]. - pub async fn identity(&self) -> Result<(PublicKey, Vec), Error> { + pub async fn identity(&self) -> Result<(PublicKey, Vec, Vec), Error> { async move { let (tx, rx) = oneshot_channel(); - self.to_task - .clone() - .send(IpfsEvent::GetAddresses(tx)) - .await?; - let mut addresses = rx.await?; + self.to_task.clone().send(IpfsEvent::Indentify(tx)).await?; + let (mut addresses, protocols) = rx.await?; let public_key = self.keys.get_ref().public(); let peer_id = public_key.clone().into_peer_id(); @@ -737,7 +734,7 @@ impl Ipfs { addr.push(Protocol::P2p(peer_id.clone().into())) } - Ok((public_key, addresses)) + Ok((public_key, addresses, protocols)) } .instrument(self.span.clone()) .await @@ -1396,13 +1393,16 @@ impl Future for IpfsFuture { } ret.send(Ok(())).ok(); } - IpfsEvent::GetAddresses(ret) => { + IpfsEvent::Indentify(ret) => { // perhaps this could be moved under `IpfsEvent` or free functions? let mut addresses = Vec::new(); addresses.extend(Swarm::listeners(&self.swarm).cloned()); addresses.extend(Swarm::external_addresses(&self.swarm).cloned()); + + let protocols = self.swarm.protocols(); + // ignore error, perhaps caller went away already - let _ = ret.send(addresses); + let _ = ret.send((addresses, protocols)); } IpfsEvent::PubsubSubscribe(topic, ret) => { let _ = ret.send(self.swarm.pubsub().subscribe(topic)); diff --git a/src/p2p/behaviour.rs b/src/p2p/behaviour.rs index ca5bf3290..985cd06bd 100644 --- a/src/p2p/behaviour.rs +++ b/src/p2p/behaviour.rs @@ -623,6 +623,14 @@ impl Behaviour { Ok(ret.into_iter().collect()) } + + pub fn protocols(&self) -> Vec { + self.swarm + .protocols + .iter() + .map(|bytes| String::from_utf8_lossy(&bytes).into_owned()) + .collect() + } } /// Create a IPFS behaviour with the IPFS bootstrap nodes. diff --git a/src/p2p/swarm.rs b/src/p2p/swarm.rs index 82a220744..e37678d4a 100644 --- a/src/p2p/swarm.rs +++ b/src/p2p/swarm.rs @@ -46,6 +46,7 @@ pub struct SwarmApi { roundtrip_times: HashMap, connected_peers: HashMap>, pub(crate) bootstrappers: HashSet, + pub(crate) protocols: Vec>, } impl SwarmApi { @@ -242,8 +243,12 @@ impl NetworkBehaviour for SwarmApi { fn poll( &mut self, _: &mut Context, - _: &mut impl PollParameters, + params: &mut impl PollParameters, ) -> Poll { + if params.supported_protocols().len() != self.protocols.len() { + self.protocols = params.supported_protocols().collect(); + } + if let Some(event) = self.events.pop_front() { Poll::Ready(event) } else { diff --git a/tests/listening_addresses.rs b/tests/listening_addresses.rs index ab2e38f3c..151c543b4 100644 --- a/tests/listening_addresses.rs +++ b/tests/listening_addresses.rs @@ -128,7 +128,7 @@ async fn pre_configured_listening_addrs() { opts.listening_addrs.push(addr.clone()); let ipfs = Node::with_options(opts).await; - let (_id, addrs) = ipfs.identity().await.unwrap(); + let (_id, addrs, _) = ipfs.identity().await.unwrap(); let addrs: Vec = addrs .into_iter() .map(|addr| MultiaddrWithPeerId::try_from(addr).unwrap().multiaddr)