casper_types/
peers_map.rs

1use alloc::collections::BTreeMap;
2
3use crate::bytesrepr::{self, FromBytes, ToBytes};
4use alloc::{
5    string::{String, ToString},
6    vec::Vec,
7};
8#[cfg(feature = "json-schema")]
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12#[cfg(any(feature = "testing", test))]
13use crate::testing::TestRng;
14#[cfg(any(feature = "testing", test))]
15use core::iter;
16#[cfg(any(feature = "testing", test))]
17use rand::Rng;
18
19/// Node peer entry.
20#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
21#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
22#[serde(deny_unknown_fields)]
23pub struct PeerEntry {
24    /// Node id.
25    pub node_id: String,
26    /// Node address.
27    pub address: String,
28}
29
30impl PeerEntry {
31    #[cfg(any(feature = "testing", test))]
32    pub(crate) fn random(rng: &mut TestRng) -> Self {
33        Self {
34            node_id: rng.random_string(10..20),
35            address: rng.random_string(10..20),
36        }
37    }
38}
39
40impl ToBytes for PeerEntry {
41    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
42        let mut buffer = bytesrepr::allocate_buffer(self)?;
43        self.write_bytes(&mut buffer)?;
44        Ok(buffer)
45    }
46
47    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
48        self.node_id.write_bytes(writer)?;
49        self.address.write_bytes(writer)
50    }
51
52    fn serialized_length(&self) -> usize {
53        self.node_id.serialized_length() + self.address.serialized_length()
54    }
55}
56
57impl FromBytes for PeerEntry {
58    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
59        let (node_id, remainder) = String::from_bytes(bytes)?;
60        let (address, remainder) = String::from_bytes(remainder)?;
61        Ok((PeerEntry { node_id, address }, remainder))
62    }
63}
64
65/// Map of peer IDs to network addresses.
66#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
67#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
68#[serde(deny_unknown_fields)]
69pub struct Peers(Vec<PeerEntry>);
70
71impl Peers {
72    /// Retrieve collection of `PeerEntry` records.
73    pub fn into_inner(self) -> Vec<PeerEntry> {
74        self.0
75    }
76
77    /// Random.
78    #[cfg(any(feature = "testing", test))]
79    pub fn random(rng: &mut TestRng) -> Self {
80        let count = rng.gen_range(0..10);
81        let peers = iter::repeat(())
82            .map(|_| PeerEntry::random(rng))
83            .take(count)
84            .collect();
85        Self(peers)
86    }
87}
88
89impl<Id: ToString> From<BTreeMap<Id, String>> for Peers {
90    fn from(input: BTreeMap<Id, String>) -> Self {
91        let ret = input
92            .into_iter()
93            .map(|(node_id, address)| PeerEntry {
94                node_id: node_id.to_string(),
95                address,
96            })
97            .collect();
98        Peers(ret)
99    }
100}
101
102impl ToBytes for Peers {
103    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
104        let mut buffer = bytesrepr::allocate_buffer(self)?;
105        self.write_bytes(&mut buffer)?;
106        Ok(buffer)
107    }
108
109    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
110        self.0.write_bytes(writer)
111    }
112
113    fn serialized_length(&self) -> usize {
114        self.0.serialized_length()
115    }
116}
117
118impl FromBytes for Peers {
119    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
120        let (inner, remainder) = Vec::<PeerEntry>::from_bytes(bytes)?;
121        Ok((Peers(inner), remainder))
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128    use crate::testing::TestRng;
129
130    #[test]
131    fn bytesrepr_roundtrip() {
132        let rng = &mut TestRng::new();
133
134        let val = Peers::random(rng);
135        bytesrepr::test_serialization_roundtrip(&val);
136    }
137
138    #[test]
139    fn bytesrepr_empty_roundtrip() {
140        let val = Peers(vec![]);
141        bytesrepr::test_serialization_roundtrip(&val);
142    }
143
144    #[test]
145    fn bytesrepr_empty_vec_should_have_count_0() {
146        let val = Peers(vec![]);
147        let x = Peers::to_bytes(&val).expect("should have vec");
148        let (count, _) = u32::from_bytes(&x).expect("should have count");
149        assert!(count == 0, "count should be 0");
150    }
151}