diff --git a/core/src/swarm.rs b/core/src/swarm.rs index 55c535df..1c071847 100644 --- a/core/src/swarm.rs +++ b/core/src/swarm.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. use crate::{ - Transport, Multiaddr, PeerId, InboundUpgrade, OutboundUpgrade, UpgradeInfo, + Transport, Multiaddr, PublicKey, PeerId, InboundUpgrade, OutboundUpgrade, UpgradeInfo, muxing::StreamMuxer, nodes::{ handled_node::NodeHandler, @@ -55,9 +55,18 @@ where TTransport: Transport, /// if we're not connected to them. topology: TTopology, + /// Public key of the local node. + local_public_key: PublicKey, + + /// Peer ID of the local node. + local_peer_id: PeerId, + /// List of protocols that the behaviour says it supports. supported_protocols: SmallVec<[Vec; 16]>, + /// List of multiaddresses we're listening on. + listened_addrs: SmallVec<[Multiaddr; 8]>, + /// List of multiaddresses we're listening on after NAT traversal. external_addresses: SmallVec<[Multiaddr; 8]>, } @@ -112,7 +121,7 @@ where TBehaviour: NetworkBehaviour, { /// Builds a new `Swarm`. #[inline] - pub fn new(transport: TTransport, mut behaviour: TBehaviour, topology: TTopology) -> Self { + pub fn new(transport: TTransport, mut behaviour: TBehaviour, topology: TTopology, local_public_key: PublicKey) -> Self { let supported_protocols = behaviour .new_handler() .listen_protocol() @@ -121,11 +130,17 @@ where TBehaviour: NetworkBehaviour, .collect(); let raw_swarm = RawSwarm::new(transport); + + let local_peer_id = local_public_key.clone().into_peer_id(); + Swarm { raw_swarm, behaviour, topology, + local_public_key, + local_peer_id, supported_protocols, + listened_addrs: SmallVec::new(), external_addresses: SmallVec::new(), } } @@ -142,7 +157,11 @@ where TBehaviour: NetworkBehaviour, /// On success, returns an alternative version of the address. #[inline] pub fn listen_on(me: &mut Self, addr: Multiaddr) -> Result { - me.raw_swarm.listen_on(addr) + let result = me.raw_swarm.listen_on(addr); + if let Ok(ref addr) = result { + me.listened_addrs.push(addr.clone()); + } + result } /// Tries to dial the given address. @@ -173,6 +192,12 @@ where TBehaviour: NetworkBehaviour, RawSwarm::listeners(&me.raw_swarm) } + /// Returns the peer ID of the swarm passed as parameter. + #[inline] + pub fn local_peer_id(me: &Self) -> &PeerId { + &me.local_peer_id + } + /// Returns the topology of the swarm. #[inline] pub fn topology(me: &Self) -> &TTopology { @@ -250,7 +275,10 @@ where TBehaviour: NetworkBehaviour, let mut parameters = PollParameters { topology: &mut self.topology, supported_protocols: &self.supported_protocols, + listened_addrs: &self.listened_addrs, external_addresses: &self.external_addresses, + local_public_key: &self.local_public_key, + local_peer_id: &self.local_peer_id, }; self.behaviour.poll(&mut parameters) }; @@ -326,7 +354,10 @@ pub trait NetworkBehaviour { pub struct PollParameters<'a, TTopology: 'a> { topology: &'a mut TTopology, supported_protocols: &'a [Vec], + listened_addrs: &'a [Multiaddr], external_addresses: &'a [Multiaddr], + local_public_key: &'a PublicKey, + local_peer_id: &'a PeerId, } impl<'a, TTopology> PollParameters<'a, TTopology> { @@ -347,6 +378,12 @@ impl<'a, TTopology> PollParameters<'a, TTopology> { self.supported_protocols.iter().map(AsRef::as_ref) } + /// Returns the list of the addresses we're listening on + #[inline] + pub fn listened_addresses(&self) -> impl ExactSizeIterator { + self.listened_addrs.iter() + } + /// Returns the list of the addresses we're listening on, after accounting for NAT traversal. /// /// This corresponds to the elements produced with `ReportObservedAddr`. @@ -354,6 +391,18 @@ impl<'a, TTopology> PollParameters<'a, TTopology> { pub fn external_addresses(&self) -> impl ExactSizeIterator { self.external_addresses.iter() } + + /// Returns the public key of the local node. + #[inline] + pub fn local_public_key(&self) -> &PublicKey { + self.local_public_key + } + + /// Returns the peer id of the local node. + #[inline] + pub fn local_peer_id(&self) -> &PeerId { + self.local_peer_id + } } /// Action to perform. diff --git a/examples/chat.rs b/examples/chat.rs index 50139396..14ba0359 100644 --- a/examples/chat.rs +++ b/examples/chat.rs @@ -56,10 +56,11 @@ use libp2p::{ fn main() { env_logger::init(); + // Create a random PeerId let local_key = secio::SecioKeyPair::ed25519_generated().unwrap(); - let local_peer_id = local_key.to_peer_id(); - println!("Local peer id: {:?}", local_peer_id); + let local_pub_key = local_key.to_public_key(); + println!("Local peer id: {:?}", local_pub_key.clone().into_peer_id()); // Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol let transport = libp2p::CommonTransport::new() @@ -75,9 +76,9 @@ fn main() { // Create a Swarm to manage peers and events let mut swarm = { - let mut behaviour = libp2p::floodsub::FloodsubBehaviour::new(local_peer_id); + let mut behaviour = libp2p::floodsub::FloodsubBehaviour::new(local_pub_key.clone().into_peer_id()); behaviour.subscribe(floodsub_topic.clone()); - libp2p::Swarm::new(transport, behaviour, libp2p::core::topology::MemoryTopology::empty()) + libp2p::Swarm::new(transport, behaviour, libp2p::core::topology::MemoryTopology::empty(), local_pub_key) }; // Listen on all interfaces and whatever port the OS assigns diff --git a/examples/ipfs-kad.rs b/examples/ipfs-kad.rs index 18a89ca1..c370f007 100644 --- a/examples/ipfs-kad.rs +++ b/examples/ipfs-kad.rs @@ -40,7 +40,7 @@ use libp2p::{ fn main() { // Create a random key for ourselves. let local_key = secio::SecioKeyPair::ed25519_generated().unwrap(); - let local_peer_id = local_key.to_peer_id(); + let local_pub_key = local_key.to_public_key(); // Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol let transport = libp2p::CommonTransport::new() @@ -70,8 +70,8 @@ fn main() { // to insert our local node in the DHT. However here we use `without_init` because this // example is very ephemeral and we don't want to pollute the DHT. In a real world // application, you want to use `new` instead. - let mut behaviour = libp2p::kad::Kademlia::without_init(local_peer_id); - libp2p::core::Swarm::new(transport, behaviour, topology) + let mut behaviour = libp2p::kad::Kademlia::without_init(local_pub_key.clone().into_peer_id()); + libp2p::core::Swarm::new(transport, behaviour, topology, local_pub_key) }; // Order Kademlia to search for a peer.