From d7959009790a422ebb17d4c4ab1d9be3d48dc511 Mon Sep 17 00:00:00 2001 From: tv Date: Wed, 28 Oct 2026 17:38:16 +0100 Subject: list libp2p relays in document --- src/swarm/members.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/swarm/members.rs') diff --git a/src/swarm/members.rs b/src/swarm/members.rs index c2edd01..3bfb9cf 100644 --- a/src/swarm/members.rs +++ b/src/swarm/members.rs @@ -146,6 +146,27 @@ pub(crate) fn learn_addresses(state: &AppState, doc: &AutoCommit) { } } +/// Relays listed for the swarm, at most this many. +const MAX_RELAYS: usize = 32; + +/// The relays listed for the swarm under `_continuum/relays` (by `--protocol-writers`): +/// addresses (`libp2p:`, with or without the relay's peer ID) of relays that +/// aren't members, e.g. nodes that only relay. Every member's transport may +/// pick them (`Transport::learn_relays`), after the relays it is configured with. +pub(crate) fn relays(doc: &AutoCommit) -> Vec { + match store::read_path(doc, &meta::path(&[meta::RELAYS])) { + Ok(Some(JsonValue::Array(items))) => items + .into_iter() + .filter_map(|item| match item { + JsonValue::String(address) => Some(address), + _ => None, + }) + .take(MAX_RELAYS) + .collect(), + _ => Vec::new(), + } +} + fn alive_path(pk: &str) -> Vec { let mut path = member_path(pk); path.push("alive".to_owned()); @@ -302,6 +323,17 @@ mod tests { ); } + #[test] + fn listed_relays() { + let mut doc = AutoCommit::new(); + assert!(relays(&doc).is_empty()); + let relay = "libp2p:/ip6/fd00::1/tcp/9661"; + store::write_path(&mut doc, &meta::path(&[meta::RELAYS]), &json!([relay, 7])).unwrap(); + assert_eq!(relays(&doc), [relay]); // Anything but text is ignored. + store::write_path(&mut doc, &meta::path(&[meta::RELAYS]), &json!(relay)).unwrap(); + assert!(relays(&doc).is_empty()); // Not a list. + } + #[test] fn renewal_interval() { let day = Duration::from_secs(24 * 3600); -- cgit v1.3.1