X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser.rs;h=f0208aad46aebd3a16d242383995073f2de71810;hb=3d479c9de62665214e8589699cdbb8a797b77188;hp=928cc61946e46f358a70e82672b06bda1dec4867;hpb=3bd395f2a8a7398d7bf5ad9b2c7257e64f9c126b;p=rust-lightning diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 928cc619..f0208aad 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -89,6 +89,8 @@ impl Writer for VecWriter { /// Writer that only tracks the amount of data written - useful if you need to calculate the length /// of some data when serialized but don't yet need the full data. +/// +/// (C-not exported) as manual TLV building is not currently supported in bindings pub struct LengthCalculatingWriter(pub usize); impl Writer for LengthCalculatingWriter { #[inline] @@ -100,6 +102,8 @@ impl Writer for LengthCalculatingWriter { /// Essentially [`std::io::Take`] but a bit simpler and with a method to walk the underlying stream /// forward to ensure we always consume exactly the fixed length specified. +/// +/// (C-not exported) as manual TLV building is not currently supported in bindings pub struct FixedLengthReader { read: R, bytes_read: u64, @@ -155,6 +159,8 @@ impl LengthRead for FixedLengthReader { /// A [`Read`] implementation which tracks whether any bytes have been read at all. This allows us to distinguish /// between "EOF reached before we started" and "EOF reached mid-read". +/// +/// (C-not exported) as manual TLV building is not currently supported in bindings pub struct ReadTrackingReader { read: R, /// Returns whether we have read from this reader or not yet. @@ -289,18 +295,40 @@ impl MaybeReadable for T { } /// Wrapper to read a required (non-optional) TLV record. -pub struct OptionDeserWrapper(pub Option); -impl Readable for OptionDeserWrapper { +/// +/// (C-not exported) as manual TLV building is not currently supported in bindings +pub struct RequiredWrapper(pub Option); +impl Readable for RequiredWrapper { #[inline] fn read(reader: &mut R) -> Result { Ok(Self(Some(Readable::read(reader)?))) } } +impl> ReadableArgs for RequiredWrapper { + #[inline] + fn read(reader: &mut R, args: A) -> Result { + Ok(Self(Some(ReadableArgs::read(reader, args)?))) + } +} /// When handling `default_values`, we want to map the default-value T directly -/// to a `OptionDeserWrapper` in a way that works for `field: T = t;` as +/// to a `RequiredWrapper` in a way that works for `field: T = t;` as /// well. Thus, we assume `Into for T` does nothing and use that. -impl From for OptionDeserWrapper { - fn from(t: T) -> OptionDeserWrapper { OptionDeserWrapper(Some(t)) } +impl From for RequiredWrapper { + fn from(t: T) -> RequiredWrapper { RequiredWrapper(Some(t)) } +} + +/// Wrapper to read a required (non-optional) TLV record that may have been upgraded without +/// backwards compat. +/// +/// (C-not exported) as manual TLV building is not currently supported in bindings +pub struct UpgradableRequired(pub Option); +impl MaybeReadable for UpgradableRequired { + #[inline] + fn read(reader: &mut R) -> Result, DecodeError> { + let tlv = MaybeReadable::read(reader)?; + if let Some(tlv) = tlv { return Ok(Some(Self(Some(tlv)))) } + Ok(None) + } } pub(crate) struct U48(pub u64); @@ -573,6 +601,8 @@ impl Readable for [u16; 8] { /// A type for variable-length values within TLV record where the length is encoded as part of the record. /// Used to prevent encoding the length twice. +/// +/// (C-not exported) as manual TLV building is not currently supported in bindings pub struct WithoutLength(pub T); impl Writeable for WithoutLength<&String> { @@ -770,6 +800,7 @@ impl Readable for Vec { } impl_for_vec!(ecdsa::Signature); +impl_for_vec!(crate::ln::channelmanager::MonitorUpdateCompletionAction); impl_for_vec!((A, B), A, B); impl Writeable for Script { @@ -1241,4 +1272,46 @@ mod tests { hostname.write(&mut buf).unwrap(); assert_eq!(Hostname::read(&mut buf.as_slice()).unwrap().as_str(), "test"); } + + #[test] + fn bigsize_encoding_decoding() { + let values = vec![0, 252, 253, 65535, 65536, 4294967295, 4294967296, 18446744073709551615]; + let bytes = vec![ + "00", + "fc", + "fd00fd", + "fdffff", + "fe00010000", + "feffffffff", + "ff0000000100000000", + "ffffffffffffffffff" + ]; + for i in 0..=7 { + let mut stream = crate::io::Cursor::new(::hex::decode(bytes[i]).unwrap()); + assert_eq!(super::BigSize::read(&mut stream).unwrap().0, values[i]); + let mut stream = super::VecWriter(Vec::new()); + super::BigSize(values[i]).write(&mut stream).unwrap(); + assert_eq!(stream.0, ::hex::decode(bytes[i]).unwrap()); + } + let err_bytes = vec![ + "fd00fc", + "fe0000ffff", + "ff00000000ffffffff", + "fd00", + "feffff", + "ffffffffff", + "fd", + "fe", + "ff", + "" + ]; + for i in 0..=9 { + let mut stream = crate::io::Cursor::new(::hex::decode(err_bytes[i]).unwrap()); + if i < 3 { + assert_eq!(super::BigSize::read(&mut stream).err(), Some(crate::ln::msgs::DecodeError::InvalidValue)); + } else { + assert_eq!(super::BigSize::read(&mut stream).err(), Some(crate::ln::msgs::DecodeError::ShortRead)); + } + } + } }