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		Self::decode(&mut byte_slice)
93	}
94
95	/// Serialize the object to a lowercase hex string.
96	fn serialize_hex(&self) -> String {
97		use hex_conservative::Case::Lower;
98		let mut buf = String::new();
99		let mut writer = hex_conservative::display::HexWriter::new(&mut buf, Lower);
100		self.encode(&mut writer).expect("no I/O errors for buffers");
101		buf
102	}
103
104	/// Deserialize object from hex slice.
105	fn deserialize_hex(hex_str: &str) -> Result<Self, ProtocolDecodingError> {
106		let mut iter = hex_conservative::HexToBytesIter::new(hex_str).map_err(|e| {
107			ProtocolDecodingError::Io(io::Error::new(io::ErrorKind::InvalidData, e))
108		})?;
109		Self::decode(&mut iter)
110	}
111}
112
113/// Utility trait to write some primitive values into our encoding format.
114pub trait WriteExt: io::Write {
115	/// Write an 8-bit unsigned integer in little-endian.
116	fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> {
117		self.write_all(&v.to_le_bytes())
118	}
119
120	/// Write a 16-bit unsigned integer in little-endian.
121	fn emit_u16(&mut self, v: u16) -> Result<(), io::Error> {
122		self.write_all(&v.to_le_bytes())
123	}
124
125	/// Write a 32-bit unsigned integer in little-endian.
126	fn emit_u32(&mut self, v: u32) -> Result<(), io::Error> {
127		self.write_all(&v.to_le_bytes())
128	}
129
130	/// Write a 64-bit unsigned integer in little-endian.
131	fn emit_u64(&mut self, v: u64) -> Result<(), io::Error> {
132		self.write_all(&v.to_le_bytes())
133	}
134
135	/// Write the entire slice to the writer.
136	fn emit_slice(&mut self, slice: &[u8]) -> Result<(), io::Error> {
137		self.write_all(slice)
138	}
139
140	/// Write a value in compact size aka "VarInt" encoding.
141	fn emit_compact_size(&mut self, value: impl Into<u64>) -> Result<usize, io::Error> {
142		let value = value.into();
143		match value {
144			0..=0xFC => {
145				self.emit_u8(value as u8)?;
146				Ok(1)
147			},
148			0xFD..=0xFFFF => {
149				self.emit_u8(0xFD)?;
150				self.emit_u16(value as u16)?;
151				Ok(3)
152			},
153			0x10000..=0xFFFFFFFF => {
154				self.emit_u8(0xFE)?;
155				self.emit_u32(value as u32)?;
156				Ok(5)
157			},
158			_ => {
159				self.emit_u8(0xFF)?;
160				self.emit_u64(value)?;
161				Ok(9)
162			},
163		}
164	}
165}
166
167impl<W: io::Write + ?Sized> WriteExt for W {}
168
169/// Utility trait to read some primitive values into our encoding format.
170pub trait ReadExt: io::Read {
171	/// Read an 8-bit unsigned integer in little-endian.
172	fn read_u8(&mut self) -> Result<u8, io::Error> {
173		let mut buf = [0; 1];
174		self.read_exact(&mut buf[..])?;
175		Ok(u8::from_le_bytes(buf))
176	}
177
178	/// Read a 16-bit unsigned integer in little-endian.
179	fn read_u16(&mut self) -> Result<u16, io::Error> {
180		let mut buf = [0; 2];
181		self.read_exact(&mut buf[..])?;
182		Ok(u16::from_le_bytes(buf))
183	}
184
185	/// Read a 32-bit unsigned integer in little-endian.
186	fn read_u32(&mut self) -> Result<u32, io::Error> {
187		let mut buf = [0; 4];
188		self.read_exact(&mut buf[..])?;
189		Ok(u32::from_le_bytes(buf))
190	}
191
192	/// Read a 64-bit unsigned integer in little-endian.
193	fn read_u64(&mut self) -> Result<u64, io::Error> {
194		let mut buf = [0; 8];
195		self.read_exact(&mut buf[..])?;
196		Ok(u64::from_le_bytes(buf))
197	}
198
199	/// Read from the reader to fill the entire slice.
200	fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), io::Error> {
201		self.read_exact(slice)
202	}
203
204	/// Read a byte array
205	fn read_byte_array<const N: usize>(&mut self) -> Result<[u8; N], io::Error> {
206		let mut ret = [0u8; N];
207		self.read_exact(&mut ret)?;
208		Ok(ret)
209	}
210
211	/// Read a value in compact size aka "VarInt" encoding.
212	fn read_compact_size(&mut self) -> Result<u64, io::Error> {
213		match self.read_u8()? {
214			0xFF => {
215				let x = self.read_u64()?;
216				if x < 0x1_0000_0000 { // I.e., would have fit in a `u32`.
217					Err(io::Error::new(io::ErrorKind::InvalidData, "non-minimal varint"))
218				} else {
219					Ok(x)
220				}
221			},
222			0xFE => {
223				let x = self.read_u32()?;
224				if x < 0x1_0000 { // I.e., would have fit in a `u16`.
225					Err(io::Error::new(io::ErrorKind::InvalidData, "non-minimal varint"))
226				} else {
227					Ok(x as u64)
228				}
229			},
230			0xFD => {
231				let x = self.read_u16()?;
232				if x < 0xFD { // Could have been encoded as a `u8`.
233					Err(io::Error::new(io::ErrorKind::InvalidData, "non-minimal varint"))
234				} else {
235					Ok(x as u64)
236				}
237			},
238			n => Ok(n as u64),
239		}
240	}
241}
242
243impl<R: io::Read + ?Sized> ReadExt for R {}
244
245
246impl ProtocolEncoding for PublicKey {
247	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
248		w.emit_slice(&self.serialize())
249	}
250
251	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
252		let mut buf = [0; secp256k1::constants::PUBLIC_KEY_SIZE];
253		r.read_slice(&mut buf[..])?;
254		PublicKey::from_slice(&buf).map_err(|e| {
255			ProtocolDecodingError::invalid_err(e, "invalid public key")
256		})
257	}
258}
259
260impl ProtocolEncoding for XOnlyPublicKey {
261	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
262		w.emit_slice(&self.serialize())
263	}
264
265	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
266		let mut buf = [0; 32];
267		r.read_slice(&mut buf[..])?;
268		XOnlyPublicKey::from_slice(&buf).map_err(|e| {
269			ProtocolDecodingError::invalid_err(e, "invalid x-only public key")
270		})
271	}
272}
273
274impl ProtocolEncoding for Option<sha256::Hash> {
275	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
276		if let Some(h) = self {
277			w.emit_u8(1)?;
278			w.emit_slice(&h.as_byte_array()[..])
279		} else {
280			w.emit_u8(0)
281		}
282	}
283
284	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
285		let first = r.read_u8()?;
286		if first == 0 {
287			Ok(None)
288		} else if first == 1 {
289			let mut buf = [0u8; 32];
290			r.read_slice(&mut buf)?;
291			Ok(Some(sha256::Hash::from_byte_array(buf)))
292		} else {
293			Err(ProtocolDecodingError::invalid("invalid optional hash prefix byte"))
294		}
295	}
296}
297
298impl ProtocolEncoding for Option<PublicKey> {
299	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
300		if let Some(pk) = self {
301			w.emit_slice(&pk.serialize())
302		} else {
303			w.emit_u8(0)
304		}
305	}
306
307	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
308		let first = r.read_u8()?;
309		if first == 0 {
310			Ok(None)
311		} else {
312			let mut pk = [first; secp256k1::constants::PUBLIC_KEY_SIZE];
313			r.read_slice(&mut pk[1..])?;
314			Ok(Some(PublicKey::from_slice(&pk).map_err(|e| {
315				ProtocolDecodingError::invalid_err(e, "invalid public key")
316			})?))
317		}
318	}
319}
320
321impl ProtocolEncoding for schnorr::Signature {
322	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
323		w.emit_slice(&self.serialize())
324	}
325
326	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
327		let mut buf = [0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE];
328		r.read_slice(&mut buf[..])?;
329		schnorr::Signature::from_slice(&buf).map_err(|e| {
330			ProtocolDecodingError::invalid_err(e, "invalid schnorr signature")
331		})
332	}
333}
334
335impl ProtocolEncoding for Option<schnorr::Signature> {
336	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
337		if let Some(sig) = self {
338			w.emit_slice(&sig.serialize())
339		} else {
340			w.emit_slice(&[0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE])
341		}
342	}
343
344	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
345		let mut buf = [0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE];
346		r.read_slice(&mut buf[..])?;
347		if buf == [0; secp256k1::constants::SCHNORR_SIGNATURE_SIZE] {
348			Ok(None)
349		} else {
350			Ok(Some(schnorr::Signature::from_slice(&buf).map_err(|e| {
351				ProtocolDecodingError::invalid_err(e, "invalid schnorr signature")
352			})?))
353		}
354	}
355}
356
357impl ProtocolEncoding for sha256::Hash {
358	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
359		w.emit_slice(&self[..])
360	}
361
362	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
363		let mut buf = [0; sha256::Hash::LEN];
364		r.read_exact(&mut buf[..])?;
365		Ok(sha256::Hash::from_byte_array(buf))
366	}
367}
368
369impl ProtocolEncoding for musig::PublicNonce {
370	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
371	    w.emit_slice(&self.serialize())
372	}
373	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
374		Ok(Self::from_byte_array(&r.read_byte_array()?).map_err(|e| {
375			ProtocolDecodingError::invalid_err(e, "invalid musig public nonce")
376		})?)
377	}
378}
379
380impl ProtocolEncoding for musig::PartialSignature {
381	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
382	    w.emit_slice(&self.serialize())
383	}
384	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
385		Ok(Self::from_byte_array(&r.read_byte_array()?).map_err(|e| {
386			ProtocolDecodingError::invalid_err(e, "invalid musig public nonce")
387		})?)
388	}
389}
390
391/// A macro to implement our [ProtocolEncoding] for a rust-bitcoin type that
392/// implements their `consensus::Encodable/Decodable` traits.
393macro_rules! impl_bitcoin_encode {
394	($name:ty) => {
395		impl ProtocolEncoding for $name {
396			fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
397				let mut wrapped = bitcoin::io::FromStd::new(w);
398				bitcoin::consensus::Encodable::consensus_encode(self, &mut wrapped)?;
399				Ok(())
400			}
401
402			fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
403				let mut wrapped = bitcoin::io::FromStd::new(r);
404				let ret = bitcoin::consensus::Decodable::consensus_decode(&mut wrapped)?;
405				Ok(ret)
406			}
407		}
408	};
409}
410
411impl_bitcoin_encode!(bitcoin::BlockHash);
412impl_bitcoin_encode!(bitcoin::OutPoint);
413
414impl ProtocolEncoding for bitcoin::TxOut {
415	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
416		let mut wrapped = bitcoin::io::FromStd::new(w);
417		bitcoin::consensus::Encodable::consensus_encode(self, &mut wrapped)?;
418		Ok(())
419	}
420
421	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
422		use bitcoin::consensus::Decodable;
423
424		let mut wrapped = bitcoin::io::FromStd::new(r);
425		let ret = bitcoin::TxOut::consensus_decode(&mut wrapped)?;
426		if ret.script_pubkey.len() > MAX_SCRIPT_PUBKEY_SIZE {
427			return Err(ProtocolDecodingError::invalid("oversized output scriptPubkey"));
428		}
429		Ok(ret)
430	}
431}
432
433impl ProtocolEncoding for bitcoin::taproot::TapTweakHash {
434	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
435		w.emit_slice(&self.to_byte_array())
436	}
437
438	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
439		Ok(Self::from_byte_array(r.read_byte_array().map_err(|e| {
440			ProtocolDecodingError::invalid_err(e, "TapTweakHash must be 32 bytes")
441		})?))
442	}
443}
444
445impl<'a, T: ProtocolEncoding + Clone> ProtocolEncoding for Cow<'a, T> {
446	fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
447	    ProtocolEncoding::encode(self.as_ref(), writer)
448	}
449
450	fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, ProtocolDecodingError> {
451	    Ok(Cow::Owned(ProtocolEncoding::decode(reader)?))
452	}
453}
454
455#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
456#[error("requested to allocate a vector above our limit: requested={requested}, max={max}")]
457pub struct OversizedVectorError {
458	/// requested number of elements
459	pub requested: usize,
460	/// maximum number of elements
461	pub max: usize,
462}
463
464impl OversizedVectorError {
465	/// Check if allocating the requested number of items is allowed
466	pub fn check<T>(requested: usize) -> Result<(), Self> {
467		assert_ne!(mem::size_of::<T>(), 0, "cannot serialize vectors of empty types");
468		let max = MAX_VEC_SIZE.checked_div(mem::size_of::<T>())
469			.expect("size_of always > 0 for instantiable T");
470		if requested > max {
471			Err(Self { requested, max })
472		} else {
473			Ok(())
474		}
475	}
476}
477
478/// A wrapper around a `Vec<T>` for any `T` with [ProtocolEncoding] that can be safely
479/// encoded and decoded using a CompactSize length prefix
480///
481/// Max allocation size is protected to `MAX_VEC_SIZE`.
482#[derive(Debug, Clone)]
483pub struct LengthPrefixedVector<'a, T: Clone> {
484	inner: Cow<'a, [T]>,
485}
486
487impl<'a, T: Clone> LengthPrefixedVector<'a, T> {
488	/// Create a new [LengthPrefixedVector] wrapping the slice
489	pub fn new(buf: &'a [T]) -> Self {
490		Self { inner: Cow::Borrowed(buf) }
491	}
492
493	/// Unwrap into inner vector
494	pub fn into_inner(self) -> Vec<T> {
495		self.inner.into_owned()
496	}
497}
498
499impl<'a, T: ProtocolEncoding + Clone> ProtocolEncoding for LengthPrefixedVector<'a, T> {
500	fn encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<(), io::Error> {
501		w.emit_compact_size(self.inner.as_ref().len() as u64)?;
502		for item in self.inner.as_ref() {
503			item.encode(w)?;
504		}
505		Ok(())
506	}
507
508	fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, ProtocolDecodingError> {
509		let count = r.read_compact_size()? as usize;
510		OversizedVectorError::check::<T>(count)?;
511
512		let mut buf = Vec::with_capacity(count);
513		for _ in 0..count {
514			buf.push(ProtocolEncoding::decode(r)?);
515		}
516
517		Ok(LengthPrefixedVector {
518			inner: Cow::Owned(buf),
519		})
520	}
521}
522
523
524pub mod serde {
525	//! Module that helps to encode [ProtocolEncoding] objects with serde.
526	//!
527	//! By default, the objects will be encoded as bytes for regular serializers,
528	//! and as hex for human-readable serializers.
529	//!
530	//! Can be used as follows:
531	//! ```no_run
532	//! # use ark::Vtxo;
533	//! # use serde::{Serialize, Deserialize};
534	//! #[derive(Serialize, Deserialize)]
535	//! struct SomeStruct {
536	//! 	#[serde(with = "ark::encode::serde")]
537	//! 	single: Vtxo,
538	//! 	#[serde(with = "ark::encode::serde::vec")]
539	//! 	multiple: Vec<Vtxo>,
540	//! }
541	//! ```
542
543	use std::fmt;
544	use std::borrow::Cow;
545	use std::marker::PhantomData;
546
547	use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
548
549	use super::ProtocolEncoding;
550
551	struct SerWrapper<'a, T>(&'a T);
552
553	impl<'a, T: ProtocolEncoding> Serialize for SerWrapper<'a, T> {
554		fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
555			if s.is_human_readable() {
556				s.serialize_str(&self.0.serialize_hex())
557			} else {
558				s.serialize_bytes(&self.0.serialize())
559			}
560		}
561	}
562
563	struct DeWrapper<T>(T);
564
565	impl<'de, T: ProtocolEncoding> Deserialize<'de> for DeWrapper<T> {
566		fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
567			if d.is_human_readable() {
568				let s = <Cow<'de, str>>::deserialize(d)?;
569				Ok(DeWrapper(ProtocolEncoding::deserialize_hex(s.as_ref())
570					.map_err(serde::de::Error::custom)?))
571			} else {
572				let b = <Cow<'de, [u8]>>::deserialize(d)?;
573				Ok(DeWrapper(ProtocolEncoding::deserialize(b.as_ref())
574					.map_err(serde::de::Error::custom)?))
575			}
576		}
577	}
578
579	pub fn serialize<T: ProtocolEncoding, S: Serializer>(v: &T, s: S) -> Result<S::Ok, S::Error> {
580		SerWrapper(v).serialize(s)
581	}
582
583	pub fn deserialize<'d, T: ProtocolEncoding, D: Deserializer<'d>>(d: D) -> Result<T, D::Error> {
584		Ok(DeWrapper::<T>::deserialize(d)?.0)
585	}
586
587	pub mod opt {
588		use super::*;
589
590
591		pub fn serialize<T: ProtocolEncoding, S: Serializer>(v: &Option<T>, s: S) -> Result<S::Ok, S::Error> {
592			match v {
593				Some(v) => s.serialize_some(&SerWrapper(v)),
594				None => s.serialize_none(),
595			}
596		}
597
598		pub fn deserialize<'d, T: ProtocolEncoding, D: Deserializer<'d>>(d: D) -> Result<Option<T>, D::Error> {
599			Ok(Option::<DeWrapper<T>>::deserialize(d)?.map(|w| w.0))
600		}
601	}
602
603	pub mod vec {
604		use super::*;
605
606		pub fn serialize<T: ProtocolEncoding, S: Serializer>(v: &[T], s: S) -> Result<S::Ok, S::Error> {
607			let mut seq = s.serialize_seq(Some(v.len()))?;
608			for item in v {
609				ser::SerializeSeq::serialize_element(&mut seq, &SerWrapper(item))?;
610			}
611			ser::SerializeSeq::end(seq)
612		}
613
614		pub fn deserialize<'d, T: ProtocolEncoding, D: Deserializer<'d>>(d: D) -> Result<Vec<T>, D::Error> {
615			struct Visitor<T>(PhantomData<T>);
616
617			impl<'de, T: ProtocolEncoding> de::Visitor<'de> for Visitor<T> {
618				type Value = Vec<T>;
619
620				fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
621					f.write_str("a vector of objects implementing ProtocolEncoding")
622				}
623
624				fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
625					let mut ret = Vec::with_capacity(seq.size_hint().unwrap_or_default());
626					while let Some(v) = seq.next_element::<DeWrapper<T>>()? {
627						ret.push(v.0);
628					}
629					Ok(ret)
630				}
631			}
632			d.deserialize_seq(Visitor(PhantomData))
633		}
634	}
635
636	pub mod cow {
637		use super::*;
638
639		use std::borrow::Cow;
640
641		pub fn serialize<'a, T, S>(v: &Cow<'a, T>, s: S) -> Result<S::Ok, S::Error>
642		where
643			T: ProtocolEncoding + Clone,
644			S: Serializer,
645		{
646			SerWrapper(v.as_ref()).serialize(s)
647		}
648
649		pub fn deserialize<'d, T, D>(d: D) -> Result<Cow<'static, T>, D::Error>
650		where
651			T: ProtocolEncoding + Clone,
652			D: Deserializer<'d>,
653		{
654			Ok(Cow::Owned(DeWrapper::<T>::deserialize(d)?.0))
655		}
656
657		pub mod vec {
658			use super::*;
659
660			use std::borrow::Cow;
661
662			pub fn serialize<'a, T, S>(v: &Cow<'a, [T]>, s: S) -> Result<S::Ok, S::Error>
663			where
664				T: ProtocolEncoding + Clone,
665				S: Serializer,
666			{
667				let mut seq = s.serialize_seq(Some(v.len()))?;
668				for item in v.as_ref().iter() {
669					ser::SerializeSeq::serialize_element(&mut seq, &SerWrapper(item))?;
670				}
671				ser::SerializeSeq::end(seq)
672			}
673
674			pub fn deserialize<'d, T, D>(d: D) -> Result<Cow<'static, [T]>, D::Error>
675			where
676				T: ProtocolEncoding + Clone,
677				D: Deserializer<'d>,
678			{
679				struct Visitor<T>(PhantomData<T>);
680
681				impl<'de, T: ProtocolEncoding + Clone + 'static> de::Visitor<'de> for Visitor<T> {
682					type Value = Cow<'static, [T]>;
683
684					fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
685						f.write_str("a vector of objects implementing ProtocolEncoding")
686					}
687
688					fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
689						let mut ret = Vec::with_capacity(seq.size_hint().unwrap_or_default());
690						while let Some(v) = seq.next_element::<DeWrapper<T>>()? {
691							ret.push(v.0);
692						}
693						Ok(ret.into())
694					}
695				}
696				d.deserialize_seq(Visitor(PhantomData))
697			}
698		}
699	}
700}
701
702
703#[cfg(test)]
704mod test {
705	use bitcoin::hex::DisplayHex;
706	use bitcoin::secp256k1::{self, Keypair};
707
708	use crate::SECP;
709	use super::*;
710
711
712	#[test]
713	fn option_pubkey() {
714		let key = Keypair::new(&SECP, &mut secp256k1::rand::thread_rng());
715		let pk = key.public_key();
716
717		println!("pk: {}", pk);
718
719		println!("serialize option: {}",
720			<Option<PublicKey> as ProtocolEncoding>::serialize(&Some(pk)).as_hex(),
721		);
722
723		assert_eq!(pk,
724			ProtocolEncoding::deserialize(&ProtocolEncoding::serialize(&pk)).unwrap(),
725		);
726
727		assert_eq!(Some(pk),
728			ProtocolEncoding::deserialize(&ProtocolEncoding::serialize(&Some(pk))).unwrap(),
729		);
730
731		assert_eq!(None,
732			<Option<PublicKey> as ProtocolEncoding>::deserialize(
733				&ProtocolEncoding::serialize(&Option::<PublicKey>::None),
734			).unwrap(),
735		);
736
737	}
738
739	#[test]
740	fn serde_opt_json_roundtrip() {
741		#[derive(Serialize, Deserialize, PartialEq, Debug)]
742		struct Wrap {
743			#[serde(default, skip_serializing_if = "Option::is_none", with = "super::serde::opt")]
744			pk: Option<PublicKey>,
745		}
746
747		let pk = Keypair::new(&SECP, &mut secp256k1::rand::thread_rng()).public_key();
748
749		let some = Wrap { pk: Some(pk) };
750		let json = serde_json::to_string(&some).unwrap();
751		assert_eq!(some, serde_json::from_str(&json).unwrap());
752
753		let none = Wrap { pk: None };
754		let json = serde_json::to_string(&none).unwrap();
755		assert_eq!(none, serde_json::from_str(&json).unwrap());
756	}
757}