1use std::{
3 cmp::Ordering,
4 collections::HashSet,
5 fmt,
6 hash::{Hash, Hasher},
7 io::{self, Error, ErrorKind},
8 path::Path,
9 str::FromStr,
10};
11
12use lazy_static::lazy_static;
13use serde::{self, de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
14use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned};
15
16use crate::{formatting, hash, ids::short};
17
18pub const LEN: usize = 20;
19pub const ENCODE_PREFIX: &str = "NodeID-";
20
21lazy_static! {
22 static ref EMPTY: Vec<u8> = vec![0; LEN];
23}
24
25#[derive(Debug, Copy, Clone, Eq, AsBytes, FromZeroes, FromBytes, Unaligned)]
28#[repr(transparent)]
29pub struct Id([u8; LEN]);
30
31impl Default for Id {
32 fn default() -> Self {
33 Self::empty()
34 }
35}
36
37impl Id {
38 pub fn empty() -> Self {
39 Id([0; LEN])
40 }
41
42 pub fn is_empty(&self) -> bool {
43 (*self) == Self::empty()
44 }
45
46 pub fn to_vec(&self) -> Vec<u8> {
47 self.0.to_vec()
48 }
49
50 pub fn from_slice(d: &[u8]) -> Self {
51 assert_eq!(d.len(), LEN);
52 let d: [u8; LEN] = d.try_into().unwrap();
53 Id(d)
54 }
55
56 pub fn from_cert_pem_file(cert_file_path: &str) -> io::Result<Self> {
59 log::info!("loading node ID from certificate {}", cert_file_path);
60 let pub_key_der = cert_manager::x509::load_pem_cert_to_der(cert_file_path)?;
61
62 Self::from_cert_der_bytes(pub_key_der)
65 }
66
67 pub fn from_cert_der_bytes<S>(cert_bytes: S) -> io::Result<Self>
72 where
73 S: AsRef<[u8]>,
74 {
75 let short_address = hash::sha256_ripemd160(cert_bytes)?;
76 let node_id = Self::from_slice(&short_address);
77 Ok(node_id)
78 }
79
80 pub fn load_or_generate_pem(key_path: &str, cert_path: &str) -> io::Result<(Self, bool)> {
84 let tls_key_exists = Path::new(&key_path).exists();
85 log::info!("staking TLS key {} exists? {}", key_path, tls_key_exists);
86
87 let tls_cert_exists = Path::new(&cert_path).exists();
88 log::info!("staking TLS cert {} exists? {}", cert_path, tls_cert_exists);
89
90 let mut generated = false;
91 if !tls_key_exists || !tls_cert_exists {
92 log::info!(
93 "generating staking TLS certs (key exists {}, cert exists {})",
94 tls_key_exists,
95 tls_cert_exists
96 );
97 cert_manager::x509::generate_and_write_pem(None, key_path, cert_path)?;
98 generated = true;
99 } else {
100 log::info!(
101 "loading existing staking TLS certificates from '{}' and '{}'",
102 key_path,
103 cert_path
104 );
105 }
106
107 let node_id = Self::from_cert_pem_file(cert_path)?;
108 Ok((node_id, generated))
109 }
110
111 pub fn short_id(&self) -> short::Id {
112 short::Id::from_slice(&self.0)
113 }
114}
115
116impl AsRef<[u8]> for Id {
117 fn as_ref(&self) -> &[u8] {
118 &self.0
119 }
120}
121
122impl fmt::Display for Id {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 let mut node_id = String::from(ENCODE_PREFIX);
128 let short_id = formatting::encode_cb58_with_checksum_string(&self.0);
129 node_id.push_str(&short_id);
130 write!(f, "{}", node_id)
131 }
132}
133
134impl FromStr for Id {
136 type Err = Error;
137 fn from_str(s: &str) -> Result<Self, Self::Err> {
138 let processed = s.trim().trim_start_matches(ENCODE_PREFIX);
140 let decoded = formatting::decode_cb58_with_checksum(processed).map_err(|e| {
141 Error::new(
142 ErrorKind::Other,
143 format!("failed decode_cb58_with_checksum '{}'", e),
144 )
145 })?;
146 Ok(Self::from_slice(&decoded))
147 }
148}
149
150impl Serialize for Id {
153 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
154 where
155 S: Serializer,
156 {
157 serializer.serialize_str(&self.to_string())
158 }
159}
160
161impl<'de> Deserialize<'de> for Id {
164 fn deserialize<D>(deserializer: D) -> std::result::Result<Id, D::Error>
165 where
166 D: Deserializer<'de>,
167 {
168 struct IdVisitor;
169
170 impl<'de> Visitor<'de> for IdVisitor {
171 type Value = Id;
172
173 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
174 formatter.write_str("a base-58 encoded ID-string with checksum")
175 }
176
177 fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
178 where
179 E: serde::de::Error,
180 {
181 Id::from_str(v).map_err(E::custom)
182 }
183 }
184
185 deserializer.deserialize_any(IdVisitor)
186 }
187}
188
189#[test]
191fn test_custom_de_serializer() {
192 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
193 struct Data {
194 node_id: Id,
195 }
196
197 let d = Data {
198 node_id: Id::from_str("NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx").unwrap(),
199 };
200
201 let yaml_encoded = serde_yaml::to_string(&d).unwrap();
202 println!("yaml_encoded:\n{}", yaml_encoded);
203 let yaml_decoded = serde_yaml::from_str(&yaml_encoded).unwrap();
204 assert_eq!(d, yaml_decoded);
205
206 let json_encoded = serde_json::to_string(&d).unwrap();
207 println!("json_encoded:\n{}", json_encoded);
208 let json_decoded = serde_json::from_str(&json_encoded).unwrap();
209 assert_eq!(d, json_decoded);
210
211 let json_decoded_2: Data =
212 serde_json::from_str(r#"{ "node_id":"NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx" }"#)
213 .unwrap();
214 assert_eq!(d, json_decoded_2);
215
216 let json_encoded_3 = serde_json::json!(
217 {
218 "node_id": "NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"
219 }
220 );
221 let json_decoded_3: Data = serde_json::from_value(json_encoded_3).unwrap();
222 assert_eq!(d, json_decoded_3);
223}
224
225fn fmt_id<'de, D>(deserializer: D) -> Result<Id, D::Error>
226where
227 D: Deserializer<'de>,
228{
229 let s = String::deserialize(deserializer)?;
230 Id::from_str(&s).map_err(serde::de::Error::custom)
231}
232
233pub fn deserialize_id<'de, D>(deserializer: D) -> Result<Option<Id>, D::Error>
236where
237 D: Deserializer<'de>,
238{
239 #[derive(Deserialize)]
240 struct Wrapper(#[serde(deserialize_with = "fmt_id")] Id);
241 let v = Option::deserialize(deserializer)?;
242 Ok(v.map(|Wrapper(a)| a))
243}
244
245pub fn must_deserialize_id<'de, D>(deserializer: D) -> Result<Id, D::Error>
249where
250 D: Deserializer<'de>,
251{
252 #[derive(Deserialize)]
253 struct Wrapper(#[serde(deserialize_with = "fmt_id")] Id);
254 let v = Option::deserialize(deserializer)?;
255 match v.map(|Wrapper(a)| a) {
256 Some(unwrapped) => Ok(unwrapped),
257 None => Err(serde::de::Error::custom(
258 "empty node::Id from deserialization",
259 )),
260 }
261}
262
263pub fn deserialize_ids<'de, D>(deserializer: D) -> Result<Option<Vec<Id>>, D::Error>
266where
267 D: Deserializer<'de>,
268{
269 #[derive(Deserialize)]
270 struct Wrapper(#[serde(deserialize_with = "fmt_ids")] Vec<Id>);
271 let v = Option::deserialize(deserializer)?;
272 Ok(v.map(|Wrapper(a)| a))
273}
274
275pub fn must_deserialize_ids<'de, D>(deserializer: D) -> Result<Vec<Id>, D::Error>
279where
280 D: Deserializer<'de>,
281{
282 #[derive(Deserialize)]
283 struct Wrapper(#[serde(deserialize_with = "fmt_ids")] Vec<Id>);
284 let v = Option::deserialize(deserializer)?;
285 match v.map(|Wrapper(a)| a) {
286 Some(unwrapped) => Ok(unwrapped),
287 None => Err(serde::de::Error::custom("empty Ids from deserialization")),
288 }
289}
290
291fn fmt_ids<'de, D>(deserializer: D) -> Result<Vec<Id>, D::Error>
292where
293 D: serde::Deserializer<'de>,
294{
295 type Strings = Vec<String>;
296 let ss = Strings::deserialize(deserializer)?;
297 match ss
298 .iter()
299 .map(|x| x.parse::<Id>())
300 .collect::<Result<Vec<Id>, Error>>()
301 {
302 Ok(x) => Ok(x),
303 Err(e) => Err(serde::de::Error::custom(format!(
304 "failed to deserialize Ids {}",
305 e
306 ))),
307 }
308}
309
310#[test]
312fn test_serialize() {
313 let id = Id::from_slice(&<Vec<u8>>::from([
314 0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, ]));
317 assert_eq!(id.to_string(), "NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx");
318
319 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
320 struct Data {
321 id: Id,
322 id2: Option<Id>,
323 ids: Vec<Id>,
324 }
325 let d = Data {
326 id,
327 id2: Some(id),
328 ids: vec![id, id, id, id, id],
329 };
330
331 let yaml_encoded = serde_yaml::to_string(&d).unwrap();
332 assert!(yaml_encoded.contains("NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"));
333 let yaml_decoded = serde_yaml::from_str(&yaml_encoded).unwrap();
334 assert_eq!(d, yaml_decoded);
335
336 let json_encoded = serde_json::to_string(&d).unwrap();
337 assert!(json_encoded.contains("NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"));
338 let json_decoded = serde_json::from_str(&json_encoded).unwrap();
339 assert_eq!(d, json_decoded);
340}
341
342pub type Set = HashSet<Id>;
345
346pub fn new_set(size: usize) -> Set {
351 let set: HashSet<Id> = HashSet::with_capacity(size);
352 set
353}
354
355#[test]
357fn test_from_cert_file() {
358 let _ = env_logger::builder()
359 .filter_level(log::LevelFilter::Info)
360 .is_test(true)
361 .try_init();
362
363 let node_id = Id::from_slice(&<Vec<u8>>::from([
364 0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, ]));
367 assert_eq!(
368 format!("{}", node_id),
369 "NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"
370 );
371 assert_eq!(
372 node_id.to_string(),
373 "NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"
374 );
375 assert_eq!(
376 node_id.short_id().to_string(),
377 "6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"
378 );
379 assert_eq!(
380 node_id,
381 Id::from_str("6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx").unwrap()
382 );
383 assert_eq!(
384 node_id,
385 Id::from_str("NodeID-6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx").unwrap()
386 );
387
388 let node_id = Id::from_cert_pem_file("./artifacts/staker1.insecure.crt").unwrap();
391 assert_eq!(
392 format!("{}", node_id),
393 "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg"
394 );
395 assert_eq!(
396 node_id.to_string(),
397 "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg"
398 );
399 assert_eq!(
400 node_id,
401 Id::from_str("7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg").unwrap()
402 );
403 assert_eq!(
404 node_id,
405 Id::from_str("NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg").unwrap()
406 );
407
408 let node_id = Id::from_cert_pem_file("./artifacts/staker2.insecure.crt").unwrap();
409 assert_eq!(
410 format!("{}", node_id),
411 "NodeID-MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ"
412 );
413 assert_eq!(
414 node_id.to_string(),
415 "NodeID-MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ"
416 );
417 assert_eq!(
418 node_id,
419 Id::from_str("MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ").unwrap()
420 );
421 assert_eq!(
422 node_id,
423 Id::from_str("NodeID-MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ").unwrap()
424 );
425
426 let node_id = Id::from_cert_pem_file("./artifacts/staker3.insecure.crt").unwrap();
427 assert_eq!(
428 format!("{}", node_id),
429 "NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN"
430 );
431 assert_eq!(
432 node_id.to_string(),
433 "NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN"
434 );
435 assert_eq!(
436 node_id,
437 Id::from_str("NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN").unwrap()
438 );
439 assert_eq!(
440 node_id,
441 Id::from_str("NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN").unwrap()
442 );
443
444 let node_id = Id::from_cert_pem_file("./artifacts/staker4.insecure.crt").unwrap();
445 assert_eq!(
446 format!("{}", node_id),
447 "NodeID-GWPcbFJZFfZreETSoWjPimr846mXEKCtu"
448 );
449 assert_eq!(
450 node_id.to_string(),
451 "NodeID-GWPcbFJZFfZreETSoWjPimr846mXEKCtu"
452 );
453 assert_eq!(
454 node_id,
455 Id::from_str("GWPcbFJZFfZreETSoWjPimr846mXEKCtu").unwrap()
456 );
457 assert_eq!(
458 node_id,
459 Id::from_str("NodeID-GWPcbFJZFfZreETSoWjPimr846mXEKCtu").unwrap()
460 );
461
462 let node_id = Id::from_cert_pem_file("./artifacts/staker5.insecure.crt").unwrap();
463 assert_eq!(
464 format!("{}", node_id),
465 "NodeID-P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5"
466 );
467 assert_eq!(
468 node_id.to_string(),
469 "NodeID-P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5"
470 );
471 assert_eq!(
472 node_id,
473 Id::from_str("P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5").unwrap()
474 );
475 assert_eq!(
476 node_id,
477 Id::from_str("NodeID-P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5").unwrap()
478 );
479
480 let node_id = Id::from_cert_pem_file("./artifacts/test.insecure.crt").unwrap();
481 assert_eq!(
482 format!("{}", node_id),
483 "NodeID-29HTAG5cfN2fw79A67Jd5zY9drcT51EBG"
484 );
485 assert_eq!(
486 node_id.to_string(),
487 "NodeID-29HTAG5cfN2fw79A67Jd5zY9drcT51EBG"
488 );
489 assert_eq!(
490 node_id,
491 Id::from_str("29HTAG5cfN2fw79A67Jd5zY9drcT51EBG").unwrap()
492 );
493 assert_eq!(
494 node_id,
495 Id::from_str("NodeID-29HTAG5cfN2fw79A67Jd5zY9drcT51EBG").unwrap()
496 );
497}
498
499impl Ord for Id {
500 fn cmp(&self, other: &Id) -> Ordering {
501 self.0.cmp(&(other.0))
502 }
503}
504
505impl PartialOrd for Id {
506 fn partial_cmp(&self, other: &Id) -> Option<Ordering> {
507 Some(self.cmp(other))
508 }
509}
510
511impl PartialEq for Id {
512 fn eq(&self, other: &Id) -> bool {
513 self.cmp(other) == Ordering::Equal
514 }
515}
516
517impl Hash for Id {
519 fn hash<H: Hasher>(&self, state: &mut H) {
520 self.0.hash(state);
521 }
522}
523
524#[derive(Debug, Eq, Clone)]
525pub struct Ids(Vec<Id>);
526
527impl Ids {
528 pub fn new(ids: &[Id]) -> Self {
529 Ids(Vec::from(ids))
530 }
531}
532
533impl From<Vec<Id>> for Ids {
534 fn from(ids: Vec<Id>) -> Self {
535 Self::new(&ids)
536 }
537}
538
539impl Ord for Ids {
540 fn cmp(&self, other: &Ids) -> Ordering {
541 let l1 = self.0.len();
544 let l2 = other.0.len();
545 l1.cmp(&l2) .then_with(
547 || self.0.cmp(&other.0), )
549 }
550}
551
552impl PartialOrd for Ids {
553 fn partial_cmp(&self, other: &Ids) -> Option<Ordering> {
554 Some(self.cmp(other))
555 }
556}
557
558impl PartialEq for Ids {
559 fn eq(&self, other: &Ids) -> bool {
560 self.cmp(other) == Ordering::Equal
561 }
562}
563
564#[test]
566fn test_sort() {
567 let id1 = Id::from_slice(&<Vec<u8>>::from([
569 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00,
571 ]));
572 let id2 = Id::from_slice(&<Vec<u8>>::from([
573 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00,
575 ]));
576 assert!(id1 == id2);
577
578 let id1 = Id::from_slice(&<Vec<u8>>::from([
580 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00,
582 ]));
583 let id2 = Id::from_slice(&<Vec<u8>>::from([
584 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00,
586 ]));
587 assert!(id1 < id2);
588
589 let id1 = Id::from_slice(&<Vec<u8>>::from([
591 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00,
593 ]));
594 let id2 = Id::from_slice(&<Vec<u8>>::from([
595 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00,
597 ]));
598 assert!(id1 > id2);
599
600 let ids1 = Ids(vec![
602 Id::from_slice(&<Vec<u8>>::from([
603 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 ])),
606 Id::from_slice(&<Vec<u8>>::from([
607 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 ])),
610 Id::from_slice(&<Vec<u8>>::from([
611 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 ])),
614 ]);
615 let ids2 = Ids(vec![
616 Id::from_slice(&<Vec<u8>>::from([
617 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 ])),
620 Id::from_slice(&<Vec<u8>>::from([
621 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 ])),
624 Id::from_slice(&<Vec<u8>>::from([
625 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 ])),
628 ]);
629 assert!(ids1 == ids2);
630
631 let ids1 = Ids(vec![
633 Id::from_slice(&<Vec<u8>>::from([
634 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 ])),
637 Id::from_slice(&<Vec<u8>>::from([
638 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 ])),
641 Id::from_slice(&<Vec<u8>>::from([
642 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 ])),
645 ]);
646 let ids2 = Ids(vec![
647 Id::from_slice(&<Vec<u8>>::from([
648 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 ])),
651 Id::from_slice(&<Vec<u8>>::from([
652 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 ])),
655 Id::from_slice(&<Vec<u8>>::from([
656 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 ])),
659 Id::from_slice(&<Vec<u8>>::from([
660 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 ])),
663 ]);
664 assert!(ids1 < ids2);
665
666 let ids1 = Ids(vec![
668 Id::from_slice(&<Vec<u8>>::from([
669 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 ])),
672 Id::from_slice(&<Vec<u8>>::from([
673 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 ])),
676 Id::from_slice(&<Vec<u8>>::from([
677 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679 ])),
680 Id::from_slice(&<Vec<u8>>::from([
681 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 ])),
684 ]);
685 let ids2 = Ids(vec![
686 Id::from_slice(&<Vec<u8>>::from([
687 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 ])),
690 Id::from_slice(&<Vec<u8>>::from([
691 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 ])),
694 Id::from_slice(&<Vec<u8>>::from([
695 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 ])),
698 ]);
699 assert!(ids1 > ids2);
700
701 let ids1 = Ids(vec![
703 Id::from_slice(&<Vec<u8>>::from([
704 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 ])),
707 Id::from_slice(&<Vec<u8>>::from([
708 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 ])),
711 Id::from_slice(&<Vec<u8>>::from([
712 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 ])),
715 ]);
716 let ids2 = Ids(vec![
717 Id::from_slice(&<Vec<u8>>::from([
718 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 ])),
721 Id::from_slice(&<Vec<u8>>::from([
722 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 ])),
725 Id::from_slice(&<Vec<u8>>::from([
726 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 ])),
729 ]);
730 assert!(ids1 < ids2);
731
732 let mut ids1 = vec![
733 Id::from_slice(&<Vec<u8>>::from([
734 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736 ])),
737 Id::from_slice(&<Vec<u8>>::from([
738 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 ])),
741 Id::from_slice(&<Vec<u8>>::from([
742 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744 ])),
745 ];
746 ids1.sort();
747 let ids2 = vec![
748 Id::from_slice(&<Vec<u8>>::from([
749 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751 ])),
752 Id::from_slice(&<Vec<u8>>::from([
753 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 ])),
756 Id::from_slice(&<Vec<u8>>::from([
757 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
759 ])),
760 ];
761 assert!(ids1 == ids2);
762}