refactor(swarm)!: deprecate PollParameters where possible (#3153)

This patch deprecates 3 out of 4 functions on `PollParameters`:

- `local_peer_id`
- `listened_addresses`
- `external_addresses`

The addresses can be obtained by inspecting the `FromSwarm` event. To make this easier, we introduce two utility structs in `libp2p-swarm`:

- `ExternalAddresses`
- `ListenAddresses`

A node's `PeerId` is always known to the caller, thus we can require them to pass it in.

Related: #3124.
This commit is contained in:
Thomas Eizinger 2022-12-14 11:50:08 +11:00 committed by GitHub
parent 5fe0dc44bd
commit be3ec6c62b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 282 additions and 112 deletions

View File

@ -91,7 +91,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
} }
// Create a Swarm to manage peers and events. // Create a Swarm to manage peers and events.
let mdns_behaviour = mdns::Behaviour::new(Default::default())?; let mdns_behaviour = mdns::Behaviour::new(Default::default(), peer_id)?;
let behaviour = MyBehaviour { let behaviour = MyBehaviour {
floodsub: Floodsub::new(peer_id), floodsub: Floodsub::new(peer_id),
mdns: mdns_behaviour, mdns: mdns_behaviour,

View File

@ -107,7 +107,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// Create a Swarm to manage peers and events // Create a Swarm to manage peers and events
let mut swarm = { let mut swarm = {
let mdns = mdns::async_io::Behaviour::new(mdns::Config::default())?; let mdns = mdns::async_io::Behaviour::new(mdns::Config::default(), local_peer_id)?;
let mut behaviour = MyBehaviour { let mut behaviour = MyBehaviour {
floodsub: Floodsub::new(local_peer_id), floodsub: Floodsub::new(local_peer_id),
mdns, mdns,

View File

@ -97,7 +97,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// Create a Kademlia behaviour. // Create a Kademlia behaviour.
let store = MemoryStore::new(local_peer_id); let store = MemoryStore::new(local_peer_id);
let kademlia = Kademlia::new(local_peer_id, store); let kademlia = Kademlia::new(local_peer_id, store);
let mdns = mdns::async_io::Behaviour::new(mdns::Config::default())?; let mdns = mdns::async_io::Behaviour::new(mdns::Config::default(), local_peer_id)?;
let behaviour = MyBehaviour { kademlia, mdns }; let behaviour = MyBehaviour { kademlia, mdns };
Swarm::with_async_std_executor(transport, behaviour, local_peer_id) Swarm::with_async_std_executor(transport, behaviour, local_peer_id)
}; };

View File

@ -104,7 +104,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// Create a Swarm to manage peers and events // Create a Swarm to manage peers and events
let mut swarm = { let mut swarm = {
let mdns = mdns::async_io::Behaviour::new(mdns::Config::default())?; let mdns = mdns::async_io::Behaviour::new(mdns::Config::default(), local_peer_id)?;
let behaviour = MyBehaviour { gossipsub, mdns }; let behaviour = MyBehaviour { gossipsub, mdns };
Swarm::with_async_std_executor(transport, behaviour, local_peer_id) Swarm::with_async_std_executor(transport, behaviour, local_peer_id)
}; };

View File

@ -39,7 +39,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let transport = libp2p::development_transport(id_keys).await?; let transport = libp2p::development_transport(id_keys).await?;
// Create an MDNS network behaviour. // Create an MDNS network behaviour.
let behaviour = mdns::async_io::Behaviour::new(mdns::Config::default())?; let behaviour = mdns::async_io::Behaviour::new(mdns::Config::default(), peer_id)?;
// Create a Swarm that establishes connections through the given transport. // Create a Swarm that establishes connections through the given transport.
// Note that the MDNS behaviour itself will not actually inititiate any connections, // Note that the MDNS behaviour itself will not actually inititiate any connections,

View File

@ -1,9 +1,13 @@
# 0.10.0 [unreleased] # 0.10.0 [unreleased]
- Require the node's local `PeerId` to be passed into the constructor of `libp2p_autonat::Behaviour`. See [PR 3153].
- Update to `libp2p-request-response` `v0.24.0`. - Update to `libp2p-request-response` `v0.24.0`.
- Update to `libp2p-swarm` `v0.42.0`. - Update to `libp2p-swarm` `v0.42.0`.
[PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153
# 0.9.0 # 0.9.0
- Update to `libp2p-core` `v0.38.0`. - Update to `libp2p-core` `v0.38.0`.

View File

@ -39,8 +39,8 @@ use libp2p_swarm::{
AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr,
ExpiredListenAddr, FromSwarm, ExpiredListenAddr, FromSwarm,
}, },
ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, ConnectionHandler, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour,
PollParameters, NetworkBehaviourAction, PollParameters,
}; };
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},
@ -212,6 +212,9 @@ pub struct Behaviour {
pending_out_events: VecDeque<<Self as NetworkBehaviour>::OutEvent>, pending_out_events: VecDeque<<Self as NetworkBehaviour>::OutEvent>,
probe_id: ProbeId, probe_id: ProbeId,
listen_addresses: ListenAddresses,
external_addresses: ExternalAddresses,
} }
impl Behaviour { impl Behaviour {
@ -236,6 +239,8 @@ impl Behaviour {
last_probe: None, last_probe: None,
pending_out_events: VecDeque::new(), pending_out_events: VecDeque::new(),
probe_id: ProbeId(0), probe_id: ProbeId(0),
listen_addresses: Default::default(),
external_addresses: Default::default(),
} }
} }
@ -288,6 +293,8 @@ impl Behaviour {
ongoing_outbound: &mut self.ongoing_outbound, ongoing_outbound: &mut self.ongoing_outbound,
last_probe: &mut self.last_probe, last_probe: &mut self.last_probe,
schedule_probe: &mut self.schedule_probe, schedule_probe: &mut self.schedule_probe,
listen_addresses: &self.listen_addresses,
external_addresses: &self.external_addresses,
} }
} }
@ -457,7 +464,7 @@ impl NetworkBehaviour for Behaviour {
Poll::Pending => is_inner_pending = true, Poll::Pending => is_inner_pending = true,
} }
match self.as_client().poll_auto_probe(params, cx) { match self.as_client().poll_auto_probe(cx) {
Poll::Ready(event) => self Poll::Ready(event) => self
.pending_out_events .pending_out_events
.push_back(Event::OutboundProbe(event)), .push_back(Event::OutboundProbe(event)),
@ -476,6 +483,9 @@ impl NetworkBehaviour for Behaviour {
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.listen_addresses.on_swarm_event(&event);
self.external_addresses.on_swarn_event(&event);
match event { match event {
FromSwarm::ConnectionEstablished(connection_established) => { FromSwarm::ConnectionEstablished(connection_established) => {
self.inner self.inner

View File

@ -29,7 +29,9 @@ use futures_timer::Delay;
use instant::Instant; use instant::Instant;
use libp2p_core::{connection::ConnectionId, Multiaddr, PeerId}; use libp2p_core::{connection::ConnectionId, Multiaddr, PeerId};
use libp2p_request_response::{self as request_response, OutboundFailure, RequestId}; use libp2p_request_response::{self as request_response, OutboundFailure, RequestId};
use libp2p_swarm::{AddressScore, NetworkBehaviourAction, PollParameters}; use libp2p_swarm::{
AddressScore, ExternalAddresses, ListenAddresses, NetworkBehaviourAction, PollParameters,
};
use rand::{seq::SliceRandom, thread_rng}; use rand::{seq::SliceRandom, thread_rng};
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},
@ -97,6 +99,9 @@ pub struct AsClient<'a> {
pub last_probe: &'a mut Option<Instant>, pub last_probe: &'a mut Option<Instant>,
pub schedule_probe: &'a mut Delay, pub schedule_probe: &'a mut Delay,
pub listen_addresses: &'a ListenAddresses,
pub external_addresses: &'a ExternalAddresses,
} }
impl<'a> HandleInnerEvent for AsClient<'a> { impl<'a> HandleInnerEvent for AsClient<'a> {
@ -146,6 +151,8 @@ impl<'a> HandleInnerEvent for AsClient<'a> {
if let Ok(address) = response.result { if let Ok(address) = response.result {
// Update observed address score if it is finite. // Update observed address score if it is finite.
#[allow(deprecated)]
// TODO: Fix once we report `AddressScore` through `FromSwarm` event.
let score = params let score = params
.external_addresses() .external_addresses()
.find_map(|r| (r.addr == address).then_some(r.score)) .find_map(|r| (r.addr == address).then_some(r.score))
@ -188,17 +195,17 @@ impl<'a> HandleInnerEvent for AsClient<'a> {
} }
impl<'a> AsClient<'a> { impl<'a> AsClient<'a> {
pub fn poll_auto_probe( pub fn poll_auto_probe(&mut self, cx: &mut Context<'_>) -> Poll<OutboundProbeEvent> {
&mut self,
params: &mut impl PollParameters,
cx: &mut Context<'_>,
) -> Poll<OutboundProbeEvent> {
match self.schedule_probe.poll_unpin(cx) { match self.schedule_probe.poll_unpin(cx) {
Poll::Ready(()) => { Poll::Ready(()) => {
self.schedule_probe.reset(self.config.retry_interval); self.schedule_probe.reset(self.config.retry_interval);
let mut addresses: Vec<_> = params.external_addresses().map(|r| r.addr).collect(); let addresses = self
addresses.extend(params.listened_addresses()); .external_addresses
.iter()
.chain(self.listen_addresses.iter())
.cloned()
.collect();
let probe_id = self.probe_id.next(); let probe_id = self.probe_id.next();
let event = match self.do_probe(probe_id, addresses) { let event = match self.do_probe(probe_id, addresses) {

View File

@ -5,7 +5,10 @@
- Declare `InboundUpgradeError` and `OutboundUpgradeError` as type aliases instead of renames. - Declare `InboundUpgradeError` and `OutboundUpgradeError` as type aliases instead of renames.
This is a workaround for a missing feature in `cargo semver-checks`. See [PR 3213]. This is a workaround for a missing feature in `cargo semver-checks`. See [PR 3213].
- Require the node's local `PeerId` to be passed into the constructor of `libp2p_dcutr::Behaviour`. See [PR 3153].
[PR 3213]: https://github.com/libp2p/rust-libp2p/pull/3213 [PR 3213]: https://github.com/libp2p/rust-libp2p/pull/3213
[PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153
# 0.8.0 # 0.8.0

View File

@ -157,7 +157,7 @@ fn main() -> Result<(), Box<dyn Error>> {
"/TODO/0.0.1".to_string(), "/TODO/0.0.1".to_string(),
local_key.public(), local_key.public(),
)), )),
dcutr: dcutr::behaviour::Behaviour::new(), dcutr: dcutr::behaviour::Behaviour::new(local_peer_id),
}; };
let mut swarm = match ThreadPool::new() { let mut swarm = match ThreadPool::new() {

View File

@ -29,8 +29,8 @@ use libp2p_core::{Multiaddr, PeerId};
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm};
use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::dial_opts::{self, DialOpts};
use libp2p_swarm::{ use libp2p_swarm::{
ConnectionHandler, ConnectionHandlerUpgrErr, IntoConnectionHandler, NetworkBehaviour, ConnectionHandler, ConnectionHandlerUpgrErr, ExternalAddresses, IntoConnectionHandler,
NetworkBehaviourAction, NotifyHandler, PollParameters, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
}; };
use std::collections::{HashMap, HashSet, VecDeque}; use std::collections::{HashMap, HashSet, VecDeque};
use std::task::{Context, Poll}; use std::task::{Context, Poll};
@ -66,20 +66,25 @@ pub enum UpgradeError {
Handler(ConnectionHandlerUpgrErr<void::Void>), Handler(ConnectionHandlerUpgrErr<void::Void>),
} }
#[derive(Default)]
pub struct Behaviour { pub struct Behaviour {
/// Queue of actions to return when polled. /// Queue of actions to return when polled.
queued_actions: VecDeque<ActionBuilder>, queued_actions: VecDeque<ActionBuilder>,
/// All direct (non-relayed) connections. /// All direct (non-relayed) connections.
direct_connections: HashMap<PeerId, HashSet<ConnectionId>>, direct_connections: HashMap<PeerId, HashSet<ConnectionId>>,
external_addresses: ExternalAddresses,
local_peer_id: PeerId,
} }
impl Behaviour { impl Behaviour {
pub fn new() -> Self { pub fn new(local_peer_id: PeerId) -> Self {
Behaviour { Behaviour {
queued_actions: Default::default(), queued_actions: Default::default(),
direct_connections: Default::default(), direct_connections: Default::default(),
external_addresses: Default::default(),
local_peer_id,
} }
} }
@ -308,16 +313,18 @@ impl NetworkBehaviour for Behaviour {
fn poll( fn poll(
&mut self, &mut self,
_cx: &mut Context<'_>, _cx: &mut Context<'_>,
poll_parameters: &mut impl PollParameters, _: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> { ) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
if let Some(action) = self.queued_actions.pop_front() { if let Some(action) = self.queued_actions.pop_front() {
return Poll::Ready(action.build(poll_parameters)); return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses));
} }
Poll::Pending Poll::Pending
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.external_addresses.on_swarn_event(&event);
match event { match event {
FromSwarm::ConnectionEstablished(connection_established) => { FromSwarm::ConnectionEstablished(connection_established) => {
self.on_connection_established(connection_established) self.on_connection_established(connection_established)
@ -364,16 +371,15 @@ impl From<NetworkBehaviourAction<Event, handler::Prototype>> for ActionBuilder {
impl ActionBuilder { impl ActionBuilder {
fn build( fn build(
self, self,
poll_parameters: &mut impl PollParameters, local_peer_id: PeerId,
external_addresses: &ExternalAddresses,
) -> NetworkBehaviourAction<Event, handler::Prototype> { ) -> NetworkBehaviourAction<Event, handler::Prototype> {
let obs_addrs = || { let obs_addrs = || {
poll_parameters external_addresses
.external_addresses() .iter()
.filter(|a| !a.addr.iter().any(|p| p == Protocol::P2pCircuit)) .cloned()
.map(|a| { .filter(|a| !a.iter().any(|p| p == Protocol::P2pCircuit))
a.addr .map(|a| a.with(Protocol::P2p(local_peer_id.into())))
.with(Protocol::P2p((*poll_parameters.local_peer_id()).into()))
})
.collect() .collect()
}; };

View File

@ -126,7 +126,7 @@ fn build_client() -> Swarm<Client> {
transport, transport,
Client { Client {
relay: behaviour, relay: behaviour,
dcutr: dcutr::behaviour::Behaviour::new(), dcutr: dcutr::behaviour::Behaviour::new(local_peer_id),
}, },
local_peer_id, local_peer_id,
) )

View File

@ -26,7 +26,8 @@ use libp2p_core::{
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm};
use libp2p_swarm::{ use libp2p_swarm::{
dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError,
IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour,
NetworkBehaviourAction, NotifyHandler, PollParameters,
}; };
use lru::LruCache; use lru::LruCache;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
@ -56,6 +57,9 @@ pub struct Behaviour {
events: VecDeque<NetworkBehaviourAction<Event, Proto>>, events: VecDeque<NetworkBehaviourAction<Event, Proto>>,
/// The addresses of all peers that we have discovered. /// The addresses of all peers that we have discovered.
discovered_peers: PeerCache, discovered_peers: PeerCache,
listen_addresses: ListenAddresses,
external_addresses: ExternalAddresses,
} }
/// A `Behaviour` request to be fulfilled, either `Handler` requests for `Behaviour` info /// A `Behaviour` request to be fulfilled, either `Handler` requests for `Behaviour` info
@ -177,6 +181,8 @@ impl Behaviour {
requests: Vec::new(), requests: Vec::new(),
events: VecDeque::new(), events: VecDeque::new(),
discovered_peers, discovered_peers,
listen_addresses: Default::default(),
external_addresses: Default::default(),
} }
} }
@ -318,7 +324,12 @@ impl NetworkBehaviour for Behaviour {
peer_id, peer_id,
handler: NotifyHandler::Any, handler: NotifyHandler::Any,
event: InEvent { event: InEvent {
listen_addrs: listen_addrs(params), listen_addrs: self
.listen_addresses
.iter()
.chain(self.external_addresses.iter())
.cloned()
.collect(),
supported_protocols: supported_protocols(params), supported_protocols: supported_protocols(params),
protocol: Protocol::Push, protocol: Protocol::Push,
}, },
@ -330,7 +341,12 @@ impl NetworkBehaviour for Behaviour {
peer_id, peer_id,
handler: NotifyHandler::One(connection_id), handler: NotifyHandler::One(connection_id),
event: InEvent { event: InEvent {
listen_addrs: listen_addrs(params), listen_addrs: self
.listen_addresses
.iter()
.chain(self.external_addresses.iter())
.cloned()
.collect(),
supported_protocols: supported_protocols(params), supported_protocols: supported_protocols(params),
protocol: Protocol::Identify(connection_id), protocol: Protocol::Identify(connection_id),
}, },
@ -344,6 +360,9 @@ impl NetworkBehaviour for Behaviour {
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.listen_addresses.on_swarm_event(&event);
self.external_addresses.on_swarn_event(&event);
match event { match event {
FromSwarm::ConnectionEstablished(connection_established) => { FromSwarm::ConnectionEstablished(connection_established) => {
self.on_connection_established(connection_established) self.on_connection_established(connection_established)
@ -453,12 +472,6 @@ fn supported_protocols(params: &impl PollParameters) -> Vec<String> {
.collect() .collect()
} }
fn listen_addrs(params: &impl PollParameters) -> Vec<Multiaddr> {
let mut listen_addrs: Vec<_> = params.external_addresses().map(|r| r.addr).collect();
listen_addrs.extend(params.listened_addresses());
listen_addrs
}
/// If there is a given peer_id in the multiaddr, make sure it is the same as /// If there is a given peer_id in the multiaddr, make sure it is the same as
/// the given peer_id. If there is no peer_id for the peer in the mutiaddr, this returns true. /// the given peer_id. If there is no peer_id for the peer in the mutiaddr, this returns true.
fn multiaddr_matches_peer_id(addr: &Multiaddr, peer_id: &PeerId) -> bool { fn multiaddr_matches_peer_id(addr: &Multiaddr, peer_id: &PeerId) -> bool {

View File

@ -41,12 +41,12 @@ use fnv::{FnvHashMap, FnvHashSet};
use instant::Instant; use instant::Instant;
use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId};
use libp2p_swarm::behaviour::{ use libp2p_swarm::behaviour::{
AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr, AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm,
FromSwarm, NewExternalAddr, NewListenAddr,
}; };
use libp2p_swarm::{ use libp2p_swarm::{
dial_opts::{self, DialOpts}, dial_opts::{self, DialOpts},
DialError, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction,
NotifyHandler, PollParameters,
}; };
use log::{debug, info, warn}; use log::{debug, info, warn};
use smallvec::SmallVec; use smallvec::SmallVec;
@ -103,12 +103,15 @@ pub struct Kademlia<TStore> {
/// Queued events to return when the behaviour is being polled. /// Queued events to return when the behaviour is being polled.
queued_events: VecDeque<NetworkBehaviourAction<KademliaEvent, KademliaHandlerProto<QueryId>>>, queued_events: VecDeque<NetworkBehaviourAction<KademliaEvent, KademliaHandlerProto<QueryId>>>,
/// The currently known addresses of the local node. listen_addresses: ListenAddresses,
local_addrs: HashSet<Multiaddr>,
external_addresses: ExternalAddresses,
/// See [`KademliaConfig::caching`]. /// See [`KademliaConfig::caching`].
caching: KademliaCaching, caching: KademliaCaching,
local_peer_id: PeerId,
/// The record storage. /// The record storage.
store: TStore, store: TStore,
} }
@ -439,6 +442,7 @@ where
protocol_config: config.protocol_config, protocol_config: config.protocol_config,
record_filtering: config.record_filtering, record_filtering: config.record_filtering,
queued_events: VecDeque::with_capacity(config.query_config.replication_factor.get()), queued_events: VecDeque::with_capacity(config.query_config.replication_factor.get()),
listen_addresses: Default::default(),
queries: QueryPool::new(config.query_config), queries: QueryPool::new(config.query_config),
connected_peers: Default::default(), connected_peers: Default::default(),
add_provider_job, add_provider_job,
@ -446,7 +450,8 @@ where
record_ttl: config.record_ttl, record_ttl: config.record_ttl,
provider_record_ttl: config.provider_record_ttl, provider_record_ttl: config.provider_record_ttl,
connection_idle_timeout: config.connection_idle_timeout, connection_idle_timeout: config.connection_idle_timeout,
local_addrs: HashSet::new(), external_addresses: Default::default(),
local_peer_id: id,
} }
} }
@ -1034,7 +1039,9 @@ where
fn provider_peers(&mut self, key: &record::Key, source: &PeerId) -> Vec<KadPeer> { fn provider_peers(&mut self, key: &record::Key, source: &PeerId) -> Vec<KadPeer> {
let kbuckets = &mut self.kbuckets; let kbuckets = &mut self.kbuckets;
let connected = &mut self.connected_peers; let connected = &mut self.connected_peers;
let local_addrs = &self.local_addrs; let listen_addresses = &self.listen_addresses;
let external_addresses = &self.external_addresses;
self.store self.store
.providers(key) .providers(key)
.into_iter() .into_iter()
@ -1055,7 +1062,13 @@ where
// done before provider records were stored along with // done before provider records were stored along with
// their addresses. // their addresses.
if &node_id == kbuckets.local_key().preimage() { if &node_id == kbuckets.local_key().preimage() {
Some(local_addrs.iter().cloned().collect::<Vec<_>>()) Some(
listen_addresses
.iter()
.chain(external_addresses.iter())
.cloned()
.collect::<Vec<_>>(),
)
} else { } else {
let key = kbucket::Key::from(node_id); let key = kbucket::Key::from(node_id);
kbuckets kbuckets
@ -1226,11 +1239,7 @@ where
} }
/// Handles a finished (i.e. successful) query. /// Handles a finished (i.e. successful) query.
fn query_finished( fn query_finished(&mut self, q: Query<QueryInner>) -> Option<KademliaEvent> {
&mut self,
q: Query<QueryInner>,
params: &mut impl PollParameters,
) -> Option<KademliaEvent> {
let query_id = q.id(); let query_id = q.id();
log::trace!("Query {:?} finished.", query_id); log::trace!("Query {:?} finished.", query_id);
let result = q.into_result(); let result = q.into_result();
@ -1340,8 +1349,8 @@ where
key, key,
phase: AddProviderPhase::GetClosestPeers, phase: AddProviderPhase::GetClosestPeers,
} => { } => {
let provider_id = *params.local_peer_id(); let provider_id = self.local_peer_id;
let external_addresses = params.external_addresses().map(|r| r.addr).collect(); let external_addresses = self.external_addresses.iter().cloned().collect();
let inner = QueryInner::new(QueryInfo::AddProvider { let inner = QueryInner::new(QueryInfo::AddProvider {
context, context,
key, key,
@ -2285,7 +2294,7 @@ where
fn poll( fn poll(
&mut self, &mut self,
cx: &mut Context<'_>, cx: &mut Context<'_>,
parameters: &mut impl PollParameters, _: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> { ) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
let now = Instant::now(); let now = Instant::now();
@ -2352,7 +2361,7 @@ where
loop { loop {
match self.queries.poll(now) { match self.queries.poll(now) {
QueryPoolState::Finished(q) => { QueryPoolState::Finished(q) => {
if let Some(event) = self.query_finished(q, parameters) { if let Some(event) = self.query_finished(q) {
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
} }
} }
@ -2406,6 +2415,9 @@ where
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.listen_addresses.on_swarm_event(&event);
self.external_addresses.on_swarn_event(&event);
match event { match event {
FromSwarm::ConnectionEstablished(connection_established) => { FromSwarm::ConnectionEstablished(connection_established) => {
self.on_connection_established(connection_established) self.on_connection_established(connection_established)
@ -2415,18 +2427,10 @@ where
} }
FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure), FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure),
FromSwarm::AddressChange(address_change) => self.on_address_change(address_change), FromSwarm::AddressChange(address_change) => self.on_address_change(address_change),
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { addr, .. }) => { FromSwarm::ExpiredListenAddr(_)
self.local_addrs.remove(addr); | FromSwarm::NewExternalAddr(_)
} | FromSwarm::NewListenAddr(_)
FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => { | FromSwarm::ListenFailure(_)
if self.local_addrs.len() < MAX_LOCAL_EXTERNAL_ADDRS {
self.local_addrs.insert(addr.clone());
}
}
FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => {
self.local_addrs.insert(addr.clone());
}
FromSwarm::ListenFailure(_)
| FromSwarm::NewListener(_) | FromSwarm::NewListener(_)
| FromSwarm::ListenerClosed(_) | FromSwarm::ListenerClosed(_)
| FromSwarm::ListenerError(_) | FromSwarm::ListenerError(_)
@ -3179,8 +3183,3 @@ pub enum RoutingUpdate {
/// peer ID). /// peer ID).
Failed, Failed,
} }
/// The maximum number of local external addresses. When reached any
/// further externally reported addresses are ignored. The behaviour always
/// tracks all its listen addresses.
const MAX_LOCAL_EXTERNAL_ADDRS: usize = 20;

View File

@ -1,7 +1,11 @@
# 0.43.0 [unreleased] # 0.43.0 [unreleased]
- Require the node's local `PeerId` to be passed into the constructor of `libp2p_mdns::Behaviour`. See [PR 3153].
- Update to `libp2p-swarm` `v0.42.0`. - Update to `libp2p-swarm` `v0.42.0`.
[PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153
# 0.42.0 # 0.42.0
- Update to `libp2p-core` `v0.38.0`. - Update to `libp2p-core` `v0.38.0`.

View File

@ -30,7 +30,8 @@ use if_watch::IfEvent;
use libp2p_core::{Multiaddr, PeerId}; use libp2p_core::{Multiaddr, PeerId};
use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm};
use libp2p_swarm::{ use libp2p_swarm::{
dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, dummy, ConnectionHandler, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction,
PollParameters,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::hash_map::{Entry, HashMap}; use std::collections::hash_map::{Entry, HashMap};
@ -121,6 +122,10 @@ where
/// ///
/// `None` if `discovered_nodes` is empty. /// `None` if `discovered_nodes` is empty.
closest_expiration: Option<P::Timer>, closest_expiration: Option<P::Timer>,
listen_addresses: ListenAddresses,
local_peer_id: PeerId,
} }
impl<P> Behaviour<P> impl<P> Behaviour<P>
@ -128,13 +133,15 @@ where
P: Provider, P: Provider,
{ {
/// Builds a new `Mdns` behaviour. /// Builds a new `Mdns` behaviour.
pub fn new(config: Config) -> io::Result<Self> { pub fn new(config: Config, local_peer_id: PeerId) -> io::Result<Self> {
Ok(Self { Ok(Self {
config, config,
if_watch: P::new_watcher()?, if_watch: P::new_watcher()?,
iface_states: Default::default(), iface_states: Default::default(),
discovered_nodes: Default::default(), discovered_nodes: Default::default(),
closest_expiration: Default::default(), closest_expiration: Default::default(),
listen_addresses: Default::default(),
local_peer_id,
}) })
} }
@ -189,6 +196,8 @@ where
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.listen_addresses.on_swarm_event(&event);
match event { match event {
FromSwarm::ConnectionClosed(ConnectionClosed { FromSwarm::ConnectionClosed(ConnectionClosed {
peer_id, peer_id,
@ -221,7 +230,7 @@ where
fn poll( fn poll(
&mut self, &mut self,
cx: &mut Context<'_>, cx: &mut Context<'_>,
params: &mut impl PollParameters, _: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, dummy::ConnectionHandler>> { ) -> Poll<NetworkBehaviourAction<Self::OutEvent, dummy::ConnectionHandler>> {
// Poll ifwatch. // Poll ifwatch.
while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) { while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) {
@ -237,7 +246,7 @@ where
continue; continue;
} }
if let Entry::Vacant(e) = self.iface_states.entry(addr) { if let Entry::Vacant(e) = self.iface_states.entry(addr) {
match InterfaceState::new(addr, self.config.clone()) { match InterfaceState::new(addr, self.config.clone(), self.local_peer_id) {
Ok(iface_state) => { Ok(iface_state) => {
e.insert(iface_state); e.insert(iface_state);
} }
@ -257,7 +266,9 @@ where
// Emit discovered event. // Emit discovered event.
let mut discovered = SmallVec::<[(PeerId, Multiaddr); 4]>::new(); let mut discovered = SmallVec::<[(PeerId, Multiaddr); 4]>::new();
for iface_state in self.iface_states.values_mut() { for iface_state in self.iface_states.values_mut() {
while let Poll::Ready((peer, addr, expiration)) = iface_state.poll(cx, params) { while let Poll::Ready((peer, addr, expiration)) =
iface_state.poll(cx, &self.listen_addresses)
{
if let Some((_, _, cur_expires)) = self if let Some((_, _, cur_expires)) = self
.discovered_nodes .discovered_nodes
.iter_mut() .iter_mut()

View File

@ -26,7 +26,7 @@ use self::query::MdnsPacket;
use crate::behaviour::{socket::AsyncSocket, timer::Builder}; use crate::behaviour::{socket::AsyncSocket, timer::Builder};
use crate::Config; use crate::Config;
use libp2p_core::{Multiaddr, PeerId}; use libp2p_core::{Multiaddr, PeerId};
use libp2p_swarm::PollParameters; use libp2p_swarm::ListenAddresses;
use socket2::{Domain, Socket, Type}; use socket2::{Domain, Socket, Type};
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
@ -66,6 +66,8 @@ pub struct InterfaceState<U, T> {
discovered: VecDeque<(PeerId, Multiaddr, Instant)>, discovered: VecDeque<(PeerId, Multiaddr, Instant)>,
/// TTL /// TTL
ttl: Duration, ttl: Duration,
local_peer_id: PeerId,
} }
impl<U, T> InterfaceState<U, T> impl<U, T> InterfaceState<U, T>
@ -74,7 +76,7 @@ where
T: Builder + futures::Stream, T: Builder + futures::Stream,
{ {
/// Builds a new [`InterfaceState`]. /// Builds a new [`InterfaceState`].
pub fn new(addr: IpAddr, config: Config) -> io::Result<Self> { pub fn new(addr: IpAddr, config: Config, local_peer_id: PeerId) -> io::Result<Self> {
log::info!("creating instance on iface {}", addr); log::info!("creating instance on iface {}", addr);
let recv_socket = match addr { let recv_socket = match addr {
IpAddr::V4(addr) => { IpAddr::V4(addr) => {
@ -134,6 +136,7 @@ where
timeout: T::interval_at(Instant::now(), query_interval), timeout: T::interval_at(Instant::now(), query_interval),
multicast_addr, multicast_addr,
ttl: config.ttl, ttl: config.ttl,
local_peer_id,
}) })
} }
@ -148,7 +151,7 @@ where
pub fn poll( pub fn poll(
&mut self, &mut self,
cx: &mut Context, cx: &mut Context,
params: &impl PollParameters, listen_addresses: &ListenAddresses,
) -> Poll<(PeerId, Multiaddr, Instant)> { ) -> Poll<(PeerId, Multiaddr, Instant)> {
loop { loop {
// 1st priority: Low latency: Create packet ASAP after timeout. // 1st priority: Low latency: Create packet ASAP after timeout.
@ -198,8 +201,8 @@ where
self.send_buffer.extend(build_query_response( self.send_buffer.extend(build_query_response(
query.query_id(), query.query_id(),
*params.local_peer_id(), self.local_peer_id,
params.listened_addresses(), listen_addresses.iter(),
self.ttl, self.ttl,
)); ));
continue; continue;
@ -211,9 +214,8 @@ where
self.addr self.addr
); );
self.discovered.extend( self.discovered
response.extract_discovered(Instant::now(), *params.local_peer_id()), .extend(response.extract_discovered(Instant::now(), self.local_peer_id));
);
continue; continue;
} }
Poll::Ready(Ok(Ok(Some(MdnsPacket::ServiceDiscovery(disc))))) => { Poll::Ready(Ok(Ok(Some(MdnsPacket::ServiceDiscovery(disc))))) => {

View File

@ -103,10 +103,10 @@ pub fn build_query() -> MdnsPacket {
/// Builds the response to an address discovery DNS query. /// Builds the response to an address discovery DNS query.
/// ///
/// If there are more than 2^16-1 addresses, ignores the rest. /// If there are more than 2^16-1 addresses, ignores the rest.
pub fn build_query_response( pub fn build_query_response<'a>(
id: u16, id: u16,
peer_id: PeerId, peer_id: PeerId,
addresses: impl ExactSizeIterator<Item = Multiaddr>, addresses: impl ExactSizeIterator<Item = &'a Multiaddr>,
ttl: Duration, ttl: Duration,
) -> Vec<MdnsPacket> { ) -> Vec<MdnsPacket> {
// Convert the TTL into seconds. // Convert the TTL into seconds.
@ -413,7 +413,7 @@ mod tests {
let packets = build_query_response( let packets = build_query_response(
0xf8f8, 0xf8f8,
my_peer_id, my_peer_id,
vec![addr1, addr2].into_iter(), vec![&addr1, &addr2].into_iter(),
Duration::from_secs(60), Duration::from_secs(60),
); );
for packet in packets { for packet in packets {

View File

@ -335,7 +335,7 @@ mod tests {
let packets = build_query_response( let packets = build_query_response(
0xf8f8, 0xf8f8,
peer_id, peer_id,
vec![addr1, addr2].into_iter(), vec![&addr1, &addr2].into_iter(),
Duration::from_secs(60), Duration::from_secs(60),
); );

View File

@ -63,7 +63,7 @@ async fn create_swarm(config: Config) -> Result<Swarm<Behaviour>, Box<dyn Error>
.authenticate(libp2p_noise::NoiseAuthenticated::xx(&id_keys).unwrap()) .authenticate(libp2p_noise::NoiseAuthenticated::xx(&id_keys).unwrap())
.multiplex(libp2p_yamux::YamuxConfig::default()) .multiplex(libp2p_yamux::YamuxConfig::default())
.boxed(); .boxed();
let behaviour = Behaviour::new(config)?; let behaviour = Behaviour::new(config, peer_id)?;
let mut swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id); let mut swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id);
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
Ok(swarm) Ok(swarm)

View File

@ -59,7 +59,7 @@ async fn create_swarm(config: Config) -> Result<Swarm<Behaviour>, Box<dyn Error>
.authenticate(libp2p_noise::NoiseAuthenticated::xx(&id_keys).unwrap()) .authenticate(libp2p_noise::NoiseAuthenticated::xx(&id_keys).unwrap())
.multiplex(libp2p_yamux::YamuxConfig::default()) .multiplex(libp2p_yamux::YamuxConfig::default())
.boxed(); .boxed();
let behaviour = Behaviour::new(config)?; let behaviour = Behaviour::new(config, peer_id)?;
let mut swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id); let mut swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id);
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
Ok(swarm) Ok(swarm)

View File

@ -32,8 +32,8 @@ use libp2p_core::multiaddr::Protocol;
use libp2p_core::PeerId; use libp2p_core::PeerId;
use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm};
use libp2p_swarm::{ use libp2p_swarm::{
ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction,
PollParameters, NotifyHandler, PollParameters,
}; };
use std::collections::{hash_map, HashMap, HashSet, VecDeque}; use std::collections::{hash_map, HashMap, HashSet, VecDeque};
use std::num::NonZeroU32; use std::num::NonZeroU32;
@ -201,6 +201,8 @@ pub struct Relay {
/// Queue of actions to return when polled. /// Queue of actions to return when polled.
queued_actions: VecDeque<Action>, queued_actions: VecDeque<Action>,
external_addresses: ExternalAddresses,
} }
impl Relay { impl Relay {
@ -211,6 +213,7 @@ impl Relay {
reservations: Default::default(), reservations: Default::default(),
circuits: Default::default(), circuits: Default::default(),
queued_actions: Default::default(), queued_actions: Default::default(),
external_addresses: Default::default(),
} }
} }
@ -263,6 +266,8 @@ impl NetworkBehaviour for Relay {
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.external_addresses.on_swarn_event(&event);
match event { match event {
FromSwarm::ConnectionClosed(connection_closed) => { FromSwarm::ConnectionClosed(connection_closed) => {
self.on_connection_closed(connection_closed) self.on_connection_closed(connection_closed)
@ -639,10 +644,10 @@ impl NetworkBehaviour for Relay {
fn poll( fn poll(
&mut self, &mut self,
_cx: &mut Context<'_>, _cx: &mut Context<'_>,
poll_parameters: &mut impl PollParameters, _: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> { ) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
if let Some(action) = self.queued_actions.pop_front() { if let Some(action) = self.queued_actions.pop_front() {
return Poll::Ready(action.build(poll_parameters)); return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses));
} }
Poll::Pending Poll::Pending
@ -760,7 +765,8 @@ impl From<NetworkBehaviourAction<Event, handler::Prototype>> for Action {
impl Action { impl Action {
fn build( fn build(
self, self,
poll_parameters: &mut impl PollParameters, local_peer_id: PeerId,
external_addresses: &ExternalAddresses,
) -> NetworkBehaviourAction<Event, handler::Prototype> { ) -> NetworkBehaviourAction<Event, handler::Prototype> {
match self { match self {
Action::Done(action) => action, Action::Done(action) => action,
@ -773,15 +779,13 @@ impl Action {
peer_id, peer_id,
event: Either::Left(handler::In::AcceptReservationReq { event: Either::Left(handler::In::AcceptReservationReq {
inbound_reservation_req, inbound_reservation_req,
addrs: poll_parameters addrs: external_addresses
.external_addresses() .iter()
.map(|a| a.addr) .cloned()
// Add local peer ID in case it isn't present yet. // Add local peer ID in case it isn't present yet.
.filter_map(|a| match a.iter().last()? { .filter_map(|a| match a.iter().last()? {
Protocol::P2p(_) => Some(a), Protocol::P2p(_) => Some(a),
_ => Some( _ => Some(a.with(Protocol::P2p(local_peer_id.into()))),
a.with(Protocol::P2p(*poll_parameters.local_peer_id().as_ref())),
),
}) })
.collect(), .collect(),
}), }),

View File

@ -34,7 +34,8 @@ use libp2p_core::identity::Keypair;
use libp2p_core::{Multiaddr, PeerId, PeerRecord}; use libp2p_core::{Multiaddr, PeerId, PeerRecord};
use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::FromSwarm;
use libp2p_swarm::{ use libp2p_swarm::{
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, CloseConnection, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler,
PollParameters,
}; };
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use std::iter::FromIterator; use std::iter::FromIterator;
@ -57,6 +58,8 @@ pub struct Behaviour {
/// Tracks the expiry of registrations that we have discovered and stored in `discovered_peers` otherwise we have a memory leak. /// Tracks the expiry of registrations that we have discovered and stored in `discovered_peers` otherwise we have a memory leak.
expiring_registrations: FuturesUnordered<BoxFuture<'static, (PeerId, Namespace)>>, expiring_registrations: FuturesUnordered<BoxFuture<'static, (PeerId, Namespace)>>,
external_addresses: ExternalAddresses,
} }
impl Behaviour { impl Behaviour {
@ -70,6 +73,7 @@ impl Behaviour {
expiring_registrations: FuturesUnordered::from_iter(vec![ expiring_registrations: FuturesUnordered::from_iter(vec![
futures::future::pending().boxed() futures::future::pending().boxed()
]), ]),
external_addresses: Default::default(),
} }
} }
@ -215,7 +219,7 @@ impl NetworkBehaviour for Behaviour {
fn poll( fn poll(
&mut self, &mut self,
cx: &mut Context<'_>, cx: &mut Context<'_>,
poll_params: &mut impl PollParameters, _: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> { ) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
if let Some(event) = self.events.pop_front() { if let Some(event) = self.events.pop_front() {
return Poll::Ready(event); return Poll::Ready(event);
@ -224,10 +228,8 @@ impl NetworkBehaviour for Behaviour {
if let Some((namespace, rendezvous_node, ttl)) = self.pending_register_requests.pop() { if let Some((namespace, rendezvous_node, ttl)) = self.pending_register_requests.pop() {
// Update our external addresses based on the Swarm's current knowledge. // Update our external addresses based on the Swarm's current knowledge.
// It doesn't make sense to register addresses on which we are not reachable, hence this should not be configurable from the outside. // It doesn't make sense to register addresses on which we are not reachable, hence this should not be configurable from the outside.
let external_addresses = poll_params
.external_addresses() let external_addresses = self.external_addresses.iter().cloned().collect::<Vec<_>>();
.map(|r| r.addr)
.collect::<Vec<Multiaddr>>();
if external_addresses.is_empty() { if external_addresses.is_empty() {
return Poll::Ready(NetworkBehaviourAction::GenerateEvent( return Poll::Ready(NetworkBehaviourAction::GenerateEvent(
@ -268,6 +270,8 @@ impl NetworkBehaviour for Behaviour {
} }
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) { fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
self.external_addresses.on_swarn_event(&event);
match event { match event {
FromSwarm::ConnectionEstablished(_) FromSwarm::ConnectionEstablished(_)
| FromSwarm::ConnectionClosed(_) | FromSwarm::ConnectionClosed(_)

View File

@ -1,11 +1,13 @@
# 0.42.0 [unreleased] # 0.42.0 [unreleased]
- Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. - Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170].
- Deprecate functions on `PollParameters` in preparation for `PollParameters` to be removed entirely eventually. See [PR 3153].
- Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134]. - Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134].
[PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170
[PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134
[PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153
# 0.41.1 # 0.41.1

View File

@ -19,8 +19,13 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
mod either; mod either;
mod external_addresses;
mod listen_addresses;
pub mod toggle; pub mod toggle;
pub use external_addresses::ExternalAddresses;
pub use listen_addresses::ListenAddresses;
use crate::dial_opts::DialOpts; use crate::dial_opts::DialOpts;
use crate::handler::{ConnectionHandler, IntoConnectionHandler}; use crate::handler::{ConnectionHandler, IntoConnectionHandler};
use crate::{AddressRecord, AddressScore, DialError}; use crate::{AddressRecord, AddressScore, DialError};
@ -402,12 +407,24 @@ pub trait PollParameters {
fn supported_protocols(&self) -> Self::SupportedProtocolsIter; fn supported_protocols(&self) -> Self::SupportedProtocolsIter;
/// Returns the list of the addresses we're listening on. /// Returns the list of the addresses we're listening on.
#[deprecated(
since = "0.42.0",
note = "Use `libp2p_swarm::ListenAddresses` instead."
)]
fn listened_addresses(&self) -> Self::ListenedAddressesIter; fn listened_addresses(&self) -> Self::ListenedAddressesIter;
/// Returns the list of the addresses nodes can use to reach us. /// Returns the list of the addresses nodes can use to reach us.
#[deprecated(
since = "0.42.0",
note = "Use `libp2p_swarm::ExternalAddresses` instead."
)]
fn external_addresses(&self) -> Self::ExternalAddressesIter; fn external_addresses(&self) -> Self::ExternalAddressesIter;
/// Returns the peer id of the local node. /// Returns the peer id of the local node.
#[deprecated(
since = "0.42.0",
note = "Pass the node's `PeerId` into the behaviour instead."
)]
fn local_peer_id(&self) -> &PeerId; fn local_peer_id(&self) -> &PeerId;
} }

View File

@ -0,0 +1,50 @@
use crate::behaviour::{ExpiredExternalAddr, FromSwarm, NewExternalAddr};
use crate::IntoConnectionHandler;
use libp2p_core::Multiaddr;
use std::collections::HashSet;
/// The maximum number of local external addresses. When reached any
/// further externally reported addresses are ignored. The behaviour always
/// tracks all its listen addresses.
const MAX_LOCAL_EXTERNAL_ADDRS: usize = 20;
/// Utility struct for tracking the external addresses of a [`Swarm`](crate::Swarm).
#[derive(Debug, Clone)]
pub struct ExternalAddresses {
addresses: HashSet<Multiaddr>,
limit: usize,
}
impl Default for ExternalAddresses {
fn default() -> Self {
Self {
addresses: Default::default(),
limit: MAX_LOCAL_EXTERNAL_ADDRS,
}
}
}
impl ExternalAddresses {
/// Returns an [`Iterator`] over all external addresses.
pub fn iter(&self) -> impl ExactSizeIterator<Item = &Multiaddr> {
self.addresses.iter()
}
/// Feed a [`FromSwarm`] event to this struct.
pub fn on_swarn_event<THandler>(&mut self, event: &FromSwarm<THandler>)
where
THandler: IntoConnectionHandler,
{
match event {
FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => {
if self.addresses.len() < self.limit {
self.addresses.insert((*addr).clone());
}
}
FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr, .. }) => {
self.addresses.insert((*addr).clone());
}
_ => {}
}
}
}

View File

@ -0,0 +1,33 @@
use crate::behaviour::{ExpiredListenAddr, FromSwarm, NewListenAddr};
use crate::IntoConnectionHandler;
use libp2p_core::Multiaddr;
use std::collections::HashSet;
/// Utility struct for tracking the addresses a [`Swarm`](crate::Swarm) is listening on.
#[derive(Debug, Default, Clone)]
pub struct ListenAddresses {
addresses: HashSet<Multiaddr>,
}
impl ListenAddresses {
/// Returns an [`Iterator`] over all listen addresses.
pub fn iter(&self) -> impl ExactSizeIterator<Item = &Multiaddr> {
self.addresses.iter()
}
/// Feed a [`FromSwarm`] event to this struct.
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>)
where
THandler: IntoConnectionHandler,
{
match event {
FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => {
self.addresses.insert((*addr).clone());
}
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { addr, .. }) => {
self.addresses.insert((*addr).clone());
}
_ => {}
}
}
}

View File

@ -101,7 +101,8 @@ pub mod derive_prelude {
} }
pub use behaviour::{ pub use behaviour::{
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, CloseConnection, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction,
NotifyHandler, PollParameters,
}; };
pub use connection::pool::{ConnectionCounters, ConnectionLimits}; pub use connection::pool::{ConnectionCounters, ConnectionLimits};
pub use connection::{ pub use connection::{