X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser.rs;h=38133d59670dd5c717a3d1dc850fe3296fc316c6;hb=32ca8ec13e0928cbb4f7067a3fb6d41f39691d1c;hp=44fdd1c0cf4d3097d27e7abebb83e0a397f0ac86;hpb=569f9038bec1f0ba09cfb01c35222a9365ee77d6;p=rust-lightning diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 44fdd1c0..38133d59 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -11,7 +11,7 @@ use std::cmp; use secp256k1::Signature; use secp256k1::key::{PublicKey, SecretKey}; use bitcoin::blockdata::script::Script; -use bitcoin::blockdata::transaction::{OutPoint, Transaction}; +use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut}; use bitcoin::consensus; use bitcoin::consensus::Encodable; use bitcoin_hashes::sha256d::Hash as Sha256dHash; @@ -173,22 +173,28 @@ pub trait Writeable { } /// 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 +pub trait Readable + where Self: Sized { /// Reads a Self in from the given Read - fn read(reader: &mut R) -> Result; + 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 +pub trait ReadableArgs

+ where Self: Sized { /// Reads a Self in from the given Read - fn read(reader: &mut R, params: P) -> Result; + fn read(reader: &mut R, params: P) -> Result; +} + +/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a Read +pub trait MaybeReadable + where Self: Sized +{ + /// Reads a Self in from the given Read + fn read(reader: &mut R) -> Result, DecodeError>; } pub(crate) struct U48(pub u64); @@ -198,9 +204,9 @@ impl Writeable for U48 { writer.write_all(&be48_to_array(self.0)) } } -impl Readable for U48 { +impl Readable for U48 { #[inline] - fn read(reader: &mut R) -> Result { + fn read(reader: &mut R) -> Result { let mut buf = [0; 6]; reader.read_exact(&mut buf)?; Ok(U48(slice_to_be48(&buf))) @@ -237,9 +243,9 @@ impl Writeable for BigSize { } } } -impl Readable for BigSize { +impl Readable for BigSize { #[inline] - fn read(reader: &mut R) -> Result { + fn read(reader: &mut R) -> Result { let n: u8 = Readable::read(reader)?; match n { 0xFF => { @@ -292,17 +298,17 @@ macro_rules! impl_writeable_primitive { writer.write_all(&$meth_write(self.0)[(self.0.leading_zeros()/8) as usize..$len]) } } - impl Readable for $val_type { + impl Readable for $val_type { #[inline] - fn read(reader: &mut R) -> Result<$val_type, DecodeError> { + fn read(reader: &mut R) -> Result<$val_type, DecodeError> { let mut buf = [0; $len]; reader.read_exact(&mut buf)?; Ok($meth_read(&buf)) } } - impl Readable for HighZeroBytesDroppedVarInt<$val_type> { + impl Readable for HighZeroBytesDroppedVarInt<$val_type> { #[inline] - fn read(reader: &mut R) -> Result, DecodeError> { + fn read(reader: &mut R) -> Result, DecodeError> { // We need to accept short reads (read_len == 0) as "EOF" and handle them as simply // the high bytes being dropped. To do so, we start reading into the middle of buf // and then convert the appropriate number of bytes with extra high bytes out of @@ -337,9 +343,9 @@ impl Writeable for u8 { writer.write_all(&[*self]) } } -impl Readable for u8 { +impl Readable for u8 { #[inline] - fn read(reader: &mut R) -> Result { + fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; reader.read_exact(&mut buf)?; Ok(buf[0]) @@ -352,9 +358,9 @@ impl Writeable for bool { writer.write_all(&[if *self {1} else {0}]) } } -impl Readable for bool { +impl Readable for bool { #[inline] - fn read(reader: &mut R) -> Result { + fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; reader.read_exact(&mut buf)?; if buf[0] != 0 && buf[0] != 1 { @@ -375,10 +381,10 @@ macro_rules! impl_array { } } - impl Readable for [u8; $size] + impl Readable for [u8; $size] { #[inline] - fn read(r: &mut R) -> Result { + fn read(r: &mut R) -> Result { let mut buf = [0u8; $size]; r.read_exact(&mut buf)?; Ok(buf) @@ -413,13 +419,12 @@ impl Writeable for HashMap } } -impl Readable for HashMap - where R: Read, - K: Readable + Eq + Hash, - V: Readable +impl Readable for HashMap + where K: Readable + Eq + Hash, + V: Readable { #[inline] - fn read(r: &mut R) -> 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 { @@ -438,9 +443,9 @@ impl Writeable for Vec { } } -impl Readable for Vec { +impl Readable for Vec { #[inline] - fn read(r: &mut R) -> Result { + 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); @@ -459,9 +464,9 @@ impl Writeable for Vec { } } -impl Readable for Vec { +impl Readable for Vec { #[inline] - fn read(r: &mut R) -> Result { + fn read(r: &mut R) -> Result { let len: u16 = Readable::read(r)?; let byte_size = (len as usize) .checked_mul(33) @@ -482,9 +487,9 @@ impl Writeable for Script { } } -impl Readable for Script { - fn read(r: &mut R) -> Result { - let len = >::read(r)? as usize; +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)) @@ -497,8 +502,8 @@ impl Writeable for PublicKey { } } -impl Readable for PublicKey { - fn read(r: &mut R) -> Result { +impl Readable for PublicKey { + fn read(r: &mut R) -> Result { let buf: [u8; 33] = Readable::read(r)?; match PublicKey::from_slice(&buf) { Ok(key) => Ok(key), @@ -515,8 +520,8 @@ impl Writeable for SecretKey { } } -impl Readable for SecretKey { - fn read(r: &mut R) -> Result { +impl Readable for SecretKey { + fn read(r: &mut R) -> Result { let buf: [u8; 32] = Readable::read(r)?; match SecretKey::from_slice(&buf) { Ok(key) => Ok(key), @@ -531,8 +536,8 @@ impl Writeable for Sha256dHash { } } -impl Readable for Sha256dHash { - fn read(r: &mut R) -> Result { +impl Readable for Sha256dHash { + fn read(r: &mut R) -> Result { use bitcoin_hashes::Hash; let buf: [u8; 32] = Readable::read(r)?; @@ -546,8 +551,8 @@ impl Writeable for Signature { } } -impl Readable for Signature { - fn read(r: &mut R) -> Result { +impl Readable for Signature { + fn read(r: &mut R) -> Result { let buf: [u8; 64] = Readable::read(r)?; match Signature::from_compact(&buf) { Ok(sig) => Ok(sig), @@ -562,8 +567,8 @@ impl Writeable for PaymentPreimage { } } -impl Readable for PaymentPreimage { - fn read(r: &mut R) -> Result { +impl Readable for PaymentPreimage { + fn read(r: &mut R) -> Result { let buf: [u8; 32] = Readable::read(r)?; Ok(PaymentPreimage(buf)) } @@ -575,8 +580,8 @@ impl Writeable for PaymentHash { } } -impl Readable for PaymentHash { - fn read(r: &mut R) -> Result { +impl Readable for PaymentHash { + fn read(r: &mut R) -> Result { let buf: [u8; 32] = Readable::read(r)?; Ok(PaymentHash(buf)) } @@ -595,12 +600,10 @@ impl Writeable for Option { } } -impl Readable for Option - where R: Read, - T: Readable +impl Readable for Option { - fn read(r: &mut R) -> Result { - match >::read(r)? { + fn read(r: &mut R) -> Result { + match ::read(r)? { 0 => Ok(None), 1 => Ok(Some(Readable::read(r)?)), _ => return Err(DecodeError::InvalidValue), @@ -616,8 +619,8 @@ impl Writeable for OutPoint { } } -impl Readable for OutPoint { - fn read(r: &mut R) -> Result { +impl Readable for OutPoint { + fn read(r: &mut R) -> Result { let txid = Readable::read(r)?; let vout = Readable::read(r)?; Ok(OutPoint { @@ -627,29 +630,35 @@ impl Readable for OutPoint { } } -impl Writeable for Transaction { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self.consensus_encode(WriterWriteAdaptor(writer)) { - Ok(_) => Ok(()), - Err(consensus::encode::Error::Io(e)) => Err(e), - Err(_) => panic!("We shouldn't get a consensus::encode::Error unless our Write generated an std::io::Error"), +macro_rules! impl_consensus_ser { + ($bitcoin_type: ty) => { + impl Writeable for $bitcoin_type { + fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + match self.consensus_encode(WriterWriteAdaptor(writer)) { + Ok(_) => Ok(()), + Err(consensus::encode::Error::Io(e)) => Err(e), + Err(_) => panic!("We shouldn't get a consensus::encode::Error unless our Write generated an std::io::Error"), + } + } } - } -} -impl Readable for Transaction { - 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(e)) => Err(DecodeError::Io(e)), - Err(_) => Err(DecodeError::InvalidValue), + impl Readable for $bitcoin_type { + 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(e)) => Err(DecodeError::Io(e)), + Err(_) => Err(DecodeError::InvalidValue), + } + } } } } +impl_consensus_ser!(Transaction); +impl_consensus_ser!(TxOut); -impl> Readable for Mutex { - fn read(r: &mut R) -> Result { +impl Readable for Mutex { + fn read(r: &mut R) -> Result { let t: T = Readable::read(r)?; Ok(Mutex::new(t)) } @@ -660,8 +669,8 @@ impl Writeable for Mutex { } } -impl, B: Readable> Readable for (A, B) { - fn read(r: &mut R) -> Result { +impl Readable for (A, B) { + fn read(r: &mut R) -> Result { let a: A = Readable::read(r)?; let b: B = Readable::read(r)?; Ok((a, b))