1use std::fmt;
4use std::marker::PhantomData;
5
6use serde::de::{Error as SerdeError, SeqAccess, Visitor};
7use serde::ser::SerializeSeq;
8use serde::{Deserialize, Serialize};
9use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};
10
11use crate::hash::{Hash, HashError};
12use crate::identity::{IdentityError, PrivateKey, PublicKey, Signature};
13use crate::operation::{Body, Header};
14
15pub fn serialize_hex<S>(value: &[u8], serializer: S) -> Result<S::Ok, S::Error>
18where
19 S: serde::Serializer,
20{
21 if serializer.is_human_readable() {
22 hex::serde::serialize(value, serializer)
23 } else {
24 SerdeBytes::new(value).serialize(serializer)
25 }
26}
27
28pub fn deserialize_hex<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
31where
32 D: serde::Deserializer<'de>,
33{
34 if deserializer.is_human_readable() {
35 hex::serde::deserialize(deserializer)
36 } else {
37 let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
38 Ok(bytes.to_vec())
39 }
40}
41
42impl Serialize for Hash {
43 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44 where
45 S: serde::Serializer,
46 {
47 serialize_hex(self.as_bytes(), serializer)
48 }
49}
50
51impl<'de> Deserialize<'de> for Hash {
52 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53 where
54 D: serde::Deserializer<'de>,
55 {
56 let bytes = deserialize_hex(deserializer)?;
57
58 bytes
59 .as_slice()
60 .try_into()
61 .map_err(|err: HashError| serde::de::Error::custom(err.to_string()))
62 }
63}
64
65impl Serialize for PrivateKey {
66 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67 where
68 S: serde::Serializer,
69 {
70 serialize_hex(self.as_bytes(), serializer)
71 }
72}
73
74impl<'de> Deserialize<'de> for PrivateKey {
75 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
76 where
77 D: serde::Deserializer<'de>,
78 {
79 let bytes = deserialize_hex(deserializer)?;
80
81 bytes
82 .as_slice()
83 .try_into()
84 .map_err(|err: IdentityError| serde::de::Error::custom(err.to_string()))
85 }
86}
87
88impl Serialize for PublicKey {
89 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
90 where
91 S: serde::Serializer,
92 {
93 serialize_hex(self.as_bytes(), serializer)
94 }
95}
96
97impl<'de> Deserialize<'de> for PublicKey {
98 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99 where
100 D: serde::Deserializer<'de>,
101 {
102 let bytes = deserialize_hex(deserializer)?;
103
104 bytes
105 .as_slice()
106 .try_into()
107 .map_err(|err: IdentityError| serde::de::Error::custom(err.to_string()))
108 }
109}
110
111impl Serialize for Signature {
112 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113 where
114 S: serde::Serializer,
115 {
116 serialize_hex(&self.to_bytes(), serializer)
117 }
118}
119
120impl<'de> Deserialize<'de> for Signature {
121 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
122 where
123 D: serde::Deserializer<'de>,
124 {
125 let bytes = deserialize_hex(deserializer)?;
126
127 bytes
128 .as_slice()
129 .try_into()
130 .map_err(|err: IdentityError| serde::de::Error::custom(err.to_string()))
131 }
132}
133
134impl<E> Serialize for Header<E>
135where
136 E: Serialize,
137{
138 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
139 where
140 S: serde::Serializer,
141 {
142 let mut seq = serializer.serialize_seq(Some(self.field_count()))?;
143 seq.serialize_element(&self.version)?;
144 seq.serialize_element(&self.public_key)?;
145
146 if let Some(signature) = &self.signature {
147 seq.serialize_element(signature)?;
148 }
149
150 seq.serialize_element(&self.payload_size)?;
151 if let Some(hash) = &self.payload_hash {
152 seq.serialize_element(&hash)?;
153 }
154
155 seq.serialize_element(&self.timestamp)?;
156 seq.serialize_element(&self.seq_num)?;
157
158 if let Some(backlink) = &self.backlink {
159 seq.serialize_element(backlink)?;
160 }
161
162 seq.serialize_element(&self.previous)?;
163
164 if let Some(extensions) = &self.extensions {
165 seq.serialize_element(extensions)?;
166 }
167
168 seq.end()
169 }
170}
171
172impl<'de, E> Deserialize<'de> for Header<E>
173where
174 E: Deserialize<'de>,
175{
176 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
177 where
178 D: serde::Deserializer<'de>,
179 {
180 struct HeaderVisitor<E> {
181 _marker: PhantomData<E>,
182 }
183
184 impl<'de, E> Visitor<'de> for HeaderVisitor<E>
185 where
186 E: Deserialize<'de>,
187 {
188 type Value = Header<E>;
189
190 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
191 formatter.write_str("Header encoded as a sequence")
192 }
193
194 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
195 where
196 A: SeqAccess<'de>,
197 {
198 let version: u64 = seq
199 .next_element()
200 .map_err(|_| SerdeError::custom("invalid version, expected u64"))?
201 .ok_or(SerdeError::custom("version missing"))?;
202
203 let public_key: PublicKey = seq
204 .next_element()
205 .map_err(|_| SerdeError::custom("invalid public key, expected bytes"))?
206 .ok_or(SerdeError::custom("public key missing"))?;
207
208 let signature: Signature = seq
209 .next_element()
210 .map_err(|_| SerdeError::custom("invalid signature, expected bytes"))?
211 .ok_or(SerdeError::custom("signature missing"))?;
212
213 let payload_size: u64 = seq
214 .next_element()
215 .map_err(|_| SerdeError::custom("invalid payload size, expected u64"))?
216 .ok_or(SerdeError::custom("payload size missing"))?;
217
218 let payload_hash: Option<Hash> = match payload_size {
219 0 => None,
220 _ => {
221 let hash: Hash = seq
222 .next_element()
223 .map_err(|_| {
224 SerdeError::custom("invalid payload hash, expected bytes")
225 })?
226 .ok_or(SerdeError::custom("payload hash missing"))?;
227 Some(hash)
228 }
229 };
230
231 let timestamp: u64 = seq
232 .next_element()
233 .map_err(|_| SerdeError::custom("invalid timestamp, expected u64"))?
234 .ok_or(SerdeError::custom("timestamp missing"))?;
235
236 let seq_num: u64 = seq
237 .next_element()
238 .map_err(|_| SerdeError::custom("invalid sequence number, expected u64"))?
239 .ok_or(SerdeError::custom("sequence number missing"))?;
240
241 let backlink: Option<Hash> = match seq_num {
242 0 => None,
243 _ => {
244 let hash: Hash = seq
245 .next_element()
246 .map_err(|err| {
247 SerdeError::custom(format!(
248 "invalid backlink, expected bytes {err}"
249 ))
250 })?
251 .ok_or(SerdeError::custom("backlink missing"))?;
252 Some(hash)
253 }
254 };
255
256 let previous: Vec<Hash> = seq
257 .next_element()
258 .map_err(|_| SerdeError::custom("invalid previous links, expected array"))?
259 .ok_or(SerdeError::custom("previous array missing"))?;
260
261 let extensions: Option<E> = seq
262 .next_element()
263 .map_err(|err| SerdeError::custom(format!("invalid extensions: {err}")))?;
264
265 Ok(Header {
266 version,
267 public_key,
268 signature: Some(signature),
269 payload_hash,
270 payload_size,
271 timestamp,
272 seq_num,
273 backlink,
274 previous,
275 extensions,
276 })
277 }
278 }
279
280 deserializer.deserialize_seq(HeaderVisitor::<E> {
281 _marker: PhantomData,
282 })
283 }
284}
285
286impl Serialize for Body {
287 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
288 where
289 S: serde::Serializer,
290 {
291 serialize_hex(&self.0, serializer)
292 }
293}
294
295impl<'de> Deserialize<'de> for Body {
296 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
297 where
298 D: serde::Deserializer<'de>,
299 {
300 let bytes = deserialize_hex(deserializer)?;
301 Ok(Body(bytes.to_vec()))
302 }
303}
304
305#[cfg(test)]
306mod tests {
307 use serde::de::DeserializeOwned;
308 use serde::{Deserialize, Serialize};
309
310 use crate::Body;
311 use crate::hash::Hash;
312 use crate::identity::{PrivateKey, PublicKey};
313 use crate::operation::Header;
314
315 use super::{deserialize_hex, serialize_hex};
316
317 #[derive(Debug, Serialize, Deserialize)]
318 struct Test(
319 #[serde(serialize_with = "serialize_hex", deserialize_with = "deserialize_hex")] Vec<u8>,
320 );
321
322 #[test]
323 fn serialize() {
324 let mut bytes: Vec<u8> = Vec::new();
325 let test = Test(vec![1, 2, 3]);
326
327 ciborium::ser::into_writer(&test, &mut bytes).unwrap();
330 assert_eq!(vec![67, 1, 2, 3], bytes);
331 }
332
333 #[test]
334 fn deserialize() {
335 let bytes: Vec<u8> = vec![67, 1, 2, 3];
336
337 let test: Test = ciborium::de::from_reader(&bytes[..]).unwrap();
340 assert_eq!(test.0, vec![1, 2, 3]);
341 }
342
343 #[test]
344 fn serialize_hash() {
345 let mut bytes: Vec<u8> = Vec::new();
347 let hash = Hash::new([1, 2, 3]);
348 ciborium::ser::into_writer(&hash, &mut bytes).unwrap();
349 assert_eq!(
350 bytes,
351 vec![
352 88, 32, 177, 119, 236, 27, 242, 109, 251, 59, 112, 16, 212, 115, 230, 212, 71, 19,
353 178, 155, 118, 91, 153, 198, 230, 14, 203, 250, 231, 66, 222, 73, 101, 67
354 ]
355 );
356
357 let json = serde_json::to_string(&hash).unwrap();
359 assert_eq!(
360 json,
361 "\"b177ec1bf26dfb3b7010d473e6d44713b29b765b99c6e60ecbfae742de496543\""
362 );
363 }
364
365 #[test]
366 fn deserialize_hash() {
367 let bytes = [
369 88, 32, 177, 119, 236, 27, 242, 109, 251, 59, 112, 16, 212, 115, 230, 212, 71, 19, 178,
370 155, 118, 91, 153, 198, 230, 14, 203, 250, 231, 66, 222, 73, 101, 67,
371 ];
372 let hash: Hash = ciborium::de::from_reader(&bytes[..]).unwrap();
373 assert_eq!(hash, Hash::new([1, 2, 3]));
374
375 let json = "\"b177ec1bf26dfb3b7010d473e6d44713b29b765b99c6e60ecbfae742de496543\"";
377 let hash: Hash = serde_json::from_str(json).unwrap();
378 assert_eq!(hash, Hash::new([1, 2, 3]));
379 }
380
381 #[test]
382 fn serialize_public_key() {
383 let mut bytes: Vec<u8> = Vec::new();
385 let public_key = PublicKey::from_bytes(&[
386 215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58, 14, 225, 114,
387 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26,
388 ])
389 .unwrap();
390 ciborium::ser::into_writer(&public_key, &mut bytes).unwrap();
391 assert_eq!(
392 bytes,
393 vec![
394 88, 32, 215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58, 14,
395 225, 114, 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26,
396 ]
397 );
398
399 let json = serde_json::to_string(&public_key).unwrap();
401 assert_eq!(
402 json,
403 "\"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\""
404 );
405 }
406
407 fn assert_serde_roundtrip<
408 E: Clone + std::fmt::Debug + PartialEq + Serialize + DeserializeOwned,
409 >(
410 mut header: Header<E>,
411 private_key: &PrivateKey,
412 ) {
413 header.sign(private_key);
414
415 let mut bytes = Vec::new();
416 ciborium::ser::into_writer(&header, &mut bytes).unwrap();
417 let header_again: Header<E> = ciborium::de::from_reader(&bytes[..]).unwrap();
418 assert_eq!(header, header_again);
419 }
420
421 #[test]
422 fn serde_roundtrip_operations() {
423 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
424 struct CustomExtensions {
425 custom_field: u64,
426 }
427
428 let extensions = CustomExtensions { custom_field: 12 };
429 let private_key = PrivateKey::new();
430
431 assert_serde_roundtrip(
432 Header::<CustomExtensions> {
433 version: 1,
434 public_key: private_key.public_key(),
435 payload_size: 123,
436 payload_hash: Some(Hash::new(vec![1, 2, 3])),
437 timestamp: 0,
438 seq_num: 0,
439 backlink: None,
440 previous: vec![],
441 extensions: Some(extensions.clone()),
442 signature: None,
443 },
444 &private_key,
445 );
446
447 assert_serde_roundtrip(
448 Header::<CustomExtensions> {
449 version: 1,
450 public_key: private_key.public_key(),
451 payload_size: 0,
452 payload_hash: None,
453 timestamp: 0,
454 seq_num: 7,
455 backlink: Some(Hash::new(vec![1, 2, 3])),
456 previous: vec![],
457 extensions: None,
458 signature: None,
459 },
460 &private_key,
461 );
462
463 assert_serde_roundtrip(
464 Header::<CustomExtensions> {
465 version: 1,
466 public_key: private_key.public_key(),
467 payload_size: 0,
468 payload_hash: None,
469 timestamp: 0,
470 seq_num: 0,
471 backlink: None,
472 previous: vec![],
473 extensions: Some(extensions),
474 signature: None,
475 },
476 &private_key,
477 );
478 }
479
480 #[test]
481 fn expected_de_error() {
482 let private_key = PrivateKey::new();
483
484 let mut header = Header::<()> {
486 version: 1,
487 public_key: private_key.public_key(),
488 signature: None,
489 payload_size: 2829099,
490 payload_hash: None,
491 timestamp: 0,
492 seq_num: 0,
493 backlink: None,
494 previous: vec![],
495 extensions: None,
496 };
497 header.sign(&private_key);
498
499 let result = ciborium::de::from_reader::<Header<()>, _>(&header.to_bytes()[..]);
500 assert!(result.is_err());
501
502 let mut header = Header::<()> {
504 version: 1,
505 public_key: private_key.public_key(),
506 signature: None,
507 payload_size: 0,
508 payload_hash: Some(Hash::new([0, 1, 2])),
509 timestamp: 0,
510 seq_num: 0,
511 backlink: None,
512 previous: vec![],
513 extensions: None,
514 };
515 header.sign(&private_key);
516
517 let result = ciborium::de::from_reader::<Header<()>, _>(&header.to_bytes()[..]);
518 assert!(result.is_err());
519
520 let mut header = Header::<()> {
522 version: 1,
523 public_key: private_key.public_key(),
524 signature: None,
525 payload_size: 0,
526 payload_hash: None,
527 timestamp: 0,
528 seq_num: 0,
529 backlink: Some(Hash::new([0, 1, 2])),
530 previous: vec![],
531 extensions: None,
532 };
533 header.sign(&private_key);
534
535 let result = ciborium::de::from_reader::<Header<()>, _>(&header.to_bytes()[..]);
536 assert!(result.is_err());
537
538 let mut header = Header::<()> {
540 version: 1,
541 public_key: private_key.public_key(),
542 signature: None,
543 payload_size: 0,
544 payload_hash: None,
545 timestamp: 0,
546 seq_num: 10,
547 backlink: None,
548 previous: vec![],
549 extensions: None,
550 };
551 header.sign(&private_key);
552
553 let result = ciborium::de::from_reader::<Header<()>, _>(&header.to_bytes()[..]);
554 assert!(result.is_err());
555 }
556
557 #[test]
558 fn serde_header_with_other_types() {
559 let private_key = PrivateKey::new();
560
561 #[derive(Debug, PartialEq, Serialize, Deserialize)]
562 struct Message {
563 header: Header<()>,
564 body: Body,
565 }
566
567 let body = Body::new(b"hello");
568 let mut header = Header::<()> {
569 version: 1,
570 public_key: private_key.public_key(),
571 signature: None,
572 payload_size: body.size(),
573 payload_hash: Some(body.hash()),
574 timestamp: 0,
575 seq_num: 0,
576 backlink: None,
577 previous: vec![],
578 extensions: Some(()),
579 };
580 header.sign(&private_key);
581
582 let message = Message { header, body };
583
584 let mut bytes = Vec::new();
585 ciborium::ser::into_writer(&message, &mut bytes).unwrap();
586
587 let message_again: Message = ciborium::de::from_reader(&bytes[..]).unwrap();
588 assert_eq!(message_again, message);
589 }
590
591 #[test]
592 fn fixtures() {
593 let private_key = PrivateKey::from_bytes(&[
594 244, 123, 85, 215, 161, 204, 94, 227, 239, 253, 128, 164, 228, 160, 195, 49, 18, 49,
595 125, 4, 50, 218, 157, 230, 174, 1, 154, 231, 231, 142, 22, 170,
596 ]);
597
598 let mut header_0 = Header::<()> {
600 version: 1,
601 public_key: private_key.public_key(),
602 signature: None,
603 payload_size: 0,
604 payload_hash: None,
605 timestamp: 0,
606 seq_num: 0,
607 backlink: None,
608 previous: vec![],
609 extensions: None,
610 };
611 header_0.sign(&private_key);
612
613 let bytes = [
614 135, 1, 88, 32, 228, 21, 196, 25, 12, 199, 241, 100, 122, 89, 46, 191, 142, 95, 144,
615 92, 42, 222, 249, 148, 139, 23, 91, 43, 92, 17, 225, 69, 17, 181, 22, 32, 88, 64, 236,
616 140, 222, 102, 249, 241, 106, 139, 172, 229, 41, 251, 225, 80, 131, 152, 32, 3, 65, 66,
617 78, 147, 22, 63, 117, 6, 187, 67, 219, 211, 108, 67, 96, 93, 226, 195, 245, 31, 13,
618 210, 38, 69, 36, 169, 206, 226, 39, 84, 140, 134, 144, 82, 135, 22, 67, 105, 151, 86,
619 210, 218, 224, 226, 24, 1, 0, 0, 0, 128,
620 ];
621
622 let header_again: Header<()> = ciborium::de::from_reader(&bytes[..]).unwrap();
623 assert_eq!(header_0, header_again);
624
625 let mut header_0_with_previous = Header::<()> {
627 version: 1,
628 public_key: private_key.public_key(),
629 signature: None,
630 payload_size: 0,
631 payload_hash: None,
632 timestamp: 0,
633 seq_num: 0,
634 backlink: None,
635 previous: vec![header_0.hash()],
636 extensions: None,
637 };
638 header_0_with_previous.sign(&private_key);
639
640 let bytes = [
641 135, 1, 88, 32, 228, 21, 196, 25, 12, 199, 241, 100, 122, 89, 46, 191, 142, 95, 144,
642 92, 42, 222, 249, 148, 139, 23, 91, 43, 92, 17, 225, 69, 17, 181, 22, 32, 88, 64, 65,
643 92, 162, 134, 52, 87, 188, 189, 159, 226, 209, 206, 173, 214, 240, 66, 236, 31, 151,
644 62, 158, 142, 15, 151, 104, 166, 213, 67, 215, 217, 184, 59, 101, 152, 87, 33, 196,
645 244, 111, 6, 235, 1, 66, 80, 60, 176, 22, 122, 141, 37, 137, 162, 48, 163, 147, 129,
646 147, 111, 19, 44, 69, 161, 6, 0, 0, 0, 0, 129, 88, 32, 95, 99, 215, 154, 144, 67, 138,
647 175, 143, 217, 30, 137, 81, 72, 104, 86, 247, 197, 178, 18, 179, 107, 250, 53, 138, 91,
648 67, 19, 45, 184, 29, 3,
649 ];
650
651 let header_again: Header<()> = ciborium::de::from_reader(&bytes[..]).unwrap();
652 assert_eq!(header_0_with_previous, header_again);
653
654 let body = Body::new("Hello, Sloth!".as_bytes());
656 let mut header_0_with_previous_and_body = Header::<()> {
657 version: 1,
658 public_key: private_key.public_key(),
659 signature: None,
660 payload_size: body.size(),
661 payload_hash: Some(body.hash()),
662 timestamp: 0,
663 seq_num: 0,
664 backlink: None,
665 previous: vec![header_0.hash()],
666 extensions: None,
667 };
668 header_0_with_previous_and_body.sign(&private_key);
669
670 let bytes = [
671 136, 1, 88, 32, 228, 21, 196, 25, 12, 199, 241, 100, 122, 89, 46, 191, 142, 95, 144,
672 92, 42, 222, 249, 148, 139, 23, 91, 43, 92, 17, 225, 69, 17, 181, 22, 32, 88, 64, 96,
673 254, 49, 186, 42, 116, 23, 226, 237, 229, 125, 86, 191, 230, 3, 76, 18, 56, 97, 17, 52,
674 29, 220, 233, 28, 185, 86, 106, 59, 42, 48, 40, 104, 231, 35, 175, 167, 182, 31, 53,
675 146, 35, 26, 96, 141, 93, 133, 41, 129, 42, 69, 23, 41, 182, 162, 120, 57, 197, 16,
676 207, 32, 6, 50, 13, 13, 88, 32, 191, 127, 68, 13, 227, 43, 252, 155, 49, 148, 176, 2,
677 162, 217, 175, 171, 49, 44, 181, 215, 71, 113, 211, 195, 29, 128, 192, 169, 5, 138,
678 160, 142, 0, 0, 129, 88, 32, 95, 99, 215, 154, 144, 67, 138, 175, 143, 217, 30, 137,
679 81, 72, 104, 86, 247, 197, 178, 18, 179, 107, 250, 53, 138, 91, 67, 19, 45, 184, 29, 3,
680 ];
681
682 let header_again: Header<()> = ciborium::de::from_reader(&bytes[..]).unwrap();
683 assert_eq!(header_0_with_previous_and_body, header_again);
684
685 let mut header_1 = Header::<()> {
687 version: 1,
688 public_key: private_key.public_key(),
689 signature: None,
690 payload_size: 0,
691 payload_hash: None,
692 timestamp: 0,
693 seq_num: 1,
694 backlink: Some(header_0.hash()),
695 previous: vec![],
696 extensions: None,
697 };
698 header_1.sign(&private_key);
699
700 let bytes = [
701 136, 1, 88, 32, 228, 21, 196, 25, 12, 199, 241, 100, 122, 89, 46, 191, 142, 95, 144,
702 92, 42, 222, 249, 148, 139, 23, 91, 43, 92, 17, 225, 69, 17, 181, 22, 32, 88, 64, 93,
703 12, 126, 212, 51, 167, 3, 55, 23, 145, 132, 176, 119, 142, 188, 118, 103, 201, 71, 181,
704 40, 110, 65, 132, 38, 183, 145, 3, 190, 215, 30, 33, 173, 44, 208, 46, 244, 163, 217,
705 74, 57, 164, 220, 11, 71, 152, 84, 243, 201, 145, 249, 150, 164, 139, 21, 208, 124, 30,
706 19, 119, 131, 39, 12, 5, 0, 0, 1, 88, 32, 95, 99, 215, 154, 144, 67, 138, 175, 143,
707 217, 30, 137, 81, 72, 104, 86, 247, 197, 178, 18, 179, 107, 250, 53, 138, 91, 67, 19,
708 45, 184, 29, 3, 128,
709 ];
710
711 let header_again: Header<()> = ciborium::de::from_reader(&bytes[..]).unwrap();
712 assert_eq!(header_1, header_again);
713
714 let mut header_1_with_previous = Header::<()> {
716 version: 1,
717 public_key: private_key.public_key(),
718 signature: None,
719 payload_size: 0,
720 payload_hash: None,
721 timestamp: 0,
722 seq_num: 1,
723 backlink: Some(header_0.hash()),
724 previous: vec![header_0.hash()],
725 extensions: None,
726 };
727 header_1_with_previous.sign(&private_key);
728
729 let bytes = [
730 136, 1, 88, 32, 228, 21, 196, 25, 12, 199, 241, 100, 122, 89, 46, 191, 142, 95, 144,
731 92, 42, 222, 249, 148, 139, 23, 91, 43, 92, 17, 225, 69, 17, 181, 22, 32, 88, 64, 16,
732 29, 23, 76, 210, 71, 14, 49, 42, 176, 10, 234, 112, 50, 120, 23, 96, 105, 110, 31, 183,
733 113, 127, 31, 56, 244, 144, 159, 66, 242, 179, 154, 245, 40, 70, 185, 145, 150, 10, 32,
734 14, 141, 78, 144, 28, 19, 247, 2, 27, 181, 182, 115, 153, 225, 115, 74, 106, 150, 78,
735 117, 15, 149, 61, 5, 0, 0, 1, 88, 32, 95, 99, 215, 154, 144, 67, 138, 175, 143, 217,
736 30, 137, 81, 72, 104, 86, 247, 197, 178, 18, 179, 107, 250, 53, 138, 91, 67, 19, 45,
737 184, 29, 3, 129, 88, 32, 95, 99, 215, 154, 144, 67, 138, 175, 143, 217, 30, 137, 81,
738 72, 104, 86, 247, 197, 178, 18, 179, 107, 250, 53, 138, 91, 67, 19, 45, 184, 29, 3,
739 ];
740
741 let header_again: Header<()> = ciborium::de::from_reader(&bytes[..]).unwrap();
742 assert_eq!(header_1_with_previous, header_again);
743 }
744
745 #[test]
746 fn decode_non_map_extensions() {
747 let private_key = PrivateKey::new();
748
749 let mut header = Header::<()> {
750 version: 1,
751 public_key: private_key.public_key(),
752 signature: None,
753 payload_size: 0,
754 payload_hash: None,
755 timestamp: 0,
756 seq_num: 0,
757 backlink: None,
758 previous: vec![],
759 extensions: None,
760 };
761 header.sign(&private_key);
762
763 let result = ciborium::de::from_reader::<Header<()>, _>(&header.to_bytes()[..]);
764 assert!(result.is_ok());
765 }
766}