From 1f1f82569a1774d2f6cb84e1de3c55dc733022c8 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 14 Sep 2018 17:50:48 -0400 Subject: [PATCH] Simplify serialization a bit by removing the useless newtypes --- fuzz/fuzz_targets/channel_target.rs | 4 +- fuzz/fuzz_targets/msg_targets/utils.rs | 42 ++--- fuzz/fuzz_targets/router_target.rs | 4 +- src/ln/msgs.rs | 83 +++++----- src/ln/peer_handler.rs | 8 +- src/util/ser.rs | 207 ++++++++++--------------- src/util/ser_macros.rs | 8 +- 7 files changed, 158 insertions(+), 198 deletions(-) diff --git a/fuzz/fuzz_targets/channel_target.rs b/fuzz/fuzz_targets/channel_target.rs index 5cf0783c5..e7cc6f76c 100644 --- a/fuzz/fuzz_targets/channel_target.rs +++ b/fuzz/fuzz_targets/channel_target.rs @@ -15,7 +15,7 @@ use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget}; use lightning::chain::transaction::OutPoint; use lightning::util::reset_rng_state; use lightning::util::logger::Logger; -use lightning::util::ser::{Readable, Reader}; +use lightning::util::ser::Readable; mod utils; @@ -121,7 +121,7 @@ pub fn do_test(data: &[u8]) { macro_rules! decode_msg { ($MsgType: path, $len: expr) => {{ - let mut reader = Reader::new(::std::io::Cursor::new(get_slice!($len))); + let mut reader = ::std::io::Cursor::new(get_slice!($len)); match <($MsgType)>::read(&mut reader) { Ok(msg) => msg, Err(e) => match e { diff --git a/fuzz/fuzz_targets/msg_targets/utils.rs b/fuzz/fuzz_targets/msg_targets/utils.rs index c1bcd8f36..52ea530cf 100644 --- a/fuzz/fuzz_targets/msg_targets/utils.rs +++ b/fuzz/fuzz_targets/msg_targets/utils.rs @@ -4,16 +4,16 @@ macro_rules! test_msg { ($MsgType: path, $data: ident) => { { - use lightning::util::ser::{Writer, Reader, Writeable, Readable}; - let mut r = Reader::new(::std::io::Cursor::new($data)); + use lightning::util::ser::{Writeable, Readable}; + let mut r = ::std::io::Cursor::new($data); if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) { - let p = r.get_ref().position() as usize; - let mut w = Writer::new(::std::io::Cursor::new(vec![])); + let p = r.position() as usize; + let mut w = ::std::io::Cursor::new(vec![]); msg.write(&mut w).unwrap(); - let buf = w.into_inner().into_inner(); + let buf = w.into_inner(); assert_eq!(buf.len(), p); - assert_eq!(&r.into_inner().into_inner()[..p], &buf[..p]); + assert_eq!(&r.into_inner()[..p], &buf[..p]); } } } @@ -23,10 +23,10 @@ macro_rules! test_msg { macro_rules! test_msg_simple { ($MsgType: path, $data: ident) => { { - use lightning::util::ser::{Writer, Reader, Writeable, Readable}; - let mut r = Reader::new(::std::io::Cursor::new($data)); + use lightning::util::ser::{Writeable, Readable}; + let mut r = ::std::io::Cursor::new($data); if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) { - msg.write(&mut Writer::new(::std::io::Cursor::new(vec![]))).unwrap(); + msg.write(&mut ::std::io::Cursor::new(vec![])).unwrap(); } } } @@ -36,14 +36,14 @@ macro_rules! test_msg_simple { macro_rules! test_msg_exact { ($MsgType: path, $data: ident) => { { - use lightning::util::ser::{Writer, Reader, Writeable, Readable}; - let mut r = Reader::new(::std::io::Cursor::new($data)); + use lightning::util::ser::{Writeable, Readable}; + let mut r = ::std::io::Cursor::new($data); if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) { - let mut w = Writer::new(::std::io::Cursor::new(vec![])); + let mut w = ::std::io::Cursor::new(vec![]); msg.write(&mut w).unwrap(); - let buf = w.into_inner().into_inner(); - assert_eq!(&r.into_inner().into_inner()[..], &buf[..]); + let buf = w.into_inner(); + assert_eq!(&r.into_inner()[..], &buf[..]); } } } @@ -53,17 +53,17 @@ macro_rules! test_msg_exact { macro_rules! test_msg_hole { ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => { { - use lightning::util::ser::{Writer, Reader, Writeable, Readable}; - let mut r = Reader::new(::std::io::Cursor::new($data)); + use lightning::util::ser::{Writeable, Readable}; + let mut r = ::std::io::Cursor::new($data); if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) { - let mut w = Writer::new(::std::io::Cursor::new(vec![])); + let mut w = ::std::io::Cursor::new(vec![]); msg.write(&mut w).unwrap(); - let p = w.get_ref().position() as usize; + let p = w.position() as usize; - let buf = w.into_inner().into_inner(); + let buf = w.into_inner(); assert_eq!(buf.len(),p); - assert_eq!(&r.get_ref().get_ref()[..$hole], &buf[..$hole]); - assert_eq!(&r.get_ref().get_ref()[$hole+$hole_len..p], &buf[$hole+$hole_len..]); + assert_eq!(&r.get_ref()[..$hole], &buf[..$hole]); + assert_eq!(&r.get_ref()[$hole+$hole_len..p], &buf[$hole+$hole_len..]); } } } diff --git a/fuzz/fuzz_targets/router_target.rs b/fuzz/fuzz_targets/router_target.rs index fc3e9e9ba..4ccd32746 100644 --- a/fuzz/fuzz_targets/router_target.rs +++ b/fuzz/fuzz_targets/router_target.rs @@ -12,7 +12,7 @@ use lightning::ln::msgs::{RoutingMessageHandler}; use lightning::ln::router::{Router, RouteHint}; use lightning::util::reset_rng_state; use lightning::util::logger::Logger; -use lightning::util::ser::{Reader, Readable}; +use lightning::util::ser::Readable; use secp256k1::key::PublicKey; use secp256k1::Secp256k1; @@ -121,7 +121,7 @@ pub fn do_test(data: &[u8]) { macro_rules! decode_msg { ($MsgType: path, $len: expr) => {{ - let mut reader = Reader::new(::std::io::Cursor::new(get_slice!($len))); + let mut reader = ::std::io::Cursor::new(get_slice!($len)); match <($MsgType)>::read(&mut reader) { Ok(msg) => msg, Err(e) => match e { diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index b4432c708..a96f34f51 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -7,10 +7,11 @@ use bitcoin::blockdata::script::Script; use std::error::Error; use std::{cmp, fmt}; +use std::io::Read; use std::result::Result; use util::{byte_utils, internal_traits, events}; -use util::ser::{Readable, Reader, Writeable, Writer}; +use util::ser::{Readable, Writeable, Writer}; pub trait MsgEncodable { fn encode(&self) -> Vec; @@ -1728,8 +1729,8 @@ impl_writeable!(AnnouncementSignatures, { bitcoin_signature }); -impl Writeable for ChannelReestablish { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for ChannelReestablish { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.channel_id.write(w)?; self.next_local_commitment_number.write(w)?; self.next_remote_commitment_number.write(w)?; @@ -1741,8 +1742,8 @@ impl Writeable for ChannelReestablish { } } -impl Readable for ChannelReestablish{ - fn read(r: &mut Reader) -> Result { +impl Readable for ChannelReestablish{ + fn read(r: &mut R) -> Result { Ok(Self { channel_id: Readable::read(r)?, next_local_commitment_number: Readable::read(r)?, @@ -1871,8 +1872,8 @@ impl_writeable!(OnionErrorPacket, { data }); -impl Writeable for OnionPacket { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for OnionPacket { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.version.write(w)?; match self.public_key { Ok(pubkey) => pubkey.write(w)?, @@ -1884,8 +1885,8 @@ impl Writeable for OnionPacket { } } -impl Readable for OnionPacket { - fn read(r: &mut Reader) -> Result { +impl Readable for OnionPacket { + fn read(r: &mut R) -> Result { Ok(OnionPacket { version: Readable::read(r)?, public_key: { @@ -1908,8 +1909,8 @@ impl_writeable!(UpdateAddHTLC, { onion_routing_packet }); -impl Writeable for OnionRealm0HopData { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for OnionRealm0HopData { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.short_channel_id.write(w)?; self.amt_to_forward.write(w)?; self.outgoing_cltv_value.write(w)?; @@ -1918,8 +1919,8 @@ impl Writeable for OnionRealm0HopData { } } -impl Readable for OnionRealm0HopData { - fn read(r: &mut Reader) -> Result { +impl Readable for OnionRealm0HopData { + fn read(r: &mut R) -> Result { Ok(OnionRealm0HopData { short_channel_id: Readable::read(r)?, amt_to_forward: Readable::read(r)?, @@ -1932,8 +1933,8 @@ impl Readable for OnionRealm0HopData { } } -impl Writeable for OnionHopData { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for OnionHopData { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.realm.write(w)?; self.data.write(w)?; self.hmac.write(w)?; @@ -1941,8 +1942,8 @@ impl Writeable for OnionHopData { } } -impl Readable for OnionHopData { - fn read(r: &mut Reader) -> Result { +impl Readable for OnionHopData { + fn read(r: &mut R) -> Result { Ok(OnionHopData { realm: { let r: u8 = Readable::read(r)?; @@ -1957,16 +1958,16 @@ impl Readable for OnionHopData { } } -impl Writeable for Ping { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for Ping { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.ponglen.write(w)?; vec![0u8; self.byteslen as usize].write(w)?; // size-unchecked write Ok(()) } } -impl Readable for Ping { - fn read(r: &mut Reader) -> Result { +impl Readable for Ping { + fn read(r: &mut R) -> Result { Ok(Ping { ponglen: Readable::read(r)?, byteslen: { @@ -1978,15 +1979,15 @@ impl Readable for Ping { } } -impl Writeable for Pong { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for Pong { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { vec![0u8; self.byteslen as usize].write(w)?; // size-unchecked write Ok(()) } } -impl Readable for Pong { - fn read(r: &mut Reader) -> Result { +impl Readable for Pong { + fn read(r: &mut R) -> Result { Ok(Pong { byteslen: { let byteslen = Readable::read(r)?; @@ -1997,8 +1998,8 @@ impl Readable for Pong { } } -impl Writeable for UnsignedChannelAnnouncement { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for UnsignedChannelAnnouncement { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.features.write(w)?; self.chain_hash.write(w)?; self.short_channel_id.write(w)?; @@ -2011,8 +2012,8 @@ impl Writeable for UnsignedChannelAnnouncement { } } -impl Readable for UnsignedChannelAnnouncement { - fn read(r: &mut Reader) -> Result { +impl Readable for UnsignedChannelAnnouncement { + fn read(r: &mut R) -> Result { Ok(Self { features: { let f: GlobalFeatures = Readable::read(r)?; @@ -2044,8 +2045,8 @@ impl_writeable!(ChannelAnnouncement,{ contents }); -impl Writeable for UnsignedChannelUpdate { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for UnsignedChannelUpdate { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.chain_hash.write(w)?; self.short_channel_id.write(w)?; self.timestamp.write(w)?; @@ -2059,8 +2060,8 @@ impl Writeable for UnsignedChannelUpdate { } } -impl Readable for UnsignedChannelUpdate { - fn read(r: &mut Reader) -> Result { +impl Readable for UnsignedChannelUpdate { + fn read(r: &mut R) -> Result { Ok(Self { chain_hash: Readable::read(r)?, short_channel_id: Readable::read(r)?, @@ -2084,16 +2085,16 @@ impl_writeable!(ChannelUpdate, { contents }); -impl Writeable for ErrorMessage { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for ErrorMessage { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.channel_id.write(w)?; self.data.as_bytes().to_vec().write(w)?; // write with size prefix Ok(()) } } -impl Readable for ErrorMessage { - fn read(r: &mut Reader) -> Result { +impl Readable for ErrorMessage { + fn read(r: &mut R) -> Result { Ok(Self { channel_id: Readable::read(r)?, data: { @@ -2110,8 +2111,8 @@ impl Readable for ErrorMessage { } } -impl Writeable for UnsignedNodeAnnouncement { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for UnsignedNodeAnnouncement { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.features.write(w)?; self.timestamp.write(w)?; self.node_id.write(w)?; @@ -2156,8 +2157,8 @@ impl Writeable for UnsignedNodeAnnouncement { } } -impl Readable for UnsignedNodeAnnouncement { - fn read(r: &mut Reader) -> Result { +impl Readable for UnsignedNodeAnnouncement { + fn read(r: &mut R) -> Result { let features: GlobalFeatures = Readable::read(r)?; if features.requires_unknown_bits() { return Err(DecodeError::UnknownRequiredFeature); diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 81ae8ca38..52abecb4b 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -1,7 +1,7 @@ use secp256k1::key::{SecretKey,PublicKey}; use ln::msgs; -use util::ser::{Writer, Reader, Writeable, Readable}; +use util::ser::{Writeable, Readable}; use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use util::byte_utils; use util::events::{EventsProvider,Event}; @@ -114,10 +114,10 @@ pub struct PeerManager { macro_rules! encode_msg { ($msg: expr, $msg_code: expr) => {{ - let mut w = Writer::new(::std::io::Cursor::new(vec![])); + let mut w = ::std::io::Cursor::new(vec![]); 0u16.write(&mut w).unwrap(); $msg.write(&mut w).unwrap(); - let mut msg = w.into_inner().into_inner(); + let mut msg = w.into_inner(); let len = msg.len(); msg[..2].copy_from_slice(&byte_utils::be16_to_array(len as u16 - 2)); msg @@ -437,7 +437,7 @@ impl PeerManager { // Need an init message as first message return Err(PeerHandleError{ no_connection_possible: false }); } - let mut reader = Reader::new(::std::io::Cursor::new(&msg_data[2..])); + let mut reader = ::std::io::Cursor::new(&msg_data[2..]); match msg_type { // Connection control: 16 => { diff --git a/src/util/ser.rs b/src/util/ser.rs index cd5e6a0db..7f795fe46 100644 --- a/src/util/ser.rs +++ b/src/util/ser.rs @@ -1,5 +1,5 @@ use std::result::Result; -use std::io::{Read, Write}; +use std::io::Read; use std::collections::HashMap; use std::hash::Hash; use std::mem; @@ -15,147 +15,106 @@ use util::byte_utils::{be64_to_array, be32_to_array, be16_to_array, slice_to_be1 const MAX_BUF_SIZE: usize = 64 * 1024; -/// A struct that holds an std::io::Write-impl'ing object and implements various -/// rust-lightning-specific write functions. -pub struct Writer { writer: W } -/// A struct that holds an std::io::Read-impl'ing object and implements various -/// rust-lightning-specific read functions. -pub struct Reader { reader: R } +/// A trait that is similar to std::io::Write. +/// An impl is provided for any type that also impls std::io::Write. +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>; +} + +impl Writer for W { + fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { + ::write_all(self, buf) + } +} /// A trait that various rust-lightning types implement allowing them to be written out to a Writer -pub trait Writeable { +pub trait Writeable { /// Writes self out to the given Writer - fn write(&self, writer: &mut Writer) -> Result<(), DecodeError>; + fn write(&self, writer: &mut W) -> Result<(), DecodeError>; } -/// A trait that various rust-lightning types implement allowing them to be read in from a Reader +/// 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 Reader - fn read(reader: &mut Reader) -> Result; + /// Reads a Self in from the given Read + fn read(reader: &mut R) -> Result; } -impl Writer { - /// Creates a new Writer from an std::io::Write-impl'ing object - pub fn new(writer: W) -> Writer { - return Writer { writer } - } - /// Consumes this object and returns the original writer - pub fn into_inner(self) -> W { self.writer } - /// Gets a reference to the original writer - pub fn get_ref(&self) -> &W { &self.writer } - fn write_u64(&mut self, v: u64) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&be64_to_array(v))?) - } - fn write_u32(&mut self, v: u32) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&be32_to_array(v))?) - } - fn write_u16(&mut self, v: u16) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&be16_to_array(v))?) - } - fn write_u8(&mut self, v: u8) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&[v])?) - } - fn write_bool(&mut self, v: bool) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&[if v {1} else {0}])?) - } - pub(crate) fn write_all(&mut self, v: &[u8]) -> Result<(), DecodeError> { - Ok(self.writer.write_all(v)?) +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<(), DecodeError> { + Ok(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 Reader { - /// Creates a new Reader from an std::io::Read-impl'ing object - pub fn new(reader: R) -> Reader { - return Reader { reader } - } - /// Consumes this object and returns the original reader - pub fn into_inner(self) -> R { self.reader } - /// Gets a reference to the original reader - pub fn get_ref(&self) -> &R { &self.reader } +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); - fn read_u64(&mut self) -> Result { - let mut buf = [0; 8]; - self.reader.read_exact(&mut buf)?; - Ok(slice_to_be64(&buf)) - } - - fn read_u32(&mut self) -> Result { - let mut buf = [0; 4]; - self.reader.read_exact(&mut buf)?; - Ok(slice_to_be32(&buf)) - } - - fn read_u16(&mut self) -> Result { - let mut buf = [0; 2]; - self.reader.read_exact(&mut buf)?; - Ok(slice_to_be16(&buf)) +impl Writeable for u8 { + #[inline] + fn write(&self, writer: &mut W) -> Result<(), DecodeError> { + Ok(writer.write_all(&[*self])?) } - - fn read_u8(&mut self) -> Result { +} +impl Readable for u8 { + #[inline] + fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; - self.reader.read_exact(&mut buf)?; + reader.read_exact(&mut buf)?; Ok(buf[0]) } - fn read_bool(&mut self) -> Result { +} + +impl Writeable for bool { + #[inline] + fn write(&self, writer: &mut W) -> Result<(), DecodeError> { + Ok(writer.write_all(&[if *self {1} else {0}])?) + } +} +impl Readable for bool { + #[inline] + fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; - self.reader.read_exact(&mut buf)?; + reader.read_exact(&mut buf)?; if buf[0] != 0 && buf[0] != 1 { return Err(DecodeError::InvalidValue); } Ok(buf[0] == 1) } - pub(crate) fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DecodeError> { - Ok(self.reader.read_exact(buf)?) - } - pub(crate) fn read_to_end(&mut self, buf: &mut Vec) -> Result { - Ok(self.reader.read_to_end(buf)?) - } } -macro_rules! impl_writeable_primitive { - ($val_type:ty, $meth_write:ident, $meth_read:ident) => { - impl Writeable for $val_type { - #[inline] - fn write(&self, writer: &mut Writer) -> Result<(), DecodeError> { - writer.$meth_write(*self) - } - } - impl Readable for $val_type { - #[inline] - fn read(reader: &mut Reader) -> Result<$val_type, DecodeError> { - reader.$meth_read() - } - } - } -} - -impl_writeable_primitive!(u64, write_u64, read_u64); -impl_writeable_primitive!(u32, write_u32, read_u32); -impl_writeable_primitive!(u16, write_u16, read_u16); -impl_writeable_primitive!(u8, write_u8, read_u8); -impl_writeable_primitive!(bool, write_bool, read_bool); - // u8 arrays macro_rules! impl_array { ( $size:expr ) => ( - impl Writeable for [u8; $size] - where W: Write + impl Writeable for [u8; $size] { #[inline] - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { w.write_all(self)?; Ok(()) } } - impl Readable for [u8; $size] - where R: Read + impl Readable for [u8; $size] { #[inline] - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let mut buf = [0u8; $size]; r.read_exact(&mut buf)?; Ok(buf) @@ -172,12 +131,12 @@ impl_array!(1300); // for OnionPacket.hop_data // HashMap impl Writeable for HashMap - where W: Write, + where W: Writer, K: Writeable + Eq + Hash, V: Writeable { #[inline] - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { (self.len() as u16).write(w)?; for (key, value) in self.iter() { key.write(w)?; @@ -193,7 +152,7 @@ impl Readable for HashMap V: Readable { #[inline] - fn read(r: &mut Reader) -> Result { + 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 { @@ -204,9 +163,9 @@ impl Readable for HashMap } // Vectors -impl> Writeable for Vec { +impl> Writeable for Vec { #[inline] - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { let byte_size = (self.len() as usize) .checked_mul(mem::size_of::()) .ok_or(DecodeError::BadLengthDescriptor)?; @@ -224,7 +183,7 @@ impl> Writeable for Vec { impl> Readable for Vec { #[inline] - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let len: u16 = Readable::read(r)?; let byte_size = (len as usize) .checked_mul(mem::size_of::()) @@ -238,14 +197,14 @@ impl> Readable for Vec { } } -impl Writeable for Script { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for Script { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.to_bytes().to_vec().write(w) } } impl Readable for Script { - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let len = >::read(r)? as usize; let mut buf = vec![0; len]; r.read_exact(&mut buf)?; @@ -253,8 +212,8 @@ impl Readable for Script { } } -impl Writeable for Option