summaryrefslogtreecommitdiffstats
path: root/src/swarm
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm')
-rw-r--r--src/swarm/members.rs32
-rw-r--r--src/swarm/topology.rs1
2 files changed, 33 insertions, 0 deletions
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:<multiaddr>`, 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<String> {
+ 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<String> {
let mut path = member_path(pk);
path.push("alive".to_owned());
@@ -303,6 +324,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);
assert_eq!(alive_renewal(7 * day), day);
diff --git a/src/swarm/topology.rs b/src/swarm/topology.rs
index 1e4f5b9..1d98637 100644
--- a/src/swarm/topology.rs
+++ b/src/swarm/topology.rs
@@ -163,6 +163,7 @@ pub(crate) async fn refresh(state: &AppState) -> Option<NeighbourChange> {
let replica = state.doc.read().await;
members::learn_addresses(state, &replica.doc);
set_aliases(state, members::aliases(&replica.doc));
+ state.transport.learn_relays(&members::relays(&replica.doc));
let current = members::members(&replica.doc);
// Those that said they are alive within the electorate window.
let alive: BTreeSet<String> = members::electorate(