feat(swarm): report outcome of handling SwarmEvent

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.
This commit is contained in:
Thomas Eizinger 2023-05-05 09:46:31 +02:00 committed by GitHub
parent 1eb929b38a
commit eecfe2f094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 8 deletions

1
Cargo.lock generated
View File

@ -2992,6 +2992,7 @@ dependencies = [
"libp2p-swarm-test",
"libp2p-yamux",
"log",
"once_cell",
"quickcheck-ext",
"rand 0.8.5",
"smallvec",

View File

@ -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

View File

@ -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"

View File

@ -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)));
}

View File

@ -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)));
}