X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser.rs;h=b27cf4b348c3d98fc805dd7478dbe640910d80f4;hb=0dfcacd22c23f69b6526c9c6507d21427a2b7ccb;hp=7bc09e7f8da00c4bc62c5a9944a1f0f8f3cf2e0d;hpb=7231b4a2456cee6bdb0eeee8c365c854ccf4c4d6;p=rust-lightning diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 7bc09e7f..b27cf4b3 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -11,10 +11,10 @@ //! as ChannelsManagers and ChannelMonitors. use prelude::*; -use std::io::{Read, Write}; -use std::collections::HashMap; +use io::{self, Read, Write}; +use io_extras::{copy, sink}; use core::hash::Hash; -use std::sync::Mutex; +use sync::Mutex; use core::cmp; use bitcoin::secp256k1::Signature; @@ -43,7 +43,7 @@ pub const MAX_BUF_SIZE: usize = 64 * 1024; /// (C-not exported) as we only export serialization to/from byte arrays instead 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>; + fn write_all(&mut self, buf: &[u8]) -> Result<(), 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); @@ -51,8 +51,8 @@ pub trait Writer { impl Writer for W { #[inline] - fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { - ::write_all(self, buf) + fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> { + ::write_all(self, buf) } #[inline] fn size_hint(&mut self, _size: usize) { } @@ -61,16 +61,16 @@ impl Writer for W { pub(crate) struct WriterWriteAdaptor<'a, W: Writer + 'a>(pub &'a mut W); impl<'a, W: Writer + 'a> Write for WriterWriteAdaptor<'a, W> { #[inline] - fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { + fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> { self.0.write_all(buf) } #[inline] - fn write(&mut self, buf: &[u8]) -> Result { + fn write(&mut self, buf: &[u8]) -> Result { self.0.write_all(buf)?; Ok(buf.len()) } #[inline] - fn flush(&mut self) -> Result<(), ::std::io::Error> { + fn flush(&mut self) -> Result<(), io::Error> { Ok(()) } } @@ -78,7 +78,7 @@ impl<'a, W: Writer + 'a> Write for WriterWriteAdaptor<'a, W> { pub(crate) struct VecWriter(pub Vec); impl Writer for VecWriter { #[inline] - fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { + fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> { self.0.extend_from_slice(buf); Ok(()) } @@ -93,7 +93,7 @@ impl Writer for VecWriter { pub(crate) struct LengthCalculatingWriter(pub usize); impl Writer for LengthCalculatingWriter { #[inline] - fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { + fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> { self.0 += buf.len(); Ok(()) } @@ -120,7 +120,7 @@ impl FixedLengthReader { #[inline] pub fn eat_remaining(&mut self) -> Result<(), DecodeError> { - ::std::io::copy(self, &mut ::std::io::sink()).unwrap(); + copy(self, &mut sink()).unwrap(); if self.bytes_read != self.total_bytes { Err(DecodeError::ShortRead) } else { @@ -130,7 +130,7 @@ impl FixedLengthReader { } impl Read for FixedLengthReader { #[inline] - fn read(&mut self, dest: &mut [u8]) -> Result { + fn read(&mut self, dest: &mut [u8]) -> Result { if self.total_bytes == self.bytes_read { Ok(0) } else { @@ -159,7 +159,7 @@ impl ReadTrackingReader { } impl Read for ReadTrackingReader { #[inline] - fn read(&mut self, dest: &mut [u8]) -> Result { + fn read(&mut self, dest: &mut [u8]) -> Result { match self.read.read(dest) { Ok(0) => Ok(0), Ok(len) => { @@ -176,7 +176,7 @@ impl Read for ReadTrackingReader { /// (C-not exported) as we only export serialization to/from byte arrays instead pub trait Writeable { /// Writes self out to the given Writer - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error>; + fn write(&self, writer: &mut W) -> Result<(), io::Error>; /// Writes self out to a Vec fn encode(&self) -> Vec { @@ -207,7 +207,7 @@ pub trait Writeable { } impl<'a, T: Writeable> Writeable for &'a T { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { (*self).write(writer) } + fn write(&self, writer: &mut W) -> Result<(), io::Error> { (*self).write(writer) } } /// A trait that various rust-lightning types implement allowing them to be read in from a Read @@ -249,28 +249,31 @@ impl Readable for OptionDeserWrapper { } } -const MAX_ALLOC_SIZE: u64 = 64*1024; - +/// Wrapper to write each element of a Vec with no length prefix pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec); impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - (self.0.len() as u64).write(writer)?; + fn write(&self, writer: &mut W) -> Result<(), io::Error> { for ref v in self.0.iter() { v.write(writer)?; } Ok(()) } } + +/// Wrapper to read elements from a given stream until it reaches the end of the stream. pub(crate) struct VecReadWrapper(pub Vec); impl Readable for VecReadWrapper { #[inline] - fn read(reader: &mut R) -> Result { - let count: u64 = Readable::read(reader)?; - let mut values = Vec::with_capacity(cmp::min(count, MAX_ALLOC_SIZE / (core::mem::size_of::() as u64)) as usize); - for _ in 0..count { - match Readable::read(reader) { + fn read(mut reader: &mut R) -> Result { + let mut values = Vec::new(); + loop { + let mut track_read = ReadTrackingReader::new(&mut reader); + match Readable::read(&mut track_read) { Ok(v) => { values.push(v); }, + // If we failed to read any bytes at all, we reached the end of our TLV + // stream and have simply exhausted all entries. + Err(ref e) if e == &DecodeError::ShortRead && !track_read.have_read => break, Err(e) => return Err(e), } } @@ -281,7 +284,7 @@ impl Readable for VecReadWrapper { pub(crate) struct U48(pub u64); impl Writeable for U48 { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { writer.write_all(&be48_to_array(self.0)) } } @@ -304,7 +307,7 @@ impl Readable for U48 { pub(crate) struct BigSize(pub u64); impl Writeable for BigSize { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { match self.0 { 0...0xFC => { (self.0 as u8).write(writer) @@ -368,13 +371,13 @@ macro_rules! impl_writeable_primitive { ($val_type:ty, $len: expr) => { impl Writeable for $val_type { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { writer.write_all(&self.to_be_bytes()) } } impl Writeable for HighZeroBytesDroppedVarInt<$val_type> { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { // Skip any full leading 0 bytes when writing (in BE): writer.write_all(&self.0.to_be_bytes()[(self.0.leading_zeros()/8) as usize..$len]) } @@ -422,7 +425,7 @@ impl_writeable_primitive!(u16, 2); impl Writeable for u8 { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { writer.write_all(&[*self]) } } @@ -437,7 +440,7 @@ impl Readable for u8 { impl Writeable for bool { #[inline] - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { writer.write_all(&[if *self {1} else {0}]) } } @@ -459,7 +462,7 @@ macro_rules! impl_array { impl Writeable for [u8; $size] { #[inline] - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { w.write_all(self) } } @@ -492,7 +495,7 @@ impl Writeable for HashMap V: Writeable { #[inline] - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { (self.len() as u16).write(w)?; for (key, value) in self.iter() { key.write(w)?; @@ -520,7 +523,7 @@ impl Readable for HashMap // Vectors impl Writeable for Vec { #[inline] - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { (self.len() as u16).write(w)?; w.write_all(&self) } @@ -538,7 +541,7 @@ impl Readable for Vec { } impl Writeable for Vec { #[inline] - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { (self.len() as u16).write(w)?; for e in self.iter() { e.write(w)?; @@ -564,7 +567,7 @@ impl Readable for Vec { } impl Writeable for Script { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { (self.len() as u16).write(w)?; w.write_all(self.as_bytes()) } @@ -580,7 +583,7 @@ impl Readable for Script { } impl Writeable for PublicKey { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.serialize().write(w) } #[inline] @@ -600,7 +603,7 @@ impl Readable for PublicKey { } impl Writeable for SecretKey { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { let mut ser = [0; SECRET_KEY_SIZE]; ser.copy_from_slice(&self[..]); ser.write(w) @@ -622,7 +625,7 @@ impl Readable for SecretKey { } impl Writeable for Sha256dHash { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { w.write_all(&self[..]) } } @@ -637,7 +640,7 @@ impl Readable for Sha256dHash { } impl Writeable for Signature { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.serialize_compact().write(w) } #[inline] @@ -657,7 +660,7 @@ impl Readable for Signature { } impl Writeable for PaymentPreimage { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.0.write(w) } } @@ -670,7 +673,7 @@ impl Readable for PaymentPreimage { } impl Writeable for PaymentHash { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.0.write(w) } } @@ -683,7 +686,7 @@ impl Readable for PaymentHash { } impl Writeable for PaymentSecret { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.0.write(w) } } @@ -695,8 +698,20 @@ impl Readable for PaymentSecret { } } +impl Writeable for Box { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + T::write(&**self, w) + } +} + +impl Readable for Box { + fn read(r: &mut R) -> Result { + Ok(Box::new(Readable::read(r)?)) + } +} + impl Writeable for Option { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { match *self { None => 0u8.write(w)?, Some(ref data) => { @@ -722,7 +737,7 @@ impl Readable for Option } impl Writeable for Txid { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { w.write_all(&self[..]) } } @@ -737,7 +752,7 @@ impl Readable for Txid { } impl Writeable for BlockHash { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { w.write_all(&self[..]) } } @@ -752,7 +767,7 @@ impl Readable for BlockHash { } impl Writeable for OutPoint { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.txid.write(w)?; self.vout.write(w)?; Ok(()) @@ -773,7 +788,7 @@ impl Readable for OutPoint { macro_rules! impl_consensus_ser { ($bitcoin_type: ty) => { impl Writeable for $bitcoin_type { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { match self.consensus_encode(WriterWriteAdaptor(writer)) { Ok(_) => Ok(()), Err(e) => Err(e), @@ -785,7 +800,7 @@ macro_rules! impl_consensus_ser { fn read(r: &mut R) -> Result { match consensus::encode::Decodable::consensus_decode(r) { Ok(t) => Ok(t), - Err(consensus::encode::Error::Io(ref e)) if e.kind() == ::std::io::ErrorKind::UnexpectedEof => Err(DecodeError::ShortRead), + Err(consensus::encode::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => Err(DecodeError::ShortRead), Err(consensus::encode::Error::Io(e)) => Err(DecodeError::Io(e.kind())), Err(_) => Err(DecodeError::InvalidValue), } @@ -803,7 +818,7 @@ impl Readable for Mutex { } } impl Writeable for Mutex { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.lock().unwrap().write(w) } } @@ -816,8 +831,24 @@ impl Readable for (A, B) { } } impl Writeable for (A, B) { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, w: &mut W) -> Result<(), io::Error> { self.0.write(w)?; self.1.write(w) } } + +impl Readable for (A, B, C) { + fn read(r: &mut R) -> Result { + let a: A = Readable::read(r)?; + let b: B = Readable::read(r)?; + let c: C = Readable::read(r)?; + Ok((a, b, c)) + } +} +impl Writeable for (A, B, C) { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + self.0.write(w)?; + self.1.write(w)?; + self.2.write(w) + } +}