Expose send_payment_for_bolt12_invoice
[rust-lightning] / lightning / src / util / ser.rs
index 0611e6ffb385b66459f93d3cee1fc46ec1f46223..5f109e1a93c64529d09e462899fb539abf662c68 100644 (file)
@@ -19,7 +19,6 @@ use crate::io_extras::{copy, sink};
 use core::hash::Hash;
 use crate::sync::{Mutex, RwLock};
 use core::cmp;
-use core::convert::TryFrom;
 use core::ops::Deref;
 
 use alloc::collections::BTreeMap;
@@ -28,6 +27,7 @@ use bitcoin::secp256k1::{PublicKey, SecretKey};
 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::amount::Amount;
 use bitcoin::blockdata::constants::ChainHash;
 use bitcoin::blockdata::script::{self, ScriptBuf};
 use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
@@ -35,13 +35,12 @@ 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;
 #[cfg(taproot)]
 use crate::ln::msgs::PartialSignatureWithNonce;
-use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+use crate::ln::types::{PaymentPreimage, PaymentHash, PaymentSecret};
 
 use crate::util::byte_utils::{be48_to_array, slice_to_be48};
 use crate::util::string::UntrustedString;
@@ -108,14 +107,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 +135,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 +153,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
@@ -820,6 +819,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> {
@@ -851,13 +893,15 @@ 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]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                (self.len() as u16).write(w)?;
                for witness in self {
-                       (witness.serialized_len() as u16).write(w)?;
+                       (witness.size() as u16).write(w)?;
                        witness.write(w)?;
                }
                Ok(())
@@ -877,7 +921,7 @@ impl Readable for Vec<Witness> {
                        // of witnesses. We'll just do a sanity check for the lengths and error if there is a mismatch.
                        let witness_len = <u16 as Readable>::read(r)? as usize;
                        let witness = <Witness as Readable>::read(r)?;
-                       if witness.serialized_len() != witness_len {
+                       if witness.size() != witness_len {
                                return Err(DecodeError::BadLengthDescriptor);
                        }
                        witnesses.push(witness);
@@ -1102,6 +1146,20 @@ impl<T: Readable> Readable for Option<T>
        }
 }
 
+impl Writeable for Amount {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               self.to_sat().write(w)
+       }
+}
+
+
+impl Readable for Amount {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let amount: u64 = Readable::read(r)?;
+               Ok(Amount::from_sat(amount))
+       }
+}
+
 impl Writeable for Txid {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                w.write_all(&self[..])
@@ -1449,10 +1507,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() {