Merge pull request #1738 from jkczyz/2022-09-invoice-request
[rust-lightning] / lightning / src / util / ser.rs
index b9722325eed04dfab630487da04e0f6b0877b2f3..02d4a81b39e4418daf45f6cb6fc6f61180b1785e 100644 (file)
@@ -11,7 +11,7 @@
 //! as ChannelsManagers and ChannelMonitors.
 
 use crate::prelude::*;
-use crate::io::{self, Read, Write};
+use crate::io::{self, Read, Seek, Write};
 use crate::io_extras::{copy, sink};
 use core::hash::Hash;
 use crate::sync::Mutex;
@@ -20,8 +20,10 @@ 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;
@@ -218,6 +220,13 @@ pub trait Readable
        fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError>;
 }
 
+/// A trait that various rust-lightning 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 rust-lightning types implement allowing them to be read in
 /// from a Read given some additional set of arguments which is required to deserialize.
 ///
@@ -366,8 +375,7 @@ 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, Eq))]
-#[derive(Clone, Debug)]
+#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
 pub(crate) struct HighZeroBytesDroppedBigSize<T>(pub T);
 
 macro_rules! impl_writeable_primitive {
@@ -419,9 +427,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);
@@ -482,13 +494,13 @@ 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] {
@@ -518,6 +530,23 @@ impl Readable for [u16; 8] {
 /// Used to prevent encoding the length twice.
 pub(crate) 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> {
@@ -636,7 +665,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)?;
@@ -647,7 +676,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)?;
@@ -736,20 +765,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),
                }
@@ -864,6 +905,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)?;