//! A very simple serialization framework which is used to serialize/deserialize messages as well //! as ChannelsManagers and ChannelMonitors. use std::result::Result; use std::io::{Read, Write}; use std::collections::HashMap; use std::hash::Hash; use secp256k1::{Secp256k1, Signature}; use secp256k1::key::{PublicKey, SecretKey}; use bitcoin::util::hash::Sha256dHash; use bitcoin::blockdata::script::Script; use std::marker::Sized; use ln::msgs::DecodeError; use util::byte_utils; use util::byte_utils::{be64_to_array, be48_to_array, be32_to_array, be16_to_array, slice_to_be16, slice_to_be32, slice_to_be48, slice_to_be64}; const MAX_BUF_SIZE: usize = 64 * 1024; /// A trait that is similar to std::io::Write but has one extra function which can be used to size /// buffers being written into. /// An impl is provided for any type that also impls std::io::Write which simply ignores size /// hints. pub trait Writer { /// Writes the given buf out. See std::io::Write::write_all for more fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error>; /// Hints that data of the given size is about the be written. This may not always be called /// prior to data being written and may be safely ignored. fn size_hint(&mut self, size: usize); } impl Writer for W { #[inline] fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { ::write_all(self, buf) } #[inline] fn size_hint(&mut self, _size: usize) { } } pub(crate) struct WriterWriteAdaptor<'a, W: Writer + 'a>(pub &'a mut W); impl<'a, W: Writer + 'a> Write for WriterWriteAdaptor<'a, W> { fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { self.0.write_all(buf) } fn write(&mut self, buf: &[u8]) -> Result { self.0.write_all(buf)?; Ok(buf.len()) } fn flush(&mut self) -> Result<(), ::std::io::Error> { Ok(()) } } struct VecWriter(Vec); impl Writer for VecWriter { fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { self.0.extend_from_slice(buf); Ok(()) } fn size_hint(&mut self, size: usize) { self.0.reserve_exact(size); } } /// A trait that various rust-lightning types implement allowing them to be written out to a Writer pub trait Writeable { /// Writes self out to the given Writer fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error>; /// Writes self out to a Vec fn encode(&self) -> Vec { let mut msg = VecWriter(Vec::new()); self.write(&mut msg).unwrap(); msg.0 } /// Writes self out to a Vec fn encode_with_len(&self) -> Vec { let mut msg = VecWriter(Vec::new()); 0u16.write(&mut msg).unwrap(); self.write(&mut msg).unwrap(); let len = msg.0.len(); msg.0[..2].copy_from_slice(&byte_utils::be16_to_array(len as u16 - 2)); msg.0 } } /// A trait that various rust-lightning types implement allowing them to be read in from a Read pub trait Readable where Self: Sized, R: Read { /// Reads a Self in from the given Read fn read(reader: &mut R) -> Result; } /// A trait that various higher-level rust-lightning types implement allowing them to be read in /// from a Read given some additional set of arguments which is required to deserialize. pub trait ReadableArgs where Self: Sized, R: Read { /// Reads a Self in from the given Read fn read(reader: &mut R, params: P) -> Result; } pub(crate) struct U48(pub u64); impl Writeable for U48 { #[inline] fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { writer.write_all(&be48_to_array(self.0)) } } impl Readable for U48 { #[inline] fn read(reader: &mut R) -> Result { let mut buf = [0; 6]; reader.read_exact(&mut buf)?; Ok(U48(slice_to_be48(&buf))) } } macro_rules! impl_writeable_primitive { ($val_type:ty, $meth_write:ident, $len: expr, $meth_read:ident) => { impl Writeable for $val_type { #[inline] fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { writer.write_all(&$meth_write(*self)) } } impl Readable for $val_type { #[inline] fn read(reader: &mut R) -> Result<$val_type, DecodeError> { let mut buf = [0; $len]; reader.read_exact(&mut buf)?; Ok($meth_read(&buf)) } } } } impl_writeable_primitive!(u64, be64_to_array, 8, slice_to_be64); impl_writeable_primitive!(u32, be32_to_array, 4, slice_to_be32); impl_writeable_primitive!(u16, be16_to_array, 2, slice_to_be16); impl Writeable for u8 { #[inline] fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { writer.write_all(&[*self]) } } impl Readable for u8 { #[inline] fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; reader.read_exact(&mut buf)?; Ok(buf[0]) } } impl Writeable for bool { #[inline] fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { writer.write_all(&[if *self {1} else {0}]) } } impl Readable for bool { #[inline] fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; reader.read_exact(&mut buf)?; if buf[0] != 0 && buf[0] != 1 { return Err(DecodeError::InvalidValue); } Ok(buf[0] == 1) } } // u8 arrays macro_rules! impl_array { ( $size:expr ) => ( impl Writeable for [u8; $size] { #[inline] fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { w.write_all(self) } } impl Readable for [u8; $size] { #[inline] fn read(r: &mut R) -> Result { let mut buf = [0u8; $size]; r.read_exact(&mut buf)?; Ok(buf) } } ); } //TODO: performance issue with [u8; size] with impl_array!() impl_array!(32); // for channel id & hmac impl_array!(33); // for PublicKey impl_array!(64); // for Signature impl_array!(1300); // for OnionPacket.hop_data // HashMap impl Writeable for HashMap where K: Writeable + Eq + Hash, V: Writeable { #[inline] fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { (self.len() as u16).write(w)?; for (key, value) in self.iter() { key.write(w)?; value.write(w)?; } Ok(()) } } impl Readable for HashMap where R: Read, K: Readable + Eq + Hash, V: Readable { #[inline] fn read(r: &mut R) -> Result { let len: u16 = Readable::read(r)?; let mut ret = HashMap::with_capacity(len as usize); for _ in 0..len { ret.insert(K::read(r)?, V::read(r)?); } Ok(ret) } } // Vectors impl Writeable for Vec { #[inline] fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { (self.len() as u16).write(w)?; w.write_all(&self) } } impl Readable for Vec { #[inline] fn read(r: &mut R) -> Result { let len: u16 = Readable::read(r)?; let mut ret = Vec::with_capacity(len as usize); ret.resize(len as usize, 0); r.read_exact(&mut ret)?; Ok(ret) } } impl Writeable for Vec { #[inline] fn write(&self, w: &mut W) -> Result<(), ::std::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(33) .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(Signature::read(r)?); } Ok(ret) } } impl Writeable for Script { fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { (self.len() as u16).write(w)?; w.write_all(self.as_bytes()) } } impl Readable for Script { fn read(r: &mut R) -> Result { let len = >::read(r)? as usize; let mut buf = vec![0; len]; r.read_exact(&mut buf)?; Ok(Script::from(buf)) } } impl Writeable for Option