diff --git a/core/src/swarm.rs b/core/src/swarm.rs index 46a6e124..f45b9d41 100644 --- a/core/src/swarm.rs +++ b/core/src/swarm.rs @@ -50,7 +50,8 @@ use crate::{ raw_swarm::{RawSwarm, RawSwarmEvent} }, protocols_handler::{NodeHandlerWrapper, ProtocolsHandler}, - topology::Topology + topology::Topology, + topology::DisconnectReason, }; use futures::prelude::*; use smallvec::SmallVec; @@ -268,13 +269,20 @@ where TBehaviour: NetworkBehaviour, self.behaviour.inject_node_event(peer_id, event); }, Async::Ready(RawSwarmEvent::Connected { peer_id, endpoint }) => { + self.topology.set_connected(&peer_id, &endpoint); self.behaviour.inject_connected(peer_id, endpoint); }, - Async::Ready(RawSwarmEvent::NodeClosed { peer_id, endpoint }) | + Async::Ready(RawSwarmEvent::NodeClosed { peer_id, endpoint }) => { + self.topology.set_disconnected(&peer_id, &endpoint, DisconnectReason::Graceful); + self.behaviour.inject_disconnected(&peer_id, endpoint); + }, Async::Ready(RawSwarmEvent::NodeError { peer_id, endpoint, .. }) => { + self.topology.set_disconnected(&peer_id, &endpoint, DisconnectReason::Error); self.behaviour.inject_disconnected(&peer_id, endpoint); }, Async::Ready(RawSwarmEvent::Replaced { peer_id, closed_endpoint, endpoint }) => { + self.topology.set_disconnected(&peer_id, &closed_endpoint, DisconnectReason::Replaced); + self.topology.set_connected(&peer_id, &endpoint); self.behaviour.inject_disconnected(&peer_id, closed_endpoint); self.behaviour.inject_connected(peer_id, endpoint); }, @@ -284,8 +292,12 @@ where TBehaviour: NetworkBehaviour, }, Async::Ready(RawSwarmEvent::ListenerClosed { .. }) => {}, Async::Ready(RawSwarmEvent::IncomingConnectionError { .. }) => {}, - Async::Ready(RawSwarmEvent::DialError { .. }) => {}, - Async::Ready(RawSwarmEvent::UnknownPeerDialError { .. }) => {}, + Async::Ready(RawSwarmEvent::DialError { multiaddr, .. }) => { + self.topology.set_unreachable(&multiaddr); + }, + Async::Ready(RawSwarmEvent::UnknownPeerDialError { multiaddr, .. }) => { + self.topology.set_unreachable(&multiaddr); + }, } let behaviour_poll = { diff --git a/core/src/topology/mod.rs b/core/src/topology/mod.rs index a7bb2afe..d88bb0fb 100644 --- a/core/src/topology/mod.rs +++ b/core/src/topology/mod.rs @@ -32,7 +32,7 @@ //! prototyping, it shouldn't be used in an actual high-performance production software. use std::collections::HashMap; -use crate::{Multiaddr, PeerId, PublicKey}; +use crate::{swarm::ConnectedPoint, Multiaddr, PeerId, PublicKey}; /// Storage for the network topology. /// @@ -44,6 +44,12 @@ pub trait Topology { /// > **Note**: Keep in mind that `peer` can be the local node. fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec; + /// Returns the `PeerId` of the local node. + fn local_peer_id(&self) -> &PeerId; + + /// Returns the public key of the local node. + fn local_public_key(&self) -> &PublicKey; + /// Adds an address that other nodes can use to connect to our local node. /// /// > **Note**: Should later be returned when calling `addresses_of_peer()` with the `PeerId` @@ -51,11 +57,24 @@ pub trait Topology { fn add_local_external_addrs(&mut self, addrs: TIter) where TIter: Iterator; - /// Returns the `PeerId` of the local node. - fn local_peer_id(&self) -> &PeerId; + /// Indicates to the topology that we have successfully connected to the given address with the + /// given `PeerId`. + fn set_connected(&mut self, _peer_id: &PeerId, _addr: &ConnectedPoint) {} - /// Returns the public key of the local node. - fn local_public_key(&self) -> &PublicKey; + /// Indicates to the topology that we have been disconnected from the given address with the + /// given `PeerId`. + fn set_disconnected(&mut self, _peer_id: &PeerId, _addr: &ConnectedPoint, _reason: DisconnectReason) {} + + /// Indicates to the topology that we have failed to reach the given address. + fn set_unreachable(&mut self, _addr: &Multiaddr) {} +} + +/// Reason why the peer has been disconnected. +#[derive(Debug, Copy, Clone)] +pub enum DisconnectReason { + Error, + Graceful, + Replaced, } /// Topology of the network stored in memory.