Skip to content

Commit

Permalink
feat(swarm): report outcome of handling SwarmEvent
Browse files Browse the repository at this point in the history
Previously, a user wouldn't know whether passing a `SwarmEvent` to `ListenAddresses` or `ExternalAddresses` changed the state. We now return a boolean where `true` indicates that we handled the event **and** changed state as a result.

The API is inspired by `HashSet::insert` and the like.

Pull-Request: #3865.
  • Loading branch information
thomaseizinger authored May 5, 2023
1 parent 1eb929b commit eecfe2f
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion swarm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions swarm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
52 changes: 49 additions & 3 deletions swarm/src/behaviour/external_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<THandler>(&mut self, event: &FromSwarm<THandler>)
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>) -> 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<Multiaddr> =
Lazy::new(|| Multiaddr::empty().with(Protocol::Memory(1000)));
}
58 changes: 54 additions & 4 deletions swarm/src/behaviour/listen_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<THandler>(&mut self, event: &FromSwarm<THandler>)
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>) -> 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<Multiaddr> =
Lazy::new(|| Multiaddr::empty().with(Protocol::Memory(1000)));
}

0 comments on commit eecfe2f

Please sign in to comment.