1use std::{
3 cmp::Ordering,
4 fmt,
5 hash::{Hash, Hasher},
6 io::{self, Error, ErrorKind},
7 str::FromStr,
8};
9
10use crate::{formatting, hash, key::secp256k1};
11use lazy_static::lazy_static;
12use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
13use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned};
14
15pub const LEN: usize = 20;
16
17lazy_static! {
18 static ref EMPTY: Vec<u8> = vec![0; LEN];
19}
20
21#[derive(Debug, Clone, Eq, AsBytes, FromZeroes, FromBytes, Unaligned)]
24#[repr(transparent)]
25pub struct Id([u8; LEN]);
26
27impl Default for Id {
28 fn default() -> Self {
29 Self::empty()
30 }
31}
32
33impl Id {
34 pub fn empty() -> Self {
35 Id([0; LEN])
36 }
37
38 pub fn is_empty(&self) -> bool {
39 (*self) == Self::empty()
40 }
41
42 pub fn from_slice(d: &[u8]) -> Self {
43 assert!(d.len() <= LEN);
44 let mut d: Vec<u8> = Vec::from(d);
45 if d.len() < LEN {
46 d.resize(LEN, 0);
47 }
48 let d: [u8; LEN] = d.try_into().unwrap();
49 Id(d)
50 }
51
52 pub fn from_public_key_bytes<S>(pub_key_bytes: S) -> io::Result<Self>
55 where
56 S: AsRef<[u8]>,
57 {
58 let hashed = hash::sha256_ripemd160(pub_key_bytes)?;
59
60 let encoded = formatting::encode_cb58_with_checksum_string(&hashed);
63 Self::from_str(&encoded)
64 }
65}
66
67impl AsRef<[u8]> for Id {
68 fn as_ref(&self) -> &[u8] {
69 &self.0
70 }
71}
72
73impl fmt::Display for Id {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 let s = formatting::encode_cb58_with_checksum_string(&self.0);
79 write!(f, "{}", s)
80 }
81}
82
83impl FromStr for Id {
85 type Err = Error;
86 fn from_str(s: &str) -> Result<Self, Self::Err> {
87 let decoded = formatting::decode_cb58_with_checksum(s.trim()).map_err(|e| {
89 Error::new(
90 ErrorKind::Other,
91 format!("failed decode_cb58_with_checksum '{}'", e),
92 )
93 })?;
94 Ok(Self::from_slice(&decoded))
95 }
96}
97
98impl Serialize for Id {
101 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
102 where
103 S: Serializer,
104 {
105 serializer.serialize_str(&self.to_string())
106 }
107}
108
109impl<'de> Deserialize<'de> for Id {
112 fn deserialize<D>(deserializer: D) -> Result<Id, D::Error>
113 where
114 D: Deserializer<'de>,
115 {
116 let s: String = Deserialize::deserialize(deserializer)?;
117 let ss: Vec<&str> = s.split('-').collect();
118 if ss.len() == 1 {
119 return Id::from_str(&s).map_err(serde::de::Error::custom);
120 }
121
122 let addr = ss[1];
123 let (_, short_bytes) = secp256k1::address::avax_address_to_short_bytes("", addr)
124 .map_err(serde::de::Error::custom)?;
125 Ok(Id::from_slice(&short_bytes))
126 }
127}
128
129fn fmt_id<'de, D>(deserializer: D) -> Result<Id, D::Error>
130where
131 D: Deserializer<'de>,
132{
133 let s = String::deserialize(deserializer)?;
134 Id::from_str(&s).map_err(serde::de::Error::custom)
135}
136
137pub fn deserialize_id<'de, D>(deserializer: D) -> Result<Option<Id>, D::Error>
140where
141 D: Deserializer<'de>,
142{
143 #[derive(Deserialize)]
144 struct Wrapper(#[serde(deserialize_with = "fmt_id")] Id);
145 let v = Option::deserialize(deserializer)?;
146 Ok(v.map(|Wrapper(a)| a))
147}
148
149pub fn must_deserialize_id<'de, D>(deserializer: D) -> Result<Id, D::Error>
153where
154 D: Deserializer<'de>,
155{
156 #[derive(Deserialize)]
157 struct Wrapper(#[serde(deserialize_with = "fmt_id")] Id);
158 let v = Option::deserialize(deserializer)?;
159 match v.map(|Wrapper(a)| a) {
160 Some(unwrapped) => Ok(unwrapped),
161 None => Err(serde::de::Error::custom(
162 "empty short::Id from deserialization",
163 )),
164 }
165}
166
167pub fn deserialize_ids<'de, D>(deserializer: D) -> Result<Option<Vec<Id>>, D::Error>
170where
171 D: Deserializer<'de>,
172{
173 #[derive(Deserialize)]
174 struct Wrapper(#[serde(deserialize_with = "fmt_ids")] Vec<Id>);
175 let v = Option::deserialize(deserializer)?;
176 Ok(v.map(|Wrapper(a)| a))
177}
178
179pub fn must_deserialize_ids<'de, D>(deserializer: D) -> Result<Vec<Id>, D::Error>
183where
184 D: Deserializer<'de>,
185{
186 #[derive(Deserialize)]
187 struct Wrapper(#[serde(deserialize_with = "fmt_ids")] Vec<Id>);
188 let v = Option::deserialize(deserializer)?;
189 match v.map(|Wrapper(a)| a) {
190 Some(unwrapped) => Ok(unwrapped),
191 None => Err(serde::de::Error::custom("empty Ids from deserialization")),
192 }
193}
194
195fn fmt_ids<'de, D>(deserializer: D) -> Result<Vec<Id>, D::Error>
196where
197 D: serde::Deserializer<'de>,
198{
199 type Strings = Vec<String>;
200 let ss = Strings::deserialize(deserializer)?;
201 match ss
202 .iter()
203 .map(|x| x.parse::<Id>())
204 .collect::<Result<Vec<Id>, Error>>()
205 {
206 Ok(x) => Ok(x),
207 Err(e) => Err(serde::de::Error::custom(format!(
208 "failed to deserialize Ids {}",
209 e
210 ))),
211 }
212}
213
214#[test]
216fn test_serialize() {
217 let id = Id::from_slice(&<Vec<u8>>::from([
218 0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, ]));
221 assert_eq!(id.to_string(), "6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx");
222
223 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
224 struct Data {
225 id: Id,
226 id2: Option<Id>,
227 ids: Vec<Id>,
228 }
229 let d = Data {
230 id: id.clone(),
231 id2: Some(id.clone()),
232 ids: vec![id.clone(), id.clone(), id.clone(), id.clone(), id.clone()],
233 };
234
235 let yaml_encoded = serde_yaml::to_string(&d).unwrap();
236 assert!(yaml_encoded.contains("6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"));
237 let yaml_decoded = serde_yaml::from_str(&yaml_encoded).unwrap();
238 assert_eq!(d, yaml_decoded);
239
240 let json_encoded = serde_json::to_string(&d).unwrap();
241 assert!(json_encoded.contains("6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx"));
242 let json_decoded = serde_json::from_str(&json_encoded).unwrap();
243 assert_eq!(d, json_decoded);
244
245 let pk = crate::key::secp256k1::private_key::Key::generate().unwrap();
246 let pubkey = pk.to_public_key();
247 let short_addr = pubkey.to_short_id().unwrap();
248 let p_addr = pubkey.to_hrp_address(1, "P").unwrap();
249
250 let d1: Data = serde_json::from_str(
251 format!(
252 "{{\"id\": \"{}\", \"ids\": [\"{}\", \"{}\"]}}",
253 short_addr, p_addr, p_addr
254 )
255 .as_str(),
256 )
257 .unwrap();
258 let d2 = Data {
259 id: short_addr.clone(),
260 id2: None,
261 ids: vec![short_addr.clone(), short_addr.clone()],
262 };
263 assert_eq!(d1, d2);
264
265 let id = Id::from_str("6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV").unwrap();
266 println!("{}", id);
267
268 let d: Data = serde_json::from_str("{\"id\": \"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV\", \"ids\": [\"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV\", \"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV\"]}")
269 .unwrap();
270 println!("{:?}", d);
271}
272
273#[test]
275fn test_id() {
276 let id = Id::from_slice(&<Vec<u8>>::from([
277 0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, ]));
280 assert_eq!(id.to_string(), "6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx");
281 let id_from_str = Id::from_str("6ZmBHXTqjknJoZtXbnJ6x7af863rXDTwx").unwrap();
282 assert_eq!(id, id_from_str);
283}
284
285impl Ord for Id {
286 fn cmp(&self, other: &Id) -> Ordering {
287 self.0.cmp(&(other.0))
288 }
289}
290
291impl PartialOrd for Id {
292 fn partial_cmp(&self, other: &Id) -> Option<Ordering> {
293 Some(self.cmp(other))
294 }
295}
296
297impl PartialEq for Id {
298 fn eq(&self, other: &Id) -> bool {
299 self.cmp(other) == Ordering::Equal
300 }
301}
302
303impl Hash for Id {
305 fn hash<H: Hasher>(&self, state: &mut H) {
306 self.0.hash(state);
307 }
308}
309
310#[derive(Debug, Eq, Clone)]
311pub struct Ids(Vec<Id>);
312
313impl Ids {
314 pub fn new(ids: &[Id]) -> Self {
315 Ids(Vec::from(ids))
316 }
317}
318
319impl From<Vec<Id>> for Ids {
320 fn from(ids: Vec<Id>) -> Self {
321 Self::new(&ids)
322 }
323}
324
325impl Ord for Ids {
326 fn cmp(&self, other: &Ids) -> Ordering {
327 let l1 = self.0.len();
330 let l2 = other.0.len();
331 l1.cmp(&l2) .then_with(
333 || self.0.cmp(&other.0), )
335 }
336}
337
338impl PartialOrd for Ids {
339 fn partial_cmp(&self, other: &Ids) -> Option<Ordering> {
340 Some(self.cmp(other))
341 }
342}
343
344impl PartialEq for Ids {
345 fn eq(&self, other: &Ids) -> bool {
346 self.cmp(other) == Ordering::Equal
347 }
348}
349
350#[test]
352fn test_sort() {
353 let id1 = Id::from_slice(&<Vec<u8>>::from([0x01, 0x00, 0x00, 0x00]));
355 let id2 = Id::from_slice(&<Vec<u8>>::from([0x01, 0x00, 0x00, 0x00, 0x00]));
356 assert!(id1 == id2);
357
358 let id1 = Id::from_slice(&<Vec<u8>>::from([0x01, 0x00, 0x00, 0x00, 0x00]));
360 let id2 = Id::from_slice(&<Vec<u8>>::from([0x02]));
361 assert!(id1 < id2);
362
363 let id1 = Id::from_slice(&<Vec<u8>>::from([0x02, 0x00, 0x00, 0x00, 0x00]));
365 let id2 = Id::from_slice(&<Vec<u8>>::from([0x01, 0x00, 0x00, 0x00, 0x00]));
366 assert!(id1 > id2);
367
368 let ids1 = Ids(vec![
370 Id::from_slice(&<Vec<u8>>::from([0x01])),
371 Id::from_slice(&<Vec<u8>>::from([0x02])),
372 Id::from_slice(&<Vec<u8>>::from([0x03])),
373 ]);
374 let ids2 = Ids(vec![
375 Id::from_slice(&<Vec<u8>>::from([0x01])),
376 Id::from_slice(&<Vec<u8>>::from([0x02])),
377 Id::from_slice(&<Vec<u8>>::from([0x03])),
378 ]);
379 assert!(ids1 == ids2);
380
381 let ids1 = Ids(vec![
383 Id::from_slice(&<Vec<u8>>::from([0x05])),
384 Id::from_slice(&<Vec<u8>>::from([0x06])),
385 Id::from_slice(&<Vec<u8>>::from([0x07])),
386 ]);
387 let ids2 = Ids(vec![
388 Id::from_slice(&<Vec<u8>>::from([0x01])),
389 Id::from_slice(&<Vec<u8>>::from([0x02])),
390 Id::from_slice(&<Vec<u8>>::from([0x03])),
391 Id::from_slice(&<Vec<u8>>::from([0x04])),
392 ]);
393 assert!(ids1 < ids2);
394
395 let ids1 = Ids(vec![
397 Id::from_slice(&<Vec<u8>>::from([0x01])),
398 Id::from_slice(&<Vec<u8>>::from([0x02])),
399 Id::from_slice(&<Vec<u8>>::from([0x03])),
400 Id::from_slice(&<Vec<u8>>::from([0x04])),
401 ]);
402 let ids2 = Ids(vec![
403 Id::from_slice(&<Vec<u8>>::from([0x09])),
404 Id::from_slice(&<Vec<u8>>::from([0x09])),
405 Id::from_slice(&<Vec<u8>>::from([0x09])),
406 ]);
407 assert!(ids1 > ids2);
408
409 let ids1 = Ids(vec![
411 Id::from_slice(&<Vec<u8>>::from([0x01])),
412 Id::from_slice(&<Vec<u8>>::from([0x02])),
413 Id::from_slice(&<Vec<u8>>::from([0x03])),
414 ]);
415 let ids2 = Ids(vec![
416 Id::from_slice(&<Vec<u8>>::from([0x01])),
417 Id::from_slice(&<Vec<u8>>::from([0x02])),
418 Id::from_slice(&<Vec<u8>>::from([0x05])),
419 ]);
420 assert!(ids1 < ids2);
421
422 let mut ids1 = vec![
423 Id::from_slice(&<Vec<u8>>::from([0x03])),
424 Id::from_slice(&<Vec<u8>>::from([0x02])),
425 Id::from_slice(&<Vec<u8>>::from([0x01])),
426 ];
427 ids1.sort();
428 let ids2 = vec![
429 Id::from_slice(&<Vec<u8>>::from([0x01])),
430 Id::from_slice(&<Vec<u8>>::from([0x02])),
431 Id::from_slice(&<Vec<u8>>::from([0x03])),
432 ];
433 assert!(ids1 == ids2);
434}