sc_telemetry/
endpoints.rs1use libp2p::multiaddr::{self, Multiaddr};
20use serde::{Deserialize, Deserializer, Serialize};
21
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
27pub struct TelemetryEndpoints(
28 #[serde(deserialize_with = "url_or_multiaddr_deser")] pub(crate) Vec<(Multiaddr, u8)>,
29);
30
31fn url_or_multiaddr_deser<'de, D>(deserializer: D) -> Result<Vec<(Multiaddr, u8)>, D::Error>
33where
34 D: Deserializer<'de>,
35{
36 Vec::<(String, u8)>::deserialize(deserializer)?
37 .iter()
38 .map(|e| url_to_multiaddr(&e.0).map_err(serde::de::Error::custom).map(|m| (m, e.1)))
39 .collect()
40}
41
42impl TelemetryEndpoints {
43 pub fn new(endpoints: Vec<(String, u8)>) -> Result<Self, multiaddr::Error> {
45 let endpoints: Result<Vec<(Multiaddr, u8)>, multiaddr::Error> =
46 endpoints.iter().map(|e| Ok((url_to_multiaddr(&e.0)?, e.1))).collect();
47 endpoints.map(Self)
48 }
49}
50
51impl TelemetryEndpoints {
52 pub fn is_empty(&self) -> bool {
54 self.0.is_empty()
55 }
56}
57
58fn url_to_multiaddr(url: &str) -> Result<Multiaddr, multiaddr::Error> {
60 let parse_error = match url.parse() {
62 Ok(ma) => return Ok(ma),
63 Err(err) => err,
64 };
65
66 if let Ok(ma) = multiaddr::from_url(url) {
68 return Ok(ma)
69 }
70
71 Err(parse_error)
74}
75
76#[cfg(test)]
77mod tests {
78 use super::{url_to_multiaddr, Multiaddr, TelemetryEndpoints};
79
80 #[test]
81 fn valid_endpoints() {
82 let endp = vec![
83 ("wss://telemetry.polkadot.io/submit/".into(), 3),
84 ("/ip4/80.123.90.4/tcp/5432".into(), 4),
85 ];
86 let telem =
87 TelemetryEndpoints::new(endp.clone()).expect("Telemetry endpoint should be valid");
88 let mut res: Vec<(Multiaddr, u8)> = vec![];
89 for (a, b) in endp.iter() {
90 res.push((url_to_multiaddr(a).expect("provided url should be valid"), *b))
91 }
92 assert_eq!(telem.0, res);
93 }
94
95 #[test]
96 fn invalid_endpoints() {
97 let endp = vec![
98 ("/ip4/...80.123.90.4/tcp/5432".into(), 3),
99 ("/ip4/no:!?;rlkqre;;::::///tcp/5432".into(), 4),
100 ];
101 let telem = TelemetryEndpoints::new(endp);
102 assert!(telem.is_err());
103 }
104
105 #[test]
106 fn valid_and_invalid_endpoints() {
107 let endp = vec![
108 ("/ip4/80.123.90.4/tcp/5432".into(), 3),
109 ("/ip4/no:!?;rlkqre;;::::///tcp/5432".into(), 4),
110 ];
111 let telem = TelemetryEndpoints::new(endp);
112 assert!(telem.is_err());
113 }
114}