1use crate::config::{PeerRole, RoleType};
8use diem_types::PeerId;
9use serde::{Deserialize, Serialize, Serializer};
10use short_hex_str::AsShortHexStr;
11use std::{cmp::Ordering, fmt};
12
13#[derive(Clone, Eq, PartialEq, Serialize)]
17pub struct NetworkContext {
18 role: RoleType,
20 #[serde(serialize_with = "NetworkId::serialize_str")]
21 network_id: NetworkId,
22 peer_id: PeerId,
23}
24
25impl fmt::Debug for NetworkContext {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27 write!(f, "{}", self)
28 }
29}
30
31impl fmt::Display for NetworkContext {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 write!(
34 f,
35 "[{},{},{}]",
36 self.role,
37 self.network_id.as_str(),
38 self.peer_id.short_str(),
39 )
40 }
41}
42
43impl NetworkContext {
44 pub fn new(
45 role: RoleType, network_id: NetworkId, peer_id: PeerId,
46 ) -> NetworkContext {
47 NetworkContext {
48 role,
49 network_id,
50 peer_id,
51 }
52 }
53
54 pub fn role(&self) -> RoleType { self.role }
55
56 pub fn network_id(&self) -> &NetworkId { &self.network_id }
57
58 pub fn peer_id(&self) -> PeerId { self.peer_id }
59
60 #[cfg(any(test, feature = "testing", feature = "fuzzing"))]
61 pub fn mock_with_peer_id(peer_id: PeerId) -> std::sync::Arc<Self> {
62 std::sync::Arc::new(Self::new(
63 RoleType::Validator,
64 NetworkId::Validator,
65 peer_id,
66 ))
67 }
68
69 #[cfg(any(test, feature = "testing", feature = "fuzzing"))]
70 pub fn mock() -> std::sync::Arc<Self> {
71 std::sync::Arc::new(Self::new(
72 RoleType::Validator,
73 NetworkId::Validator,
74 PeerId::random(),
75 ))
76 }
77}
78
79#[derive(Clone, Deserialize, Eq, Hash, PartialEq, Serialize)]
86#[serde(rename = "NetworkId", rename_all = "snake_case")]
87pub enum NetworkId {
88 Validator,
89 Public,
90 Private(String),
91}
92
93impl PartialOrd for NetworkId {
94 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
95 Some(self.cmp(other))
96 }
97}
98
99impl Ord for NetworkId {
100 fn cmp(&self, other: &Self) -> Ordering {
105 if self == other {
107 Ordering::Equal
108 } else {
109 match self {
111 NetworkId::Validator => Ordering::Less,
112 NetworkId::Public => Ordering::Greater,
113 NetworkId::Private(_) => match other {
114 NetworkId::Validator => Ordering::Greater,
115 NetworkId::Public => Ordering::Less,
116 NetworkId::Private(_) => {
117 if self.is_vfn_network() {
118 Ordering::Less
119 } else {
120 Ordering::Greater
121 }
122 }
123 },
124 }
125 }
126 }
127}
128
129#[derive(Clone, Deserialize, Eq, Hash, PartialEq, Serialize)]
134pub struct NodeNetworkId(NetworkId, usize);
135
136impl NodeNetworkId {
137 pub fn new(network_id: NetworkId, num_id: usize) -> Self {
138 Self(network_id, num_id)
139 }
140
141 pub fn network_id(&self) -> NetworkId { self.0.clone() }
142}
143
144impl fmt::Debug for NodeNetworkId {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 write!(f, "{}", self)
147 }
148}
149
150impl fmt::Display for NodeNetworkId {
151 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152 write!(f, "{}:{}", self.0, self.1)
153 }
154}
155
156impl Default for NetworkId {
158 fn default() -> NetworkId { NetworkId::Public }
159}
160
161impl fmt::Debug for NetworkId {
162 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 f.write_str(self.as_str())
164 }
165}
166
167impl fmt::Display for NetworkId {
168 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169 f.write_str(self.as_str())
170 }
171}
172
173const VFN_NETWORK: &str = "vfn";
174
175impl NetworkId {
176 pub fn vfn_network() -> NetworkId {
178 NetworkId::Private(VFN_NETWORK.to_string())
179 }
180
181 pub fn is_vfn_network(&self) -> bool {
182 matches!(self, NetworkId::Private(network) if network == VFN_NETWORK)
183 }
184
185 pub fn is_validator_network(&self) -> bool {
186 matches!(self, NetworkId::Validator)
187 }
188
189 pub fn upstream_roles(&self, role: &RoleType) -> &'static [PeerRole] {
191 match self {
192 NetworkId::Validator => &[PeerRole::Validator],
193 NetworkId::Public => &[
194 PeerRole::PreferredUpstream,
195 PeerRole::Upstream,
196 PeerRole::ValidatorFullNode,
197 ],
198 NetworkId::Private(_) => {
199 if self.is_vfn_network() {
200 match role {
201 RoleType::Validator => &[],
202 RoleType::FullNode => &[PeerRole::Validator],
203 }
204 } else {
205 &[PeerRole::PreferredUpstream, PeerRole::Upstream]
206 }
207 }
208 }
209 }
210
211 pub fn downstream_roles(&self, role: &RoleType) -> &'static [PeerRole] {
213 match self {
214 NetworkId::Validator => &[PeerRole::Validator],
215 NetworkId::Public => &[
218 PeerRole::ValidatorFullNode,
219 PeerRole::Downstream,
220 PeerRole::Known,
221 PeerRole::Unknown,
222 ],
223 NetworkId::Private(_) => {
224 if self.is_vfn_network() {
225 match role {
226 RoleType::Validator => &[PeerRole::ValidatorFullNode],
227 RoleType::FullNode => &[],
228 }
229 } else {
230 &[PeerRole::Downstream, PeerRole::Known]
232 }
233 }
234 }
235 }
236
237 pub fn as_str(&self) -> &str {
238 match self {
239 NetworkId::Validator => "Validator",
240 NetworkId::Public => "Public",
241 NetworkId::Private(info) => info.as_ref(),
248 }
249 }
250
251 fn serialize_str<S>(
252 &self, serializer: S,
253 ) -> std::result::Result<S::Ok, S::Error>
254 where S: Serializer {
255 self.as_str().serialize(serializer)
256 }
257}
258
259#[cfg(test)]
260mod test {
261 use super::*;
262
263 #[test]
264 fn test_ensure_network_id_order() {
265 assert!(NetworkId::Validator < NetworkId::vfn_network());
266 assert!(NetworkId::vfn_network() < NetworkId::Public);
267 assert!(NetworkId::Validator < NetworkId::Public);
268 }
269
270 #[test]
271 fn test_serialization() {
272 let id = NetworkId::vfn_network();
273 let encoded = yaml_serde::to_string(&id).unwrap();
274 let decoded: NetworkId =
275 yaml_serde::from_str(encoded.as_str()).unwrap();
276 assert_eq!(id, decoded);
277 let encoded = yaml_serde::to_string(&id).unwrap().into_bytes();
278 let decoded: NetworkId =
279 yaml_serde::from_slice(encoded.as_slice()).unwrap();
280 assert_eq!(id, decoded);
281
282 let id = NetworkId::Validator;
283 let encoded = yaml_serde::to_string(&id).unwrap();
284 let decoded: NetworkId =
285 yaml_serde::from_str(encoded.as_str()).unwrap();
286 assert_eq!(id, decoded);
287 let encoded = yaml_serde::to_string(&id).unwrap().into_bytes();
288 let decoded: NetworkId =
289 yaml_serde::from_slice(encoded.as_slice()).unwrap();
290 assert_eq!(id, decoded);
291 }
292
293 #[test]
294 fn test_network_context_serialization() {
295 let peer_id = PeerId::random();
296 let context = NetworkContext::new(
297 RoleType::Validator,
298 NetworkId::vfn_network(),
299 peer_id,
300 );
301 let expected = format!(
302 "role: {}\nnetwork_id: {}\npeer_id: {:x}\n",
303 RoleType::Validator,
304 VFN_NETWORK,
305 peer_id
306 );
307 assert_eq!(expected, yaml_serde::to_string(&context).unwrap());
308 }
309}