X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser.rs;h=af4de88a1a7dda59145b1ea25fa7b7e434519f76;hb=1ac53ed02bf26520d3b1a2c3c0e90c8691c83099;hp=36b64b63900b575c477444b43a51d94c25faf051;hpb=70c7161dbead8e4b840e81caacd84e024f9eab21;p=rust-lightning diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 36b64b63..af4de88a 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -29,18 +29,22 @@ 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::Script; +use bitcoin::blockdata::script::{self, Script}; use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut}; -use bitcoin::consensus; +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::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; @@ -48,7 +52,7 @@ pub const MAX_BUF_SIZE: usize = 64 * 1024; /// A simplified version of [`std::io::Write`] that exists largely for backwards compatibility. /// An impl is provided for any type that also impls [`std::io::Write`]. /// -/// (C-not exported) as we only export serialization to/from byte arrays instead +/// This is not exported to bindings users as we only export serialization to/from byte arrays instead pub trait Writer { /// Writes the given buf out. See std::io::Write::write_all for more fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error>; @@ -89,6 +93,8 @@ impl Writer for VecWriter { /// Writer that only tracks the amount of data written - useful if you need to calculate the length /// of some data when serialized but don't yet need the full data. +/// +/// This is not exported to bindings users as manual TLV building is not currently supported in bindings pub struct LengthCalculatingWriter(pub usize); impl Writer for LengthCalculatingWriter { #[inline] @@ -100,6 +106,8 @@ impl Writer for LengthCalculatingWriter { /// Essentially [`std::io::Take`] but a bit simpler and with a method to walk the underlying stream /// 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 { read: R, bytes_read: u64, @@ -155,6 +163,8 @@ impl LengthRead for FixedLengthReader { /// A [`Read`] implementation which tracks whether any bytes have been read at all. This allows us to distinguish /// between "EOF reached before we started" and "EOF reached mid-read". +/// +/// This is not exported to bindings users as manual TLV building is not currently supported in bindings pub struct ReadTrackingReader { read: R, /// Returns whether we have read from this reader or not yet. @@ -182,7 +192,7 @@ impl Read for ReadTrackingReader { /// A trait that various LDK types implement allowing them to be written out to a [`Writer`]. /// -/// (C-not exported) as we only export serialization to/from byte arrays instead +/// This is not exported to bindings users as we only export serialization to/from byte arrays instead pub trait Writeable { /// Writes `self` out to the given [`Writer`]. fn write(&self, writer: &mut W) -> Result<(), io::Error>; @@ -222,7 +232,7 @@ impl<'a, T: Writeable> Writeable for &'a T { /// A trait that various LDK types implement allowing them to be read in from a [`Read`]. /// -/// (C-not exported) as we only export serialization to/from byte arrays instead +/// This is not exported to bindings users as we only export serialization to/from byte arrays instead pub trait Readable where Self: Sized { @@ -240,7 +250,7 @@ pub(crate) trait SeekReadable where Self: Sized { /// A trait that various higher-level LDK types implement allowing them to be read in /// from a [`Read`] given some additional set of arguments which is required to deserialize. /// -/// (C-not exported) as we only export serialization to/from byte arrays instead +/// This is not exported to bindings users as we only export serialization to/from byte arrays instead pub trait ReadableArgs

where Self: Sized { @@ -273,7 +283,7 @@ pub(crate) trait LengthReadable where Self: Sized /// A trait that various LDK types implement allowing them to (maybe) be read in from a [`Read`]. /// -/// (C-not exported) as we only export serialization to/from byte arrays instead +/// This is not exported to bindings users as we only export serialization to/from byte arrays instead pub trait MaybeReadable where Self: Sized { @@ -289,20 +299,42 @@ impl MaybeReadable for T { } /// Wrapper to read a required (non-optional) TLV record. -pub struct RequiredWrapper(pub Option); +/// +/// This is not exported to bindings users as manual TLV building is not currently supported in bindings +pub struct RequiredWrapper(pub Option); impl Readable for RequiredWrapper { #[inline] fn read(reader: &mut R) -> Result { Ok(Self(Some(Readable::read(reader)?))) } } +impl> ReadableArgs for RequiredWrapper { + #[inline] + fn read(reader: &mut R, args: A) -> Result { + Ok(Self(Some(ReadableArgs::read(reader, args)?))) + } +} /// When handling `default_values`, we want to map the default-value T directly /// to a `RequiredWrapper` in a way that works for `field: T = t;` as /// well. Thus, we assume `Into for T` does nothing and use that. -impl From for RequiredWrapper { +impl From for RequiredWrapper { fn from(t: T) -> RequiredWrapper { RequiredWrapper(Some(t)) } } +/// Wrapper to read a required (non-optional) TLV record that may have been upgraded without +/// backwards compat. +/// +/// This is not exported to bindings users as manual TLV building is not currently supported in bindings +pub struct UpgradableRequired(pub Option); +impl MaybeReadable for UpgradableRequired { + #[inline] + fn read(reader: &mut R) -> Result, DecodeError> { + let tlv = MaybeReadable::read(reader)?; + if let Some(tlv) = tlv { return Ok(Some(Self(Some(tlv)))) } + Ok(None) + } +} + pub(crate) struct U48(pub u64); impl Writeable for U48 { #[inline] @@ -326,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] @@ -482,6 +515,10 @@ impl_writeable_primitive!(u128, 16); impl_writeable_primitive!(u64, 8); impl_writeable_primitive!(u32, 4); impl_writeable_primitive!(u16, 2); +impl_writeable_primitive!(i64, 8); +impl_writeable_primitive!(i32, 4); +impl_writeable_primitive!(i16, 2); +impl_writeable_primitive!(i8, 1); impl Writeable for u8 { #[inline] @@ -516,63 +553,55 @@ 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(&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: &mut R) -> Result { - 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!(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(&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: &mut R) -> Result { - 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] as u16) << 8 | (buf[idx + 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. +/// +/// This is not exported to bindings users as manual TLV building is not currently supported in bindings pub struct WithoutLength(pub T); impl Writeable for WithoutLength<&String> { @@ -592,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(&self, w: &mut W) -> Result<(), io::Error> { + WithoutLength(&self.0.0).write(w) + } +} +impl Readable for WithoutLength { + #[inline] + fn read(r: &mut R) -> Result { + let s: WithoutLength = Readable::read(r)?; + Ok(Self(UntrustedString(s.0))) + } +} + impl<'a, T: Writeable> Writeable for WithoutLength<&'a Vec> { #[inline] fn write(&self, writer: &mut W) -> Result<(), io::Error> { @@ -624,6 +668,21 @@ impl<'a, T> From<&'a Vec> for WithoutLength<&'a Vec> { fn from(v: &'a Vec) -> Self { Self(v) } } +impl Writeable for WithoutLength<&Script> { + #[inline] + fn write(&self, writer: &mut W) -> Result<(), io::Error> { + writer.write_all(self.0.as_bytes()) + } +} + +impl Readable for WithoutLength