1use std::borrow::Cow;
7use std::{fmt, io, mem};
8
9use bitcoin::hashes::{sha256, Hash};
10use bitcoin::secp256k1::{self, schnorr, PublicKey, XOnlyPublicKey};
14use secp256k1_musig::musig;
15
16
17pub const MAX_VEC_SIZE: usize = 4_000_000;
19
20pub const MAX_SCRIPT_PUBKEY_SIZE: usize = 100;
22
23#[derive(Debug, thiserror::Error)]
25pub enum ProtocolDecodingError {
26 #[error("I/O error: {0}")]
27 Io(#[from] io::Error),
28 #[error("invalid protocol encoding: {message}")]
29 Invalid {
30 message: String,
31 #[source]
32 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
33 },
34 #[error("{0}")]
35 OversizedVector(#[from] OversizedVectorError),
36}
37
38impl ProtocolDecodingError {
39 pub fn invalid(message: impl fmt::Display) -> Self {
41 Self::Invalid {
42 message: message.to_string(),
43 source: None,
44 }
45 }
46
47 pub fn invalid_err<E>(source: E, message: impl fmt::Display) -> Self
49 where
50 E: std::error::Error + Send + Sync + 'static,
51 {
52 Self::Invalid {
53 message: message.to_string(),
54 source: Some(Box::new(source)),
55 }
56 }
57}
58
59impl From<bitcoin::consensus::encode::Error> for ProtocolDecodingError {
60 fn from(e: bitcoin::consensus::encode::Error) -> Self {
61 match e {
62 bitcoin::consensus::encode::Error::Io(e) => Self::Io(e.into()),
63 e => Self::invalid_err(e, "bitcoin protocol decoding error"),
64 }
65 }
66}
67
68impl From<bitcoin::io::Error> for ProtocolDecodingError {
69 fn from(e: bitcoin::io::Error) -> Self {
70 Self::Io(e.into())
71 }
72}
73
74pub trait ProtocolEncoding: Sized {
76 fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error>;
79
80 fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, ProtocolDecodingError>;
82
83 fn serialize(&self) -> Vec<u8> {
85 let mut buf = Vec::new();
86 self.encode(&mut buf).expect("buffers don't produce I/O errors");
87 buf
88 }
89
90 fn deserialize(mut byte_slice: &[u8]) -> Result<Self, ProtocolDecodingError> {
92 let ret = Self::decode(&mut byte_slice)?;
93 if byte_slice.is_empty() {
94 Ok(ret)
95 } else {
96 Err(ProtocolDecodingError::invalid("trailing bytes"))
97 }
98 }
99
100 fn serialize_hex(&self) -> String {
102 use hex_conservative::Case::Lower;
103 let mut buf = String::new();
104 let mut writer = hex_conservative::display::HexWriter::new(&mut buf, Lower);
105 self.encode(&mut writer).expect("no I/O errors for buffers");
106 buf
107 }
108
109 fn deserialize_hex(hex_str: &str) -> Result<Self, ProtocolDecodingError> {
111 let mut iter = hex_conservative::HexToBytesIter::new(hex_str).map_err(|e| {
112 ProtocolDecodingError::Io(io::Error::new(io::ErrorKind::InvalidData, e))
113 })?;
114 let ret = Self::decode(&mut iter)?;
115 if iter.next().is_none() {
116 Ok(ret)
117 } else {
118 Err(ProtocolDecodingError::invalid("trailing bytes"))
119 }
120 }
121}
122
123pub trait WriteExt: io::Write {
125 fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> {
127 self.write_all(&v.to_le_bytes())
128 }
129
130 fn emit_u16(&mut self, v: u16) -> Result<(), io::Error> {
132 self.write_all(&v.to_le_bytes())
133 }
134
135 fn emit_u32(&mut self, v: u32) -> Result<(), io::Error> {
137 self.write_all(&v.to_le_bytes())
138 }
139
140 fn emit_u64(&mut self, v: u64) -> Result<(), io::Error> {
142 self.write_all(&v.to_le_bytes())
143 }
144
145 fn emit_slice(&mut self, slice: &[u8]) -> Result<(), io::Error> {
147 self.write_all(slice)
148 }
149
150 fn emit_compact_size(&mut self, value: impl Into<u64>) -> Result<usize, io::Error> {
152 let value = value.into();
153 match value {
154 0..=0xFC => {
155 self.emit_u8(value as u8)?;
156 Ok(1)
157 },
158 0xFD..=0xFFFF => {
159 self.emit_u8(0xFD)?;
160 self.emit_u16(value as u16)?;
161 Ok(3)
162 },
163 0x10000..=0xFFFFFFFF => {
164 self.emit_u8(0xFE)?;
165 self.emit_u32(value as u32)?;
166 Ok(5)
167 },
168 _ => {
169 self.emit_u8(0xFF)?;
170 self.emit_u64(value)?;
171 Ok(9)
172 },
173 }
174 }
175}
176
177impl<W: io::Write + ?Sized> WriteExt for W {}
178
179pub trait ReadExt: io::Read {
181 fn read_u8(&mut self) -> Result<u8, io::Error> {
183 let mut buf = [0; 1];
184 self.read_exact(&mut buf[..])?;
185 Ok(u8::from_le_bytes(buf))
186 }
187
188 fn read_u16(&mut self) -> Result<u16, io::Error> {
190 let mut buf = [0; 2];
191 self.read_exact(&mut buf[..])?;
192 Ok(u16::from_le_bytes(buf))
193 }
194
195 fn read_u32(&mut self) -> Result<u32, io::Error> {
197 let mut buf = [0; 4];
198 self.read_exact(&mut buf[..])?;
199 Ok(u32::from_le_bytes(buf))
200 }
201
202 fn read_u64(&mut self) -> Result<u64, io::Error> {
204 let mut buf = [0; 8];
205 self.read_exact(&mut buf[..])?;
206 Ok(u64::from_le_bytes(buf))
207 }
208
209 fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), io::Error> {
211 self.read_exact(slice)
212 }
213
214 fn read_byte_array<const N: usize>(&mut self) -> Result<[u8; N], io::Error> {
216 let mut ret = [0u8; N];
217 self.read_exact(&mut ret)?;
218 Ok(ret)
219 }
220
221 fn read_compact_size(&mut self) -> Result<u64, io::Error> {
223 match self.read_u8()? {
224 0xFF => {
225 let x = self.read_u64()?;
226 if x < 0x1_0000_0000 { Err(io::Error::new(io::ErrorKind::InvalidData, "non-minimal varint"))
228 } else {
229 Ok(x)
230 }
231 },
232 0xFE => {
233 let x = self.read_u32()?;
234 if x < 0x1_0000 { Err(io::Error::new(io::ErrorKind::InvalidData, "non-minimal varint"))
236 } else {
237 Ok(x as u64)
238 }
239 },
240 0xFD => {
241 let x = self.read_u16()?;
242 if x < 0xFD { Err(io::Error::new(io::ErrorKind::InvalidData, "non-minimal varint"))
244 } else {
245 Ok(x as u64)
246 }
247 },
248 n => Ok(n as u64),
249 }
250 }
251}
252
253impl<R: io::Read + ?Sized> ReadExt for R {}
254
255
256impl ProtocolEncoding for PublicKey {
257 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
258 w.emit_slice(&self.serialize())
259 }
260
261 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
262 let mut buf = [0; secp256k1::constants::PUBLIC_KEY_SIZE];
263 r.read_slice(&mut buf[..])?;
264 PublicKey::from_slice(&buf).map_err(|e| {
265 ProtocolDecodingError::invalid_err(e, "invalid public key")
266 })
267 }
268}
269
270impl ProtocolEncoding for XOnlyPublicKey {
271 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
272 w.emit_slice(&self.serialize())
273 }
274
275 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
276 let mut buf = [0; 32];
277 r.read_slice(&mut buf[..])?;
278 XOnlyPublicKey::from_slice(&buf).map_err(|e| {
279 ProtocolDecodingError::invalid_err(e, "invalid x-only public key")
280 })
281 }
282}
283
284impl ProtocolEncoding for Option<sha256::Hash> {
285 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
286 if let Some(h) = self {
287 w.emit_u8(1)?;
288 w.emit_slice(&h.as_byte_array()[..])
289 } else {
290 w.emit_u8(0)
291 }
292 }
293
294 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
295 let first = r.read_u8()?;
296 if first == 0 {
297 Ok(None)
298 } else if first == 1 {
299 let mut buf = [0u8; 32];
300 r.read_slice(&mut buf)?;
301 Ok(Some(sha256::Hash::from_byte_array(buf)))
302 } else {
303 Err(ProtocolDecodingError::invalid("invalid optional hash prefix byte"))
304 }
305 }
306}
307
308impl ProtocolEncoding for Option<PublicKey> {
309 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
310 if let Some(pk) = self {
311 w.emit_slice(&pk.serialize())
312 } else {
313 w.emit_u8(0)
314 }
315 }
316
317 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
318 let first = r.read_u8()?;
319 if first == 0 {
320 Ok(None)
321 } else {
322 let mut pk = [first; secp256k1::constants::PUBLIC_KEY_SIZE];
323 r.read_slice(&mut pk[1..])?;
324 Ok(Some(PublicKey::from_slice(&pk).map_err(|e| {
325 ProtocolDecodingError::invalid_err(e, "invalid public key")
326 })?))
327 }
328 }
329}
330
331impl ProtocolEncoding for schnorr::Signature {
332 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
333 w.emit_slice(&self.serialize())
334 }
335
336 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
337 let mut buf = [0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE];
338 r.read_slice(&mut buf[..])?;
339 schnorr::Signature::from_slice(&buf).map_err(|e| {
340 ProtocolDecodingError::invalid_err(e, "invalid schnorr signature")
341 })
342 }
343}
344
345impl ProtocolEncoding for Option<schnorr::Signature> {
346 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
347 if let Some(sig) = self {
348 w.emit_slice(&sig.serialize())
349 } else {
350 w.emit_slice(&[0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE])
351 }
352 }
353
354 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
355 let mut buf = [0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE];
356 r.read_slice(&mut buf[..])?;
357 if buf == [0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE] {
358 Ok(None)
359 } else {
360 Ok(Some(schnorr::Signature::from_slice(&buf).map_err(|e| {
361 ProtocolDecodingError::invalid_err(e, "invalid schnorr signature")
362 })?))
363 }
364 }
365}
366
367impl ProtocolEncoding for sha256::Hash {
368 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
369 w.emit_slice(&self[..])
370 }
371
372 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
373 let mut buf = [0; sha256::Hash::LEN];
374 r.read_exact(&mut buf[..])?;
375 Ok(sha256::Hash::from_byte_array(buf))
376 }
377}
378
379impl ProtocolEncoding for musig::PublicNonce {
380 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
381 w.emit_slice(&self.serialize())
382 }
383 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
384 Ok(Self::from_byte_array(&r.read_byte_array()?).map_err(|e| {
385 ProtocolDecodingError::invalid_err(e, "invalid musig public nonce")
386 })?)
387 }
388}
389
390impl ProtocolEncoding for musig::PartialSignature {
391 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
392 w.emit_slice(&self.serialize())
393 }
394 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
395 Ok(Self::from_byte_array(&r.read_byte_array()?).map_err(|e| {
396 ProtocolDecodingError::invalid_err(e, "invalid musig public nonce")
397 })?)
398 }
399}
400
401macro_rules! impl_bitcoin_encode {
404 ($name:ty) => {
405 impl ProtocolEncoding for $name {
406 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
407 let mut wrapped = bitcoin::io::FromStd::new(w);
408 bitcoin::consensus::Encodable::consensus_encode(self, &mut wrapped)?;
409 Ok(())
410 }
411
412 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
413 let mut wrapped = bitcoin::io::FromStd::new(r);
414 let ret = bitcoin::consensus::Decodable::consensus_decode(&mut wrapped)?;
415 Ok(ret)
416 }
417 }
418 };
419}
420
421impl_bitcoin_encode!(bitcoin::BlockHash);
422impl_bitcoin_encode!(bitcoin::OutPoint);
423
424impl ProtocolEncoding for bitcoin::TxOut {
425 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
426 let mut wrapped = bitcoin::io::FromStd::new(w);
427 bitcoin::consensus::Encodable::consensus_encode(self, &mut wrapped)?;
428 Ok(())
429 }
430
431 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
432 use bitcoin::consensus::Decodable;
433
434 let mut wrapped = bitcoin::io::FromStd::new(r);
435 let ret = bitcoin::TxOut::consensus_decode(&mut wrapped)?;
436 if ret.script_pubkey.len() > MAX_SCRIPT_PUBKEY_SIZE {
437 return Err(ProtocolDecodingError::invalid("oversized output scriptPubkey"));
438 }
439 Ok(ret)
440 }
441}
442
443impl ProtocolEncoding for bitcoin::taproot::TapTweakHash {
444 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
445 w.emit_slice(&self.to_byte_array())
446 }
447
448 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
449 Ok(Self::from_byte_array(r.read_byte_array().map_err(|e| {
450 ProtocolDecodingError::invalid_err(e, "TapTweakHash must be 32 bytes")
451 })?))
452 }
453}
454
455impl<'a, T: ProtocolEncoding + Clone> ProtocolEncoding for Cow<'a, T> {
456 fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
457 ProtocolEncoding::encode(self.as_ref(), writer)
458 }
459
460 fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, ProtocolDecodingError> {
461 Ok(Cow::Owned(ProtocolEncoding::decode(reader)?))
462 }
463}
464
465#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
466#[error("requested to allocate a vector above our limit: requested={requested}, max={max}")]
467pub struct OversizedVectorError {
468 pub requested: usize,
470 pub max: usize,
472}
473
474impl OversizedVectorError {
475 pub fn check<T>(requested: usize) -> Result<(), Self> {
477 assert_ne!(mem::size_of::<T>(), 0, "cannot serialize vectors of empty types");
478 let max = MAX_VEC_SIZE.checked_div(mem::size_of::<T>())
479 .expect("size_of always > 0 for instantiable T");
480 if requested > max {
481 Err(Self { requested, max })
482 } else {
483 Ok(())
484 }
485 }
486}
487
488#[derive(Debug, Clone)]
493pub struct LengthPrefixedVector<'a, T: Clone> {
494 inner: Cow<'a, [T]>,
495}
496
497impl<'a, T: Clone> LengthPrefixedVector<'a, T> {
498 pub fn new(buf: &'a [T]) -> Self {
500 Self { inner: Cow::Borrowed(buf) }
501 }
502
503 pub fn into_inner(self) -> Vec<T> {
505 self.inner.into_owned()
506 }
507}
508
509impl<'a, T: ProtocolEncoding + Clone> ProtocolEncoding for LengthPrefixedVector<'a, T> {
510 fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
511 w.emit_compact_size(self.inner.as_ref().len() as u64)?;
512 for item in self.inner.as_ref() {
513 item.encode(w)?;
514 }
515 Ok(())
516 }
517
518 fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
519 let count = r.read_compact_size()? as usize;
520 OversizedVectorError::check::<T>(count)?;
521
522 let mut buf = Vec::with_capacity(count);
523 for _ in 0..count {
524 buf.push(ProtocolEncoding::decode(r)?);
525 }
526
527 Ok(LengthPrefixedVector {
528 inner: Cow::Owned(buf),
529 })
530 }
531}
532
533
534pub mod serde {
535 use std::fmt;
554 use std::borrow::Cow;
555 use std::marker::PhantomData;
556
557 use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
558
559 use super::ProtocolEncoding;
560
561 struct SerWrapper<'a, T>(&'a T);
562
563 impl<'a, T: ProtocolEncoding> Serialize for SerWrapper<'a, T> {
564 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
565 if s.is_human_readable() {
566 s.serialize_str(&self.0.serialize_hex())
567 } else {
568 s.serialize_bytes(&self.0.serialize())
569 }
570 }
571 }
572
573 struct DeWrapper<T>(T);
574
575 impl<'de, T: ProtocolEncoding> Deserialize<'de> for DeWrapper<T> {
576 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
577 if d.is_human_readable() {
578 let s = <Cow<'de, str>>::deserialize(d)?;
579 Ok(DeWrapper(ProtocolEncoding::deserialize_hex(s.as_ref())
580 .map_err(serde::de::Error::custom)?))
581 } else {
582 let b = <Cow<'de, [u8]>>::deserialize(d)?;
583 Ok(DeWrapper(ProtocolEncoding::deserialize(b.as_ref())
584 .map_err(serde::de::Error::custom)?))
585 }
586 }
587 }
588
589 pub fn serialize<T: ProtocolEncoding, S: Serializer>(v: &T, s: S) -> Result<S::Ok, S::Error> {
590 SerWrapper(v).serialize(s)
591 }
592
593 pub fn deserialize<'d, T: ProtocolEncoding, D: Deserializer<'d>>(d: D) -> Result<T, D::Error> {
594 Ok(DeWrapper::<T>::deserialize(d)?.0)
595 }
596
597 pub mod opt {
598 use super::*;
599
600
601 pub fn serialize<T: ProtocolEncoding, S: Serializer>(v: &Option<T>, s: S) -> Result<S::Ok, S::Error> {
602 match v {
603 Some(v) => s.serialize_some(&SerWrapper(v)),
604 None => s.serialize_none(),
605 }
606 }
607
608 pub fn deserialize<'d, T: ProtocolEncoding, D: Deserializer<'d>>(d: D) -> Result<Option<T>, D::Error> {
609 Ok(Option::<DeWrapper<T>>::deserialize(d)?.map(|w| w.0))
610 }
611 }
612
613 pub mod vec {
614 use super::*;
615
616 pub fn serialize<T: ProtocolEncoding, S: Serializer>(v: &[T], s: S) -> Result<S::Ok, S::Error> {
617 let mut seq = s.serialize_seq(Some(v.len()))?;
618 for item in v {
619 ser::SerializeSeq::serialize_element(&mut seq, &SerWrapper(item))?;
620 }
621 ser::SerializeSeq::end(seq)
622 }
623
624 pub fn deserialize<'d, T: ProtocolEncoding, D: Deserializer<'d>>(d: D) -> Result<Vec<T>, D::Error> {
625 struct Visitor<T>(PhantomData<T>);
626
627 impl<'de, T: ProtocolEncoding> de::Visitor<'de> for Visitor<T> {
628 type Value = Vec<T>;
629
630 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
631 f.write_str("a vector of objects implementing ProtocolEncoding")
632 }
633
634 fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
635 let mut ret = Vec::with_capacity(seq.size_hint().unwrap_or_default());
636 while let Some(v) = seq.next_element::<DeWrapper<T>>()? {
637 ret.push(v.0);
638 }
639 Ok(ret)
640 }
641 }
642 d.deserialize_seq(Visitor(PhantomData))
643 }
644 }
645
646 pub mod cow {
647 use super::*;
648
649 use std::borrow::Cow;
650
651 pub fn serialize<'a, T, S>(v: &Cow<'a, T>, s: S) -> Result<S::Ok, S::Error>
652 where
653 T: ProtocolEncoding + Clone,
654 S: Serializer,
655 {
656 SerWrapper(v.as_ref()).serialize(s)
657 }
658
659 pub fn deserialize<'d, T, D>(d: D) -> Result<Cow<'static, T>, D::Error>
660 where
661 T: ProtocolEncoding + Clone,
662 D: Deserializer<'d>,
663 {
664 Ok(Cow::Owned(DeWrapper::<T>::deserialize(d)?.0))
665 }
666
667 pub mod vec {
668 use super::*;
669
670 use std::borrow::Cow;
671
672 pub fn serialize<'a, T, S>(v: &Cow<'a, [T]>, s: S) -> Result<S::Ok, S::Error>
673 where
674 T: ProtocolEncoding + Clone,
675 S: Serializer,
676 {
677 let mut seq = s.serialize_seq(Some(v.len()))?;
678 for item in v.as_ref().iter() {
679 ser::SerializeSeq::serialize_element(&mut seq, &SerWrapper(item))?;
680 }
681 ser::SerializeSeq::end(seq)
682 }
683
684 pub fn deserialize<'d, T, D>(d: D) -> Result<Cow<'static, [T]>, D::Error>
685 where
686 T: ProtocolEncoding + Clone,
687 D: Deserializer<'d>,
688 {
689 struct Visitor<T>(PhantomData<T>);
690
691 impl<'de, T: ProtocolEncoding + Clone + 'static> de::Visitor<'de> for Visitor<T> {
692 type Value = Cow<'static, [T]>;
693
694 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
695 f.write_str("a vector of objects implementing ProtocolEncoding")
696 }
697
698 fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
699 let mut ret = Vec::with_capacity(seq.size_hint().unwrap_or_default());
700 while let Some(v) = seq.next_element::<DeWrapper<T>>()? {
701 ret.push(v.0);
702 }
703 Ok(ret.into())
704 }
705 }
706 d.deserialize_seq(Visitor(PhantomData))
707 }
708 }
709 }
710}
711
712
713#[cfg(test)]
714mod test {
715 use bitcoin::hex::DisplayHex;
716 use bitcoin::secp256k1::{self, Keypair};
717
718 use crate::{Vtxo, SECP};
719 use crate::test_util::VTXO_VECTORS;
720 use crate::vtxo::Full;
721
722 use super::*;
723
724
725 #[test]
726 fn option_pubkey() {
727 let key = Keypair::new(&SECP, &mut secp256k1::rand::thread_rng());
728 let pk = key.public_key();
729
730 println!("pk: {}", pk);
731
732 println!("serialize option: {}",
733 <Option<PublicKey> as ProtocolEncoding>::serialize(&Some(pk)).as_hex(),
734 );
735
736 assert_eq!(pk,
737 ProtocolEncoding::deserialize(&ProtocolEncoding::serialize(&pk)).unwrap(),
738 );
739
740 assert_eq!(Some(pk),
741 ProtocolEncoding::deserialize(&ProtocolEncoding::serialize(&Some(pk))).unwrap(),
742 );
743
744 assert_eq!(None,
745 <Option<PublicKey> as ProtocolEncoding>::deserialize(
746 &ProtocolEncoding::serialize(&Option::<PublicKey>::None),
747 ).unwrap(),
748 );
749 }
750
751 #[test]
752 fn serde_opt_json_roundtrip() {
753 #[derive(Serialize, Deserialize, PartialEq, Debug)]
754 struct Wrap {
755 #[serde(default, skip_serializing_if = "Option::is_none", with = "super::serde::opt")]
756 pk: Option<PublicKey>,
757 }
758
759 let pk = Keypair::new(&SECP, &mut secp256k1::rand::thread_rng()).public_key();
760
761 let some = Wrap { pk: Some(pk) };
762 let json = serde_json::to_string(&some).unwrap();
763 assert_eq!(some, serde_json::from_str(&json).unwrap());
764
765 let none = Wrap { pk: None };
766 let json = serde_json::to_string(&none).unwrap();
767 assert_eq!(none, serde_json::from_str(&json).unwrap());
768 }
769
770 #[test]
771 fn reject_trailing_bytes() {
772 let vtxo = &VTXO_VECTORS.board_vtxo;
773
774 let encoded = vtxo.serialize();
775 assert!(<Vtxo<Full> as ProtocolEncoding>::deserialize(&encoded).is_ok());
776
777 let with_trailing = encoded.iter().copied().chain([1u8]).collect::<Vec<_>>();
778 let err = <Vtxo<Full> as ProtocolEncoding>::deserialize(&with_trailing).unwrap_err();
779 assert!(matches!(err, ProtocolDecodingError::Invalid { message, .. } if message == "trailing bytes"));
780
781 let hex = vtxo.serialize_hex();
782 assert!(<Vtxo<Full> as ProtocolEncoding>::deserialize_hex(&hex).is_ok());
783
784 let hex_with_trailing = format!("{}01", hex);
785 let err = <Vtxo<Full> as ProtocolEncoding>::deserialize_hex(&hex_with_trailing).unwrap_err();
786 assert!(matches!(err, ProtocolDecodingError::Invalid { message, .. } if message == "trailing bytes"));
787 }
788}