Merge pull request #2417 from tnull/2023-07-max-total-fee
[rust-lightning] / lightning / src / util / ser.rs
index 7e69f72b0eadace9f2896b59f57de7747ce4b74d..af4de88a1a7dda59145b1ea25fa7b7e434519f76 100644 (file)
@@ -44,6 +44,7 @@ use crate::ln::msgs::PartialSignatureWithNonce;
 use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 
 use crate::util::byte_utils::{be48_to_array, slice_to_be48};
+use crate::util::string::UntrustedString;
 
 /// serialization buffer size
 pub const MAX_BUF_SIZE: usize = 64 * 1024;
@@ -357,6 +358,7 @@ 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]
@@ -551,61 +553,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.
@@ -630,6 +621,21 @@ impl<'a> From<&'a String> for WithoutLength<&'a String> {
        fn from(s: &'a String) -> Self { Self(s) }
 }
 
+
+impl Writeable for WithoutLength<&UntrustedString> {
+       #[inline]
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               WithoutLength(&self.0.0).write(w)
+       }
+}
+impl Readable for WithoutLength<UntrustedString> {
+       #[inline]
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let s: WithoutLength<String> = Readable::read(r)?;
+               Ok(Self(UntrustedString(s.0)))
+       }
+}
+
 impl<'a, T: Writeable> Writeable for WithoutLength<&'a Vec<T>> {
        #[inline]
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
@@ -832,6 +838,7 @@ 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!((A, B), A, B);
 impl_writeable_for_vec!(&crate::routing::router::BlindedTail);
@@ -1334,6 +1341,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> {
@@ -1341,6 +1349,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> {