From: Matt Corallo Date: Mon, 28 Nov 2022 00:42:15 +0000 (+0000) Subject: Convert `Vec` de/serialization impl to a macro and impl for tuples X-Git-Tag: v0.0.114-beta~53^2~1 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=b75a558a1de8e575bd501ccc64382e5b075c471e;p=rust-lightning Convert `Vec` de/serialization impl to a macro and impl for tuples ...to make it easier to add new implementations and implement it for all tuples which implement `Readabe` + `Writeable`. Note that we don't want to just convert to a blanket implementation as we'd really like to keep our optimized `Vec` wrapper or we'll end up spinning way too much when writing vecs of bytes. --- diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 454c4990e..44725e722 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -662,6 +662,35 @@ where T: Readable + Eq + Hash } // Vectors +macro_rules! impl_for_vec { + ($ty: ty $(, $name: ident)*) => { + impl<$($name : Writeable),*> Writeable for Vec<$ty> { + #[inline] + fn write(&self, w: &mut W) -> Result<(), io::Error> { + (self.len() as u16).write(w)?; + for elem in self.iter() { + elem.write(w)?; + } + Ok(()) + } + } + + impl<$($name : Readable),*> Readable for Vec<$ty> { + #[inline] + fn read(r: &mut R) -> Result { + let len: u16 = Readable::read(r)?; + let mut ret = Vec::with_capacity(cmp::min(len as usize, MAX_BUF_SIZE / core::mem::size_of::<$ty>())); + for _ in 0..len { + if let Some(val) = MaybeReadable::read(r)? { + ret.push(val); + } + } + Ok(ret) + } + } + } +} + impl Writeable for Vec { #[inline] fn write(&self, w: &mut W) -> Result<(), io::Error> { @@ -680,32 +709,9 @@ impl Readable for Vec { Ok(ret) } } -impl Writeable for Vec { - #[inline] - fn write(&self, w: &mut W) -> Result<(), io::Error> { - (self.len() as u16).write(w)?; - for e in self.iter() { - e.write(w)?; - } - Ok(()) - } -} -impl Readable for Vec { - #[inline] - fn read(r: &mut R) -> Result { - let len: u16 = Readable::read(r)?; - let byte_size = (len as usize) - .checked_mul(COMPACT_SIGNATURE_SIZE) - .ok_or(DecodeError::BadLengthDescriptor)?; - if byte_size > MAX_BUF_SIZE { - return Err(DecodeError::BadLengthDescriptor); - } - let mut ret = Vec::with_capacity(len as usize); - for _ in 0..len { ret.push(Readable::read(r)?); } - Ok(ret) - } -} +impl_for_vec!(ecdsa::Signature); +impl_for_vec!((A, B), A, B); impl Writeable for Script { fn write(&self, w: &mut W) -> Result<(), io::Error> {