Merge pull request #1738 from jkczyz/2022-09-invoice-request
[rust-lightning] / lightning / src / util / ser.rs
index 7c4ba7fd50f99888745a6944971c10f3f00f77a9..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,9 @@ 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};
@@ -219,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.
 ///
@@ -425,6 +433,7 @@ macro_rules! impl_writeable_primitive {
        }
 }
 
+impl_writeable_primitive!(u128, 16);
 impl_writeable_primitive!(u64, 8);
 impl_writeable_primitive!(u32, 4);
 impl_writeable_primitive!(u16, 2);
@@ -491,7 +500,7 @@ 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] {
@@ -656,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)?;
@@ -667,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)?;
@@ -756,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),
                }