mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 01:51:23 +00:00
Embed the topology in the NetworkBehaviour (#889)
* Embed the topology in the NetworkBehaviour * Put topologies inside of Floodsub and Kad * Fix core tests * Fix chat example * More work * Some cleanup * Restore external addresses system
This commit is contained in:
@ -21,9 +21,10 @@
|
||||
use crate::protocol::{FloodsubConfig, FloodsubMessage, FloodsubRpc, FloodsubSubscription, FloodsubSubscriptionAction};
|
||||
use crate::topic::{Topic, TopicHash};
|
||||
use cuckoofilter::CuckooFilter;
|
||||
use fnv::FnvHashSet;
|
||||
use futures::prelude::*;
|
||||
use libp2p_core::swarm::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
||||
use libp2p_core::{protocols_handler::ProtocolsHandler, protocols_handler::OneShotHandler, PeerId};
|
||||
use libp2p_core::{protocols_handler::ProtocolsHandler, protocols_handler::OneShotHandler, Multiaddr, PeerId};
|
||||
use rand;
|
||||
use smallvec::SmallVec;
|
||||
use std::{collections::VecDeque, iter, marker::PhantomData};
|
||||
@ -39,6 +40,9 @@ pub struct Floodsub<TSubstream> {
|
||||
/// Peer id of the local node. Used for the source of the messages that we publish.
|
||||
local_peer_id: PeerId,
|
||||
|
||||
/// List of peers to send messages to.
|
||||
target_peers: FnvHashSet<PeerId>,
|
||||
|
||||
/// List of peers the network is connected to, and the topics that they're subscribed to.
|
||||
// TODO: filter out peers that don't support floodsub, so that we avoid hammering them with
|
||||
// opened substreams
|
||||
@ -62,12 +66,43 @@ impl<TSubstream> Floodsub<TSubstream> {
|
||||
Floodsub {
|
||||
events: VecDeque::new(),
|
||||
local_peer_id,
|
||||
target_peers: FnvHashSet::default(),
|
||||
connected_peers: HashMap::new(),
|
||||
subscribed_topics: SmallVec::new(),
|
||||
received: CuckooFilter::new(),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a node to the list of nodes to propagate messages to.
|
||||
#[inline]
|
||||
pub fn add_node_to_partial_view(&mut self, peer_id: PeerId) {
|
||||
// Send our topics to this node if we're already connected to it.
|
||||
if self.connected_peers.contains_key(&peer_id) {
|
||||
for topic in self.subscribed_topics.iter() {
|
||||
self.events.push_back(NetworkBehaviourAction::SendEvent {
|
||||
peer_id: peer_id.clone(),
|
||||
event: FloodsubRpc {
|
||||
messages: Vec::new(),
|
||||
subscriptions: vec![FloodsubSubscription {
|
||||
topic: topic.hash().clone(),
|
||||
action: FloodsubSubscriptionAction::Subscribe,
|
||||
}],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if self.target_peers.insert(peer_id.clone()) {
|
||||
self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id });
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove a node from the list of nodes to propagate messages to.
|
||||
#[inline]
|
||||
pub fn remove_node_from_partial_view(&mut self, peer_id: &PeerId) {
|
||||
self.target_peers.remove(&peer_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream> Floodsub<TSubstream> {
|
||||
@ -171,7 +206,7 @@ impl<TSubstream> Floodsub<TSubstream> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream, TTopology> NetworkBehaviour<TTopology> for Floodsub<TSubstream>
|
||||
impl<TSubstream> NetworkBehaviour for Floodsub<TSubstream>
|
||||
where
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
{
|
||||
@ -182,19 +217,25 @@ where
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn addresses_of_peer(&self, _: &PeerId) -> Vec<Multiaddr> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, id: PeerId, _: ConnectedPoint) {
|
||||
// We need to send our subscriptions to the newly-connected node.
|
||||
for topic in self.subscribed_topics.iter() {
|
||||
self.events.push_back(NetworkBehaviourAction::SendEvent {
|
||||
peer_id: id.clone(),
|
||||
event: FloodsubRpc {
|
||||
messages: Vec::new(),
|
||||
subscriptions: vec![FloodsubSubscription {
|
||||
topic: topic.hash().clone(),
|
||||
action: FloodsubSubscriptionAction::Subscribe,
|
||||
}],
|
||||
},
|
||||
});
|
||||
if self.target_peers.contains(&id) {
|
||||
for topic in self.subscribed_topics.iter() {
|
||||
self.events.push_back(NetworkBehaviourAction::SendEvent {
|
||||
peer_id: id.clone(),
|
||||
event: FloodsubRpc {
|
||||
messages: Vec::new(),
|
||||
subscriptions: vec![FloodsubSubscription {
|
||||
topic: topic.hash().clone(),
|
||||
action: FloodsubSubscriptionAction::Subscribe,
|
||||
}],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.connected_peers.insert(id.clone(), SmallVec::new());
|
||||
@ -203,6 +244,12 @@ where
|
||||
fn inject_disconnected(&mut self, id: &PeerId, _: ConnectedPoint) {
|
||||
let was_in = self.connected_peers.remove(id);
|
||||
debug_assert!(was_in.is_some());
|
||||
|
||||
// We can be disconnected by the remote in case of inactivity for example, so we always
|
||||
// try to reconnect.
|
||||
if self.target_peers.contains(id) {
|
||||
self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id: id.clone() });
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_node_event(
|
||||
@ -290,7 +337,7 @@ where
|
||||
|
||||
fn poll(
|
||||
&mut self,
|
||||
_: &mut PollParameters<TTopology>,
|
||||
_: &mut PollParameters,
|
||||
) -> Async<
|
||||
NetworkBehaviourAction<
|
||||
<Self::ProtocolsHandler as ProtocolsHandler>::InEvent,
|
||||
|
Reference in New Issue
Block a user