snowstorm/net/
discovery.rs

1use libp2p::{
2    rendezvous::{Cookie, Namespace},
3    PeerId,
4};
5use log::{debug, warn};
6
7use super::behaviour::SnowstormBehaviour;
8use crate::{config::Config, identity::Role};
9
10pub fn role_to_namespace(config: &Config, role: Role) -> Namespace {
11    let prefix = config.namespace.clone() + "/";
12    let namespace = Namespace::new(prefix + &role.to_string()).unwrap();
13    namespace
14}
15
16pub fn location_to_namespaces(config: &Config, location: String) -> Vec<Namespace> {
17    let prefix = config.namespace.clone() + "/location/";
18    let mut namespaces = vec![];
19    let mut location = location.clone();
20    location.truncate(config.privacy_level as usize);
21
22    let mut location = location.chars().collect::<Vec<_>>();
23    location.reverse();
24
25    let mut prefix = prefix.clone();
26    prefix.push_str("location/");
27
28    for (_, c) in location.iter().enumerate() {
29        let mut prefix = prefix.clone();
30        prefix.push(*c);
31
32        namespaces.push(Namespace::new(prefix).unwrap());
33    }
34
35    namespaces
36}
37
38impl From<&Config> for Vec<Namespace> {
39    fn from(config: &Config) -> Self {
40        let mut namespaces = vec![];
41
42        for role in config.roles.iter() {
43            if *role == Role::Client {
44                continue;
45            }
46
47            namespaces.push(role_to_namespace(config, *role));
48        }
49
50        if let Some(location) = &config.location {
51            namespaces.extend(location_to_namespaces(config, location.clone()));
52        }
53
54        debug!("namespaces: {:?}", namespaces);
55
56        namespaces
57    }
58}
59
60pub fn register(config: &Config, behaviour: &mut SnowstormBehaviour, point: PeerId) {
61    let rc = behaviour.rendezvous_client().unwrap();
62    let namespaces = Vec::<Namespace>::from(config);
63
64    for namespace in namespaces {
65        if let Err(err) = rc.register(namespace.clone(), point.clone(), config.discovery_ttl) {
66            warn!("failed to register namespace {:?}: {:?}", namespace, err);
67        } else {
68            debug!("registered namespace: {:?}", namespace);
69        }
70    }
71}
72
73pub fn search_role(
74    config: &Config,
75    behaviour: &mut SnowstormBehaviour,
76    role: Role,
77    point: PeerId,
78    cookie: Option<Cookie>,
79) {
80    let rc = behaviour.rendezvous_client().unwrap();
81    let nstr = config.namespace.clone() + "/" + &role.to_string();
82    let namespace = Namespace::new(nstr).unwrap();
83
84    rc.discover(Some(namespace), cookie, Some(8), point)
85}