diff --git a/protocols/identify/CHANGELOG.md b/protocols/identify/CHANGELOG.md index e86afde808e..f90d8ce3da4 100644 --- a/protocols/identify/CHANGELOG.md +++ b/protocols/identify/CHANGELOG.md @@ -10,10 +10,14 @@ - Fix aborting the answering of an identify request in rare situations. See [PR 3876]. +- Actively push changes in listen protocols to remote. + See [PR 3980]. + +[PR 3545]: https://github.com/libp2p/rust-libp2p/pull/3545 [PR 3698]: https://github.com/libp2p/rust-libp2p/pull/3698 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 -[PR 3545]: https://github.com/libp2p/rust-libp2p/pull/3545 [PR 3876]: https://github.com/libp2p/rust-libp2p/pull/3876 +[PR 3980]: https://github.com/libp2p/rust-libp2p/pull/3980 ## 0.42.2 diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 4c7ae58631e..5a1712e8c3d 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -36,7 +36,7 @@ use libp2p_swarm::{ ConnectionHandler, ConnectionHandlerEvent, KeepAlive, StreamProtocol, StreamUpgradeError, SubstreamProtocol, SupportedProtocols, }; -use log::warn; +use log::{warn, Level}; use smallvec::SmallVec; use std::collections::HashSet; use std::{io, task::Context, task::Poll, time::Duration}; @@ -60,6 +60,9 @@ pub struct Handler { /// Future that fires when we need to identify the node again. trigger_next_identify: Delay, + /// Whether we have exchanged at least one periodic identify. + exchanged_one_periodic_identify: bool, + /// The interval of `trigger_next_identify`, i.e. the recurrent delay. interval: Duration, @@ -122,6 +125,7 @@ impl Handler { events: SmallVec::new(), pending_replies: FuturesUnordered::new(), trigger_next_identify: Delay::new(initial_delay), + exchanged_one_periodic_identify: false, interval, public_key, protocol_version, @@ -238,6 +242,14 @@ impl Handler { self.remote_supported_protocols = new_remote_protocols; } + + fn local_protocols_to_string(&mut self) -> String { + self.local_supported_protocols + .iter() + .map(|p| p.to_string()) + .collect::>() + .join(", ") + } } impl ConnectionHandler for Handler { @@ -319,6 +331,7 @@ impl ConnectionHandler for Handler { let event = result .map(|()| Event::Identification) .unwrap_or_else(|err| Event::IdentificationError(StreamUpgradeError::Apply(err))); + self.exchanged_one_periodic_identify = true; return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)); } @@ -349,7 +362,29 @@ impl ConnectionHandler for Handler { | ConnectionEvent::ListenUpgradeError(_) | ConnectionEvent::RemoteProtocolsChange(_) => {} ConnectionEvent::LocalProtocolsChange(change) => { - self.local_supported_protocols.on_protocols_change(change); + let before = log::log_enabled!(Level::Debug) + .then(|| self.local_protocols_to_string()) + .unwrap_or_default(); + let protocols_changed = self.local_supported_protocols.on_protocols_change(change); + let after = log::log_enabled!(Level::Debug) + .then(|| self.local_protocols_to_string()) + .unwrap_or_default(); + + if protocols_changed && self.exchanged_one_periodic_identify { + log::debug!( + "Supported listen protocols changed from [{before}] to [{after}], pushing to {}", + self.remote_peer_id + ); + + let info = self.build_info(); + self.events + .push(ConnectionHandlerEvent::OutboundSubstreamRequest { + protocol: SubstreamProtocol::new( + Either::Right(Push::outbound(info)), + (), + ), + }); + } } } }