diff --git a/Cargo.lock b/Cargo.lock index 6357312d4e9..b2fa7f3873b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2992,6 +2992,7 @@ dependencies = [ "libp2p-swarm-test", "libp2p-yamux", "log", + "once_cell", "quickcheck-ext", "rand 0.8.5", "smallvec", diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 9e3d5e1b340..365c0e771c2 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -7,8 +7,12 @@ This type enforces invariants on protocol names, such as leading forward slashes and correct UTF8 encoding. See [PR 3746]. -[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 +- Return a bool from `ExternalAddresses::on_swarm_event` and `ListenAddresses::on_swarm_event` indicating whether any state was changed. + See [PR 3865]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 +[PR 3865]: https://github.com/libp2p/rust-libp2p/pull/3865 ## 0.42.2 diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 1d34dc03b13..722f3610b95 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -51,6 +51,7 @@ libp2p-swarm-test = { workspace = true } libp2p-yamux = { workspace = true } quickcheck = { workspace = true } void = "1" +once_cell = "1.17.1" [[test]] name = "swarm_derive" diff --git a/swarm/src/behaviour/external_addresses.rs b/swarm/src/behaviour/external_addresses.rs index 2090d4b3481..6f1d523ef37 100644 --- a/swarm/src/behaviour/external_addresses.rs +++ b/swarm/src/behaviour/external_addresses.rs @@ -32,21 +32,67 @@ impl ExternalAddresses { } /// Feed a [`FromSwarm`] event to this struct. + /// + /// Returns whether the event changed our set of external addresses. #[allow(deprecated)] - pub fn on_swarm_event(&mut self, event: &FromSwarm) + pub fn on_swarm_event(&mut self, event: &FromSwarm) -> bool where THandler: IntoConnectionHandler, { match event { FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => { if self.addresses.len() < self.limit { - self.addresses.insert((*addr).clone()); + return self.addresses.insert((*addr).clone()); } } FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr, .. }) => { - self.addresses.remove(addr); + return self.addresses.remove(addr) } _ => {} } + + false + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::dummy; + use libp2p_core::multiaddr::Protocol; + use once_cell::sync::Lazy; + + #[test] + fn new_external_addr_returns_correct_changed_value() { + let mut addresses = ExternalAddresses::default(); + + let changed = addresses.on_swarm_event(&new_external_addr()); + assert!(changed); + + let changed = addresses.on_swarm_event(&new_external_addr()); + assert!(!changed) + } + + #[test] + fn expired_external_addr_returns_correct_changed_value() { + let mut addresses = ExternalAddresses::default(); + addresses.on_swarm_event(&new_external_addr()); + + let changed = addresses.on_swarm_event(&expired_external_addr()); + assert!(changed); + + let changed = addresses.on_swarm_event(&expired_external_addr()); + assert!(!changed) + } + + fn new_external_addr() -> FromSwarm<'static, dummy::ConnectionHandler> { + FromSwarm::NewExternalAddr(NewExternalAddr { addr: &MEMORY_ADDR }) + } + + fn expired_external_addr() -> FromSwarm<'static, dummy::ConnectionHandler> { + FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr: &MEMORY_ADDR }) } + + static MEMORY_ADDR: Lazy = + Lazy::new(|| Multiaddr::empty().with(Protocol::Memory(1000))); } diff --git a/swarm/src/behaviour/listen_addresses.rs b/swarm/src/behaviour/listen_addresses.rs index 07bd003bc8d..f2b61582850 100644 --- a/swarm/src/behaviour/listen_addresses.rs +++ b/swarm/src/behaviour/listen_addresses.rs @@ -17,19 +17,69 @@ impl ListenAddresses { } /// Feed a [`FromSwarm`] event to this struct. + /// + /// Returns whether the event changed our set of listen addresses. #[allow(deprecated)] - pub fn on_swarm_event(&mut self, event: &FromSwarm) + pub fn on_swarm_event(&mut self, event: &FromSwarm) -> bool where THandler: IntoConnectionHandler, { match event { FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => { - self.addresses.insert((*addr).clone()); + self.addresses.insert((*addr).clone()) } FromSwarm::ExpiredListenAddr(ExpiredListenAddr { addr, .. }) => { - self.addresses.remove(addr); + self.addresses.remove(addr) } - _ => {} + _ => false, } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::dummy; + use libp2p_core::multiaddr::Protocol; + use once_cell::sync::Lazy; + + #[test] + fn new_listen_addr_returns_correct_changed_value() { + let mut addresses = ListenAddresses::default(); + + let changed = addresses.on_swarm_event(&new_listen_addr()); + assert!(changed); + + let changed = addresses.on_swarm_event(&new_listen_addr()); + assert!(!changed) + } + + #[test] + fn expired_listen_addr_returns_correct_changed_value() { + let mut addresses = ListenAddresses::default(); + addresses.on_swarm_event(&new_listen_addr()); + + let changed = addresses.on_swarm_event(&expired_listen_addr()); + assert!(changed); + + let changed = addresses.on_swarm_event(&expired_listen_addr()); + assert!(!changed) + } + + fn new_listen_addr() -> FromSwarm<'static, dummy::ConnectionHandler> { + FromSwarm::NewListenAddr(NewListenAddr { + listener_id: Default::default(), + addr: &MEMORY_ADDR, + }) + } + + fn expired_listen_addr() -> FromSwarm<'static, dummy::ConnectionHandler> { + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { + listener_id: Default::default(), + addr: &MEMORY_ADDR, + }) + } + + static MEMORY_ADDR: Lazy = + Lazy::new(|| Multiaddr::empty().with(Protocol::Memory(1000))); +}