Use `crate::prelude::*` rather than specific imports
[rust-lightning] / lightning / src / util / ser.rs
index 0e510760e62a3725055cecf3394a17b5b879af9a..f88d9f36a72832ef1161c4ff65b48abb9e66a14a 100644 (file)
@@ -17,9 +17,8 @@ use crate::prelude::*;
 use crate::io::{self, Read, Seek, Write};
 use crate::io_extras::{copy, sink};
 use core::hash::Hash;
-use crate::sync::Mutex;
+use crate::sync::{Mutex, RwLock};
 use core::cmp;
-use core::convert::TryFrom;
 use core::ops::Deref;
 
 use alloc::collections::BTreeMap;
@@ -29,13 +28,12 @@ use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SI
 use bitcoin::secp256k1::ecdsa;
 use bitcoin::secp256k1::schnorr;
 use bitcoin::blockdata::constants::ChainHash;
-use bitcoin::blockdata::script::{self, Script};
+use bitcoin::blockdata::script::{self, ScriptBuf};
 use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
 use bitcoin::{consensus, Witness};
 use bitcoin::consensus::Encodable;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{Txid, BlockHash};
-use core::marker::Sized;
 use core::time::Duration;
 use crate::chain::ClaimId;
 use crate::ln::msgs::DecodeError;
@@ -108,14 +106,14 @@ impl Writer for LengthCalculatingWriter {
 /// forward to ensure we always consume exactly the fixed length specified.
 ///
 /// This is not exported to bindings users as manual TLV building is not currently supported in bindings
-pub struct FixedLengthReader<R: Read> {
-       read: R,
+pub struct FixedLengthReader<'a, R: Read> {
+       read: &'a mut R,
        bytes_read: u64,
        total_bytes: u64,
 }
-impl<R: Read> FixedLengthReader<R> {
+impl<'a, R: Read> FixedLengthReader<'a, R> {
        /// Returns a new [`FixedLengthReader`].
-       pub fn new(read: R, total_bytes: u64) -> Self {
+       pub fn new(read: &'a mut R, total_bytes: u64) -> Self {
                Self { read, bytes_read: 0, total_bytes }
        }
 
@@ -136,7 +134,7 @@ impl<R: Read> FixedLengthReader<R> {
                }
        }
 }
-impl<R: Read> Read for FixedLengthReader<R> {
+impl<'a, R: Read> Read for FixedLengthReader<'a, R> {
        #[inline]
        fn read(&mut self, dest: &mut [u8]) -> Result<usize, io::Error> {
                if self.total_bytes == self.bytes_read {
@@ -154,7 +152,7 @@ impl<R: Read> Read for FixedLengthReader<R> {
        }
 }
 
-impl<R: Read> LengthRead for FixedLengthReader<R> {
+impl<'a, R: Read> LengthRead for FixedLengthReader<'a, R> {
        #[inline]
        fn total_bytes(&self) -> u64 {
                self.total_bytes
@@ -199,8 +197,14 @@ pub trait Writeable {
 
        /// Writes `self` out to a `Vec<u8>`.
        fn encode(&self) -> Vec<u8> {
-               let mut msg = VecWriter(Vec::new());
+               let len = self.serialized_length();
+               let mut msg = VecWriter(Vec::with_capacity(len));
                self.write(&mut msg).unwrap();
+               // Note that objects with interior mutability may change size between when we called
+               // serialized_length and when we called write. That's okay, but shouldn't happen during
+               // testing as most of our tests are not threaded.
+               #[cfg(test)]
+               debug_assert_eq!(len, msg.0.len());
                msg.0
        }
 
@@ -211,6 +215,7 @@ pub trait Writeable {
                0u16.write(&mut msg).unwrap();
                self.write(&mut msg).unwrap();
                let len = msg.0.len();
+               debug_assert_eq!(len - 2, self.serialized_length());
                msg.0[..2].copy_from_slice(&(len as u16 - 2).to_be_bytes());
                msg.0
        }
@@ -358,19 +363,20 @@ impl Readable for U48 {
 /// encoded in several different ways, which we must check for at deserialization-time. Thus, if
 /// you're looking for an example of a variable-length integer to use for your own project, move
 /// along, this is a rather poor design.
+#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
 pub struct BigSize(pub u64);
 impl Writeable for BigSize {
        #[inline]
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                match self.0 {
-                       0...0xFC => {
+                       0..=0xFC => {
                                (self.0 as u8).write(writer)
                        },
-                       0xFD...0xFFFF => {
+                       0xFD..=0xFFFF => {
                                0xFDu8.write(writer)?;
                                (self.0 as u16).write(writer)
                        },
-                       0x10000...0xFFFFFFFF => {
+                       0x10000..=0xFFFFFFFF => {
                                0xFEu8.write(writer)?;
                                (self.0 as u32).write(writer)
                        },
@@ -552,61 +558,50 @@ impl Readable for bool {
        }
 }
 
-// u8 arrays
 macro_rules! impl_array {
-       ( $size:expr ) => (
-               impl Writeable for [u8; $size]
-               {
+       ($size:expr, $ty: ty) => (
+               impl Writeable for [$ty; $size] {
                        #[inline]
                        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-                               w.write_all(self)
+                               let mut out = [0; $size * core::mem::size_of::<$ty>()];
+                               for (idx, v) in self.iter().enumerate() {
+                                       let startpos = idx * core::mem::size_of::<$ty>();
+                                       out[startpos..startpos + core::mem::size_of::<$ty>()].copy_from_slice(&v.to_be_bytes());
+                               }
+                               w.write_all(&out)
                        }
                }
 
-               impl Readable for [u8; $size]
-               {
+               impl Readable for [$ty; $size] {
                        #[inline]
                        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-                               let mut buf = [0u8; $size];
+                               let mut buf = [0u8; $size * core::mem::size_of::<$ty>()];
                                r.read_exact(&mut buf)?;
-                               Ok(buf)
+                               let mut res = [0; $size];
+                               for (idx, v) in res.iter_mut().enumerate() {
+                                       let startpos = idx * core::mem::size_of::<$ty>();
+                                       let mut arr = [0; core::mem::size_of::<$ty>()];
+                                       arr.copy_from_slice(&buf[startpos..startpos + core::mem::size_of::<$ty>()]);
+                                       *v = <$ty>::from_be_bytes(arr);
+                               }
+                               Ok(res)
                        }
                }
        );
 }
 
-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!(64); // for ecdsa::Signature and schnorr::Signature
-impl_array!(66); // for MuSig2 nonces
-impl_array!(1300); // for OnionPacket.hop_data
+impl_array!(3, u8); // for rgb, ISO 4712 code
+impl_array!(4, u8); // for IPv4
+impl_array!(12, u8); // for OnionV2
+impl_array!(16, u8); // for IPv6
+impl_array!(32, u8); // for channel id & hmac
+impl_array!(PUBLIC_KEY_SIZE, u8); // for PublicKey
+impl_array!(64, u8); // for ecdsa::Signature and schnorr::Signature
+impl_array!(66, u8); // for MuSig2 nonces
+impl_array!(1300, u8); // 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*2] as u16) << 8 | (buf[idx*2 + 1] as u16)
-               }
-               Ok(res)
-       }
-}
+impl_array!(8, u16);
+impl_array!(32, u16);
 
 /// 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.
@@ -678,14 +673,14 @@ impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
        fn from(v: &'a Vec<T>) -> Self { Self(v) }
 }
 
-impl Writeable for WithoutLength<&Script> {
+impl Writeable for WithoutLength<&ScriptBuf> {
        #[inline]
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                writer.write_all(self.0.as_bytes())
        }
 }
 
-impl Readable for WithoutLength<Script> {
+impl Readable for WithoutLength<ScriptBuf> {
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let v: WithoutLength<Vec<u8>> = Readable::read(r)?;
@@ -752,7 +747,7 @@ macro_rules! impl_for_map {
 }
 
 impl_for_map!(BTreeMap, Ord, |_| BTreeMap::new());
-impl_for_map!(HashMap, Hash, |len| HashMap::with_capacity(len));
+impl_for_map!(HashMap, Hash, |len| hash_map_with_capacity(len));
 
 // HashSet
 impl<T> Writeable for HashSet<T>
@@ -774,7 +769,7 @@ where T: Readable + Eq + Hash
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let len: CollectionLength = Readable::read(r)?;
-               let mut ret = HashSet::with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<T>()));
+               let mut ret = hash_set_with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<T>()));
                for _ in 0..len.0 {
                        if !ret.insert(T::read(r)?) {
                                return Err(DecodeError::InvalidValue)
@@ -823,6 +818,49 @@ macro_rules! impl_for_vec {
        }
 }
 
+// Alternatives to impl_writeable_for_vec/impl_readable_for_vec that add a length prefix to each
+// element in the Vec. Intended to be used when elements have variable lengths.
+macro_rules! impl_writeable_for_vec_with_element_length_prefix {
+       ($ty: ty $(, $name: ident)*) => {
+               impl<$($name : Writeable),*> Writeable for Vec<$ty> {
+                       #[inline]
+                       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+                               CollectionLength(self.len() as u64).write(w)?;
+                               for elem in self.iter() {
+                                       CollectionLength(elem.serialized_length() as u64).write(w)?;
+                                       elem.write(w)?;
+                               }
+                               Ok(())
+                       }
+               }
+       }
+}
+macro_rules! impl_readable_for_vec_with_element_length_prefix {
+       ($ty: ty $(, $name: ident)*) => {
+               impl<$($name : Readable),*> Readable for Vec<$ty> {
+                       #[inline]
+                       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+                               let len: CollectionLength = Readable::read(r)?;
+                               let mut ret = Vec::with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<$ty>()));
+                               for _ in 0..len.0 {
+                                       let elem_len: CollectionLength = Readable::read(r)?;
+                                       let mut elem_reader = FixedLengthReader::new(r, elem_len.0);
+                                       if let Some(val) = MaybeReadable::read(&mut elem_reader)? {
+                                               ret.push(val);
+                                       }
+                               }
+                               Ok(ret)
+                       }
+               }
+       }
+}
+macro_rules! impl_for_vec_with_element_length_prefix {
+       ($ty: ty $(, $name: ident)*) => {
+               impl_writeable_for_vec_with_element_length_prefix!($ty $(, $name)*);
+               impl_readable_for_vec_with_element_length_prefix!($ty $(, $name)*);
+       }
+}
+
 impl Writeable for Vec<u8> {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -850,9 +888,12 @@ impl Readable for Vec<u8> {
 impl_for_vec!(ecdsa::Signature);
 impl_for_vec!(crate::chain::channelmonitor::ChannelMonitorUpdate);
 impl_for_vec!(crate::ln::channelmanager::MonitorUpdateCompletionAction);
+impl_for_vec!(crate::ln::msgs::SocketAddress);
 impl_for_vec!((A, B), A, B);
 impl_writeable_for_vec!(&crate::routing::router::BlindedTail);
 impl_readable_for_vec!(crate::routing::router::BlindedTail);
+impl_for_vec_with_element_length_prefix!(crate::ln::msgs::UpdateAddHTLC);
+impl_writeable_for_vec_with_element_length_prefix!(&crate::ln::msgs::UpdateAddHTLC);
 
 impl Writeable for Vec<Witness> {
        #[inline]
@@ -888,19 +929,19 @@ impl Readable for Vec<Witness> {
        }
 }
 
-impl Writeable for Script {
+impl Writeable for ScriptBuf {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                (self.len() as u16).write(w)?;
                w.write_all(self.as_bytes())
        }
 }
 
-impl Readable for Script {
+impl Readable for ScriptBuf {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let len = <u16 as Readable>::read(r)? as usize;
                let mut buf = vec![0; len];
                r.read_exact(&mut buf)?;
-               Ok(Script::from(buf))
+               Ok(ScriptBuf::from(buf))
        }
 }
 
@@ -1143,7 +1184,7 @@ impl Writeable for ChainHash {
 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[..]))
+               Ok(ChainHash::from(buf))
        }
 }
 
@@ -1205,6 +1246,18 @@ impl<T: Writeable> Writeable for Mutex<T> {
        }
 }
 
+impl<T: Readable> Readable for RwLock<T> {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let t: T = Readable::read(r)?;
+               Ok(RwLock::new(t))
+       }
+}
+impl<T: Writeable> Writeable for RwLock<T> {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               self.read().unwrap().write(w)
+       }
+}
+
 impl<A: Readable, B: Readable> Readable for (A, B) {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let a: A = Readable::read(r)?;
@@ -1287,7 +1340,7 @@ impl Readable for String {
 /// 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)]
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub struct Hostname(String);
 impl Hostname {
        /// Returns the length of the hostname.
@@ -1295,6 +1348,13 @@ impl Hostname {
                (&self.0).len() as u8
        }
 }
+
+impl core::fmt::Display for Hostname {
+       fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+               write!(f, "{}", self.0)?;
+               Ok(())
+       }
+}
 impl Deref for Hostname {
        type Target = String;
 
@@ -1351,6 +1411,7 @@ impl Readable for Hostname {
        }
 }
 
+/// This is not exported to bindings users as `Duration`s are simply mapped as ints.
 impl Writeable for Duration {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -1358,6 +1419,7 @@ impl Writeable for Duration {
                self.subsec_nanos().write(w)
        }
 }
+/// This is not exported to bindings users as `Duration`s are simply mapped as ints.
 impl Readable for Duration {
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
@@ -1371,7 +1433,7 @@ impl Readable for Duration {
 /// if the `Transaction`'s consensus-serialized length is <= u16::MAX.
 ///
 /// Use [`TransactionU16LenLimited::into_transaction`] to convert into the contained `Transaction`.
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub struct TransactionU16LenLimited(Transaction);
 
 impl TransactionU16LenLimited {
@@ -1389,6 +1451,11 @@ impl TransactionU16LenLimited {
        pub fn into_transaction(self) -> Transaction {
                self.0
        }
+
+       /// Returns a reference to the contained `Transaction`
+       pub fn as_transaction(&self) -> &Transaction {
+               &self.0
+       }
 }
 
 impl Writeable for TransactionU16LenLimited {
@@ -1425,9 +1492,10 @@ impl Readable for ClaimId {
 
 #[cfg(test)]
 mod tests {
-       use core::convert::TryFrom;
+       use bitcoin::hashes::hex::FromHex;
        use bitcoin::secp256k1::ecdsa;
        use crate::util::ser::{Readable, Hostname, Writeable};
+       use crate::prelude::*;
 
        #[test]
        fn hostname_conversion() {
@@ -1474,11 +1542,11 @@ mod tests {
                        "ffffffffffffffffff"
                ];
                for i in 0..=7 {
-                       let mut stream = crate::io::Cursor::new(::hex::decode(bytes[i]).unwrap());
+                       let mut stream = crate::io::Cursor::new(<Vec<u8>>::from_hex(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());
+                       assert_eq!(stream.0, <Vec<u8>>::from_hex(bytes[i]).unwrap());
                }
                let err_bytes = vec![
                        "fd00fc",
@@ -1493,7 +1561,7 @@ mod tests {
                        ""
                ];
                for i in 0..=9 {
-                       let mut stream = crate::io::Cursor::new(::hex::decode(err_bytes[i]).unwrap());
+                       let mut stream = crate::io::Cursor::new(<Vec<u8>>::from_hex(err_bytes[i]).unwrap());
                        if i < 3 {
                                assert_eq!(super::BigSize::read(&mut stream).err(), Some(crate::ln::msgs::DecodeError::InvalidValue));
                        } else {