Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Add the list of supported libp2p protocols to /id #381

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/fetch_and_cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion examples/ipfs_bitswap_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion http/src/v0/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async fn identity_query<T: IpfsTypes>(
}

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());
Expand All @@ -51,6 +51,7 @@ async fn identity_query<T: IpfsTypes>(
addresses,
agent_version: "rust-ipfs/0.1.0",
protocol_version: "ipfs/0.1.0",
protocols,
};

Ok(warp::reply::json(&response))
Expand Down Expand Up @@ -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<String>,
}
22 changes: 11 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ enum IpfsEvent {
Connections(Channel<Vec<Connection>>),
/// Disconnect
Disconnect(MultiaddrWithPeerId, Channel<()>),
/// Request background task to return the listened and external addresses
GetAddresses(OneshotSender<Vec<Multiaddr>>),
/// Request background task to return the node's identity information
Indentify(OneshotSender<(Vec<Multiaddr>, Vec<String>)>),
PubsubSubscribe(String, OneshotSender<Option<SubscriptionStream>>),
PubsubUnsubscribe(String, OneshotSender<bool>),
PubsubPublish(String, Vec<u8>, OneshotSender<()>),
Expand Down Expand Up @@ -721,23 +721,20 @@ impl<Types: IpfsTypes> Ipfs<Types> {
/// 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<Multiaddr>), Error> {
pub async fn identity(&self) -> Result<(PublicKey, Vec<Multiaddr>, Vec<String>), 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();

for addr in &mut addresses {
addr.push(Protocol::P2p(peer_id.clone().into()))
}

Ok((public_key, addresses))
Ok((public_key, addresses, protocols))
}
.instrument(self.span.clone())
.await
Expand Down Expand Up @@ -1396,13 +1393,16 @@ impl<TRepoTypes: RepoTypes> Future for IpfsFuture<TRepoTypes> {
}
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));
Expand Down
8 changes: 8 additions & 0 deletions src/p2p/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,14 @@ impl<Types: IpfsTypes> Behaviour<Types> {

Ok(ret.into_iter().collect())
}

pub fn protocols(&self) -> Vec<String> {
self.swarm
.protocols
.iter()
.map(|bytes| String::from_utf8_lossy(&bytes).into_owned())
.collect()
}
}

/// Create a IPFS behaviour with the IPFS bootstrap nodes.
Expand Down
7 changes: 6 additions & 1 deletion src/p2p/swarm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub struct SwarmApi {
roundtrip_times: HashMap<PeerId, Duration>,
connected_peers: HashMap<PeerId, Vec<MultiaddrWithoutPeerId>>,
pub(crate) bootstrappers: HashSet<MultiaddrWithPeerId>,
pub(crate) protocols: Vec<Vec<u8>>,
}

impl SwarmApi {
Expand Down Expand Up @@ -242,8 +243,12 @@ impl NetworkBehaviour for SwarmApi {
fn poll(
&mut self,
_: &mut Context,
_: &mut impl PollParameters,
params: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction> {
if params.supported_protocols().len() != self.protocols.len() {
Copy link
Member Author

@ljedrz ljedrz Sep 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PollParameters::supported_protocols returns an ExactSizeIterator, so obtaining the len is cheap; this implementation assumes that the protocols could change during the node's lifetime

self.protocols = params.supported_protocols().collect();
}

if let Some(event) = self.events.pop_front() {
Poll::Ready(event)
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/listening_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MultiaddrWithoutPeerId> = addrs
.into_iter()
.map(|addr| MultiaddrWithPeerId::try_from(addr).unwrap().multiaddr)
Expand Down