Skip to main content

ark/
encode.rs

1//!
2//! Definitions of protocol encodings.
3//!
4
5
6use std::borrow::Cow;
7use std::{fmt, io, mem};
8
9use bitcoin::hashes::{sha256, Hash};
10// We use bitcoin::io::{Read, Write} here but we shouldn't have to.
11// I created this issue in the hope that rust-bitcoin fixes this nuisance:
12//  https://github.com/rust-bitcoin/rust-bitcoin/issues/4530
13use bitcoin::secp256k1::{self, schnorr, PublicKey, XOnlyPublicKey};
14use secp256k1_musig::musig;
15
16
17/// Maximum size, in bytes, of a vector we are allowed to decode
18pub const MAX_VEC_SIZE: usize = 4_000_000;
19
20/// Maximum allowed scriptPubkey size in vbytes
21pub const MAX_SCRIPT_PUBKEY_SIZE: usize = 100;
22
23/// Error occurring during protocol decoding.
24#[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	/// Create a new [ProtocolDecodingError::Invalid] with the given message.
40	pub fn invalid(message: impl fmt::Display) -> Self {
41		Self::Invalid {
42			message: message.to_string(),
43			source: None,
44		}
45	}
46
47	/// Create a new [ProtocolDecodingError::Invalid] with the given message and source error.
48	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
74/// Trait for encoding objects according to the bark protocol encoding.
75pub trait ProtocolEncoding: Sized {
76	/// Encode the object into the writer.
77	//TODO(stevenroose) return nb of bytes written like bitcoin::consensus::Encodable does?
78	fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error>;
79
80	/// Decode the object from the writer.
81	fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, ProtocolDecodingError>;
82
83	/// Serialize the object into a byte vector.
84	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	/// Deserialize object from the given byte slice.
91	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	/// Serialize the object to a lowercase hex string.
101	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	/// Deserialize object from hex slice.
110	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
123/// Utility trait to write some primitive values into our encoding format.
124pub trait WriteExt: io::Write {
125	/// Write an 8-bit unsigned integer in little-endian.
126	fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> {
127		self.write_all(&v.to_le_bytes())
128	}
129
130	/// Write a 16-bit unsigned integer in little-endian.
131	fn emit_u16(&mut self, v: u16) -> Result<(), io::Error> {
132		self.write_all(&v.to_le_bytes())
133	}
134
135	/// Write a 32-bit unsigned integer in little-endian.
136	fn emit_u32(&mut self, v: u32) -> Result<(), io::Error> {
137		self.write_all(&v.to_le_bytes())
138	}
139
140	/// Write a 64-bit unsigned integer in little-endian.
141	fn emit_u64(&mut self, v: u64) -> Result<(), io::Error> {
142		self.write_all(&v.to_le_bytes())
143	}
144
145	/// Write the entire slice to the writer.
146	fn emit_slice(&mut self, slice: &[u8]) -> Result<(), io::Error> {
147		self.write_all(slice)
148	}
149
150	/// Write a value in compact size aka "VarInt" encoding.
151	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
179/// Utility trait to read some primitive values into our encoding format.
180pub trait ReadExt: io::Read {
181	/// Read an 8-bit unsigned integer in little-endian.
182	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	/// Read a 16-bit unsigned integer in little-endian.
189	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	/// Read a 32-bit unsigned integer in little-endian.
196	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	/// Read a 64-bit unsigned integer in little-endian.
203	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	/// Read from the reader to fill the entire slice.
210	fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), io::Error> {
211		self.read_exact(slice)
212	}
213
214	/// Read a byte array
215	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	/// Read a value in compact size aka "VarInt" encoding.
222	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 { // I.e., would have fit in a `u32`.
227					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 { // I.e., would have fit in a `u16`.
235					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 { // Could have been encoded as a `u8`.
243					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
401/// A macro to implement our [ProtocolEncoding] for a rust-bitcoin type that
402/// implements their `consensus::Encodable/Decodable` traits.
403macro_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	/// requested number of elements
469	pub requested: usize,
470	/// maximum number of elements
471	pub max: usize,
472}
473
474impl OversizedVectorError {
475	/// Check if allocating the requested number of items is allowed
476	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/// A wrapper around a `Vec<T>` for any `T` with [ProtocolEncoding] that can be safely
489/// encoded and decoded using a CompactSize length prefix
490///
491/// Max allocation size is protected to `MAX_VEC_SIZE`.
492#[derive(Debug, Clone)]
493pub struct LengthPrefixedVector<'a, T: Clone> {
494	inner: Cow<'a, [T]>,
495}
496
497impl<'a, T: Clone> LengthPrefixedVector<'a, T> {
498	/// Create a new [LengthPrefixedVector] wrapping the slice
499	pub fn new(buf: &'a [T]) -> Self {
500		Self { inner: Cow::Borrowed(buf) }
501	}
502
503	/// Unwrap into inner vector
504	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	//! Module that helps to encode [ProtocolEncoding] objects with serde.
536	//!
537	//! By default, the objects will be encoded as bytes for regular serializers,
538	//! and as hex for human-readable serializers.
539	//!
540	//! Can be used as follows:
541	//! ```no_run
542	//! # use ark::Vtxo;
543	//! # use serde::{Serialize, Deserialize};
544	//! #[derive(Serialize, Deserialize)]
545	//! struct SomeStruct {
546	//! 	#[serde(with = "ark::encode::serde")]
547	//! 	single: Vtxo,
548	//! 	#[serde(with = "ark::encode::serde::vec")]
549	//! 	multiple: Vec<Vtxo>,
550	//! }
551	//! ```
552
553	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}