Merge pull request #1957 from TheBlueMatt/2022-01-mon-ref-lockorder
[rust-lightning] / lightning / src / util / ser.rs
index 6b17ec7ed6b10344f69028001e028d69b6cc99d4..a656604d458c492c17e8fc9a206c20afe4faa5ef 100644 (file)
@@ -8,20 +8,25 @@
 // licenses.
 
 //! A very simple serialization framework which is used to serialize/deserialize messages as well
-//! as ChannelsManagers and ChannelMonitors.
-
-use prelude::*;
-use io::{self, Read, Write};
-use io_extras::{copy, sink};
+//! as [`ChannelManager`]s and [`ChannelMonitor`]s.
+//!
+//! [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
+//! [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
+
+use crate::prelude::*;
+use crate::io::{self, Read, Seek, Write};
+use crate::io_extras::{copy, sink};
 use core::hash::Hash;
-use sync::Mutex;
+use crate::sync::Mutex;
 use core::cmp;
 use core::convert::TryFrom;
 use core::ops::Deref;
 
 use bitcoin::secp256k1::{PublicKey, SecretKey};
-use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE};
-use bitcoin::secp256k1::ecdsa::Signature;
+use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE, SCHNORR_SIGNATURE_SIZE};
+use bitcoin::secp256k1::ecdsa;
+use bitcoin::secp256k1::schnorr;
+use bitcoin::blockdata::constants::ChainHash;
 use bitcoin::blockdata::script::Script;
 use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
 use bitcoin::consensus;
@@ -30,16 +35,16 @@ use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{Txid, BlockHash};
 use core::marker::Sized;
 use core::time::Duration;
-use ln::msgs::DecodeError;
-use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+use crate::ln::msgs::DecodeError;
+use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 
-use util::byte_utils::{be48_to_array, slice_to_be48};
+use crate::util::byte_utils::{be48_to_array, slice_to_be48};
 
 /// serialization buffer size
 pub const MAX_BUF_SIZE: usize = 64 * 1024;
 
-/// A simplified version of std::io::Write that exists largely for backwards compatibility.
-/// An impl is provided for any type that also impls std::io::Write.
+/// A simplified version of [`std::io::Write`] that exists largely for backwards compatibility.
+/// An impl is provided for any type that also impls [`std::io::Write`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait Writer {
@@ -82,7 +87,7 @@ 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.
-pub(crate) struct LengthCalculatingWriter(pub usize);
+pub struct LengthCalculatingWriter(pub usize);
 impl Writer for LengthCalculatingWriter {
        #[inline]
        fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {
@@ -91,23 +96,26 @@ impl Writer for LengthCalculatingWriter {
        }
 }
 
-/// Essentially std::io::Take but a bit simpler and with a method to walk the underlying stream
+/// 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.
-pub(crate) struct FixedLengthReader<R: Read> {
+pub struct FixedLengthReader<R: Read> {
        read: R,
        bytes_read: u64,
        total_bytes: u64,
 }
 impl<R: Read> FixedLengthReader<R> {
+       /// Returns a new [`FixedLengthReader`].
        pub fn new(read: R, total_bytes: u64) -> Self {
                Self { read, bytes_read: 0, total_bytes }
        }
 
+       /// Returns whether some bytes are remaining or not.
        #[inline]
        pub fn bytes_remain(&mut self) -> bool {
                self.bytes_read != self.total_bytes
        }
 
+       /// Consumes the remaining bytes.
        #[inline]
        pub fn eat_remaining(&mut self) -> Result<(), DecodeError> {
                copy(self, &mut sink()).unwrap();
@@ -143,13 +151,15 @@ impl<R: Read> LengthRead for FixedLengthReader<R> {
        }
 }
 
-/// A Read which tracks whether any bytes have been read at all. This allows us to distinguish
+/// 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".
-pub(crate) struct ReadTrackingReader<R: Read> {
+pub struct ReadTrackingReader<R: Read> {
        read: R,
+       /// Returns whether we have read from this reader or not yet.
        pub have_read: bool,
 }
 impl<R: Read> ReadTrackingReader<R> {
+       /// Returns a new [`ReadTrackingReader`].
        pub fn new(read: R) -> Self {
                Self { read, have_read: false }
        }
@@ -168,21 +178,21 @@ impl<R: Read> Read for ReadTrackingReader<R> {
        }
 }
 
-/// A trait that various rust-lightning types implement allowing them to be written out to a Writer
+/// A trait that various LDK types implement allowing them to be written out to a [`Writer`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait Writeable {
-       /// Writes self out to the given Writer
+       /// Writes `self` out to the given [`Writer`].
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error>;
 
-       /// Writes self out to a Vec<u8>
+       /// Writes `self` out to a `Vec<u8>`.
        fn encode(&self) -> Vec<u8> {
                let mut msg = VecWriter(Vec::new());
                self.write(&mut msg).unwrap();
                msg.0
        }
 
-       /// Writes self out to a Vec<u8>
+       /// Writes `self` out to a `Vec<u8>`.
        #[cfg(test)]
        fn encode_with_len(&self) -> Vec<u8> {
                let mut msg = VecWriter(Vec::new());
@@ -208,57 +218,64 @@ impl<'a, T: Writeable> Writeable for &'a T {
        fn write<W: Writer>(&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
+/// A trait that various LDK types implement allowing them to be read in from a [`Read`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait Readable
        where Self: Sized
 {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError>;
 }
 
-/// 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.
+/// A trait that various LDK types implement allowing them to be read in from a
+/// [`Read`]` + `[`Seek`].
+pub(crate) trait SeekReadable where Self: Sized {
+       /// Reads a `Self` in from the given [`Read`].
+       fn read<R: Read + Seek>(reader: &mut R) -> Result<Self, DecodeError>;
+}
+
+/// A trait that various higher-level LDK types implement allowing them to be read in
+/// from a [`Read`] given some additional set of arguments which is required to deserialize.
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait ReadableArgs<P>
        where Self: Sized
 {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read>(reader: &mut R, params: P) -> Result<Self, DecodeError>;
 }
 
-/// A std::io::Read that also provides the total bytes available to read.
+/// A [`std::io::Read`] that also provides the total bytes available to be read.
 pub(crate) trait LengthRead: Read {
-       /// The total number of bytes available to read.
+       /// The total number of bytes available to be read.
        fn total_bytes(&self) -> u64;
 }
 
-/// A trait that various higher-level rust-lightning types implement allowing them to be read in
+/// A trait that various higher-level LDK types implement allowing them to be read in
 /// from a Read given some additional set of arguments which is required to deserialize, requiring
 /// the implementer to provide the total length of the read.
 pub(crate) trait LengthReadableArgs<P> where Self: Sized
 {
-       /// Reads a Self in from the given LengthRead
+       /// Reads a `Self` in from the given [`LengthRead`].
        fn read<R: LengthRead>(reader: &mut R, params: P) -> Result<Self, DecodeError>;
 }
 
-/// A trait that various higher-level rust-lightning types implement allowing them to be read in
-/// from a Read, requiring the implementer to provide the total length of the read.
+/// A trait that various higher-level LDK types implement allowing them to be read in
+/// from a [`Read`], requiring the implementer to provide the total length of the read.
 pub(crate) trait LengthReadable where Self: Sized
 {
-       /// Reads a Self in from the given LengthRead
+       /// Reads a `Self` in from the given [`LengthRead`].
        fn read<R: LengthRead>(reader: &mut R) -> Result<Self, DecodeError>;
 }
 
-/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a Read
+/// A trait that various LDK types implement allowing them to (maybe) be read in from a [`Read`].
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
 pub trait MaybeReadable
        where Self: Sized
 {
-       /// Reads a Self in from the given Read
+       /// Reads a `Self` in from the given [`Read`].
        fn read<R: Read>(reader: &mut R) -> Result<Option<Self>, DecodeError>;
 }
 
@@ -269,62 +286,21 @@ impl<T: Readable> MaybeReadable for T {
        }
 }
 
-/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a
-/// Read, given some additional set of arguments which is required to deserialize.
-///
-/// (C-not exported) as we only export serialization to/from byte arrays instead
-pub trait MaybeReadableArgs<P> {
-       /// Reads a Self in from the given Read
-       fn read<R: Read>(reader: &mut R, params: P) -> Result<Option<Self>, DecodeError> where Self: Sized;
-}
-
-pub(crate) struct OptionDeserWrapper<T: Readable>(pub Option<T>);
+/// Wrapper to read a required (non-optional) TLV record.
+pub struct OptionDeserWrapper<T: Readable>(pub Option<T>);
 impl<T: Readable> Readable for OptionDeserWrapper<T> {
        #[inline]
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
                Ok(Self(Some(Readable::read(reader)?)))
        }
 }
-/// When handling default_values, we want to map the default-value T directly
-/// to a OptionDeserWrapper<T> in a way that works for `field: T = t;` as
+/// When handling `default_values`, we want to map the default-value T directly
+/// to a `OptionDeserWrapper<T>` in a way that works for `field: T = t;` as
 /// well. Thus, we assume `Into<T> for T` does nothing and use that.
 impl<T: Readable> From<T> for OptionDeserWrapper<T> {
        fn from(t: T) -> OptionDeserWrapper<T> { OptionDeserWrapper(Some(t)) }
 }
 
-/// Wrapper to write each element of a Vec with no length prefix
-pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec<T>);
-impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> {
-       #[inline]
-       fn write<W: Writer>(&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<T>(pub Vec<T>);
-impl<T: MaybeReadable> Readable for VecReadWrapper<T> {
-       #[inline]
-       fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
-               let mut values = Vec::new();
-               loop {
-                       let mut track_read = ReadTrackingReader::new(&mut reader);
-                       match MaybeReadable::read(&mut track_read) {
-                               Ok(Some(v)) => { values.push(v); },
-                               Ok(None) => { },
-                               // 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),
-                       }
-               }
-               Ok(Self(values))
-       }
-}
-
 pub(crate) struct U48(pub u64);
 impl Writeable for U48 {
        #[inline]
@@ -341,7 +317,7 @@ impl Readable for U48 {
        }
 }
 
-/// Lightning TLV uses a custom variable-length integer called BigSize. It is similar to Bitcoin's
+/// Lightning TLV uses a custom variable-length integer called `BigSize`. It is similar to Bitcoin's
 /// variable-length integers except that it is serialized in big-endian instead of little-endian.
 ///
 /// Like Bitcoin's variable-length integer, it exhibits ambiguity in that certain values can be
@@ -407,8 +383,8 @@ impl Readable for BigSize {
 
 /// In TLV we occasionally send fields which only consist of, or potentially end with, a
 /// variable-length integer which is simply truncated by skipping high zero bytes. This type
-/// encapsulates such integers implementing Readable/Writeable for them.
-#[cfg_attr(test, derive(PartialEq, Debug))]
+/// encapsulates such integers implementing [`Readable`]/[`Writeable`] for them.
+#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
 pub(crate) struct HighZeroBytesDroppedBigSize<T>(pub T);
 
 macro_rules! impl_writeable_primitive {
@@ -460,9 +436,13 @@ macro_rules! impl_writeable_primitive {
                                }
                        }
                }
+               impl From<$val_type> for HighZeroBytesDroppedBigSize<$val_type> {
+                       fn from(val: $val_type) -> Self { Self(val) }
+               }
        }
 }
 
+impl_writeable_primitive!(u128, 16);
 impl_writeable_primitive!(u64, 8);
 impl_writeable_primitive!(u32, 4);
 impl_writeable_primitive!(u16, 2);
@@ -523,15 +503,91 @@ macro_rules! impl_array {
        );
 }
 
-impl_array!(3); // for rgb
+impl_array!(3); // for rgb, ISO 4712 code
 impl_array!(4); // for IPv4
 impl_array!(12); // for OnionV2
 impl_array!(16); // for IPv6
 impl_array!(32); // for channel id & hmac
 impl_array!(PUBLIC_KEY_SIZE); // for PublicKey
-impl_array!(COMPACT_SIGNATURE_SIZE); // for Signature
+impl_array!(64); // for ecdsa::Signature and schnorr::Signature
 impl_array!(1300); // for OnionPacket.hop_data
 
+impl Writeable for [u16; 8] {
+       #[inline]
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               for v in self.iter() {
+                       w.write_all(&v.to_be_bytes())?
+               }
+               Ok(())
+       }
+}
+
+impl Readable for [u16; 8] {
+       #[inline]
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let mut buf = [0u8; 16];
+               r.read_exact(&mut buf)?;
+               let mut res = [0u16; 8];
+               for (idx, v) in res.iter_mut().enumerate() {
+                       *v = (buf[idx] as u16) << 8 | (buf[idx + 1] as u16)
+               }
+               Ok(res)
+       }
+}
+
+/// 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.
+pub struct WithoutLength<T>(pub T);
+
+impl Writeable for WithoutLength<&String> {
+       #[inline]
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               w.write_all(self.0.as_bytes())
+       }
+}
+impl Readable for WithoutLength<String> {
+       #[inline]
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let v: WithoutLength<Vec<u8>> = Readable::read(r)?;
+               Ok(Self(String::from_utf8(v.0).map_err(|_| DecodeError::InvalidValue)?))
+       }
+}
+impl<'a> From<&'a String> for WithoutLength<&'a String> {
+       fn from(s: &'a String) -> Self { Self(s) }
+}
+
+impl<'a, T: Writeable> Writeable for WithoutLength<&'a Vec<T>> {
+       #[inline]
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               for ref v in self.0.iter() {
+                       v.write(writer)?;
+               }
+               Ok(())
+       }
+}
+
+impl<T: MaybeReadable> Readable for WithoutLength<Vec<T>> {
+       #[inline]
+       fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
+               let mut values = Vec::new();
+               loop {
+                       let mut track_read = ReadTrackingReader::new(&mut reader);
+                       match MaybeReadable::read(&mut track_read) {
+                               Ok(Some(v)) => { values.push(v); },
+                               Ok(None) => { },
+                               // 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),
+                       }
+               }
+               Ok(Self(values))
+       }
+}
+impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
+       fn from(v: &'a Vec<T>) -> Self { Self(v) }
+}
+
 // HashMap
 impl<K, V> Writeable for HashMap<K, V>
        where K: Writeable + Eq + Hash,
@@ -618,7 +674,7 @@ impl Readable for Vec<u8> {
                Ok(ret)
        }
 }
-impl Writeable for Vec<Signature> {
+impl Writeable for Vec<ecdsa::Signature> {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                (self.len() as u16).write(w)?;
@@ -629,7 +685,7 @@ impl Writeable for Vec<Signature> {
        }
 }
 
-impl Readable for Vec<Signature> {
+impl Readable for Vec<ecdsa::Signature> {
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let len: u16 = Readable::read(r)?;
@@ -718,20 +774,32 @@ impl Readable for Sha256dHash {
        }
 }
 
-impl Writeable for Signature {
+impl Writeable for ecdsa::Signature {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                self.serialize_compact().write(w)
        }
-       #[inline]
-       fn serialized_length(&self) -> usize {
-               COMPACT_SIGNATURE_SIZE
-       }
 }
 
-impl Readable for Signature {
+impl Readable for ecdsa::Signature {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let buf: [u8; COMPACT_SIGNATURE_SIZE] = Readable::read(r)?;
-               match Signature::from_compact(&buf) {
+               match ecdsa::Signature::from_compact(&buf) {
+                       Ok(sig) => Ok(sig),
+                       Err(_) => return Err(DecodeError::InvalidValue),
+               }
+       }
+}
+
+impl Writeable for schnorr::Signature {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               self.as_ref().write(w)
+       }
+}
+
+impl Readable for schnorr::Signature {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let buf: [u8; SCHNORR_SIGNATURE_SIZE] = Readable::read(r)?;
+               match schnorr::Signature::from_slice(&buf) {
                        Ok(sig) => Ok(sig),
                        Err(_) => return Err(DecodeError::InvalidValue),
                }
@@ -846,6 +914,19 @@ impl Readable for BlockHash {
        }
 }
 
+impl Writeable for ChainHash {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               w.write_all(self.as_bytes())
+       }
+}
+
+impl Readable for ChainHash {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let buf: [u8; 32] = Readable::read(r)?;
+               Ok(ChainHash::from(&buf[..]))
+       }
+}
+
 impl Writeable for OutPoint {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                self.txid.write(w)?;
@@ -964,8 +1045,10 @@ impl Readable for String {
 /// Only the character set and length will be validated.
 /// The character set consists of ASCII alphanumeric characters, hyphens, and periods.
 /// Its length is guaranteed to be representable by a single byte.
-/// This serialization is used by BOLT 7 hostnames.
-#[derive(Clone, Debug, PartialEq)]
+/// This serialization is used by [`BOLT 7`] hostnames.
+///
+/// [`BOLT 7`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Hostname(String);
 impl Hostname {
        /// Returns the length of the hostname.
@@ -1048,7 +1131,7 @@ impl Readable for Duration {
 #[cfg(test)]
 mod tests {
        use core::convert::TryFrom;
-       use util::ser::{Readable, Hostname, Writeable};
+       use crate::util::ser::{Readable, Hostname, Writeable};
 
        #[test]
        fn hostname_conversion() {