From d1767cdedfa1cf124cb43abeb00c74e2b43afc8d Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 14 Aug 2024 14:25:56 -0700 Subject: [PATCH] Simplify Readable mutability. In anticipation of the rust-bitcoin upgrade, which incorporates its own `io::Read` implementation, we need to make our usage compatible with dropping `std::io` and `core2::io`. Notably, in version 0.32.2, `bitcoin::io`'s `Read` is no longer implemented for `&mut R where R: Read + ?Sized`, which results in errors anytime `&mut &mut Readable` is passed instead of `&mut Readable`. This commit fixes those instances. --- lightning-rapid-gossip-sync/src/processing.rs | 16 ++++++++-------- lightning/src/blinded_path/mod.rs | 8 +++++--- lightning/src/crypto/streams.rs | 6 +++--- lightning/src/lib.rs | 2 +- lightning/src/ln/msgs.rs | 4 ++-- lightning/src/util/ser.rs | 12 ++++++------ lightning/src/util/ser_macros.rs | 14 +++++++------- 7 files changed, 32 insertions(+), 30 deletions(-) diff --git a/lightning-rapid-gossip-sync/src/processing.rs b/lightning-rapid-gossip-sync/src/processing.rs index 80163472e..7495d1d6a 100644 --- a/lightning-rapid-gossip-sync/src/processing.rs +++ b/lightning-rapid-gossip-sync/src/processing.rs @@ -63,7 +63,7 @@ where } pub(crate) fn update_network_graph_from_byte_stream_no_std( - &self, mut read_cursor: &mut R, current_time_unix: Option, + &self, read_cursor: &mut R, current_time_unix: Option, ) -> Result { log_trace!(self.logger, "Processing RGS data..."); let mut protocol_prefix = [0u8; 3]; @@ -73,7 +73,7 @@ where return Err(DecodeError::UnknownVersion.into()); } - let version: u8 = Readable::read(&mut read_cursor)?; + let version: u8 = Readable::read(read_cursor)?; if version != 1 && version != 2 { return Err(DecodeError::UnknownVersion.into()); } @@ -187,7 +187,7 @@ where for address_index in 0..address_count { let current_byte_count: u8 = Readable::read(read_cursor)?; let mut address_reader = - FixedLengthReader::new(&mut read_cursor, current_byte_count as u64); + FixedLengthReader::new(read_cursor, current_byte_count as u64); if let Ok(current_address) = Readable::read(&mut address_reader) { node_addresses.push(current_address); if address_reader.bytes_remain() { @@ -330,11 +330,11 @@ where } // obtain default values for non-incremental updates - let default_cltv_expiry_delta: u16 = Readable::read(&mut read_cursor)?; - let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?; - let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?; - let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?; - let default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?; + let default_cltv_expiry_delta: u16 = Readable::read(read_cursor)?; + let default_htlc_minimum_msat: u64 = Readable::read(read_cursor)?; + let default_fee_base_msat: u32 = Readable::read(read_cursor)?; + let default_fee_proportional_millionths: u32 = Readable::read(read_cursor)?; + let default_htlc_maximum_msat: u64 = Readable::read(read_cursor)?; let mut previous_channel_direction = None; diff --git a/lightning/src/blinded_path/mod.rs b/lightning/src/blinded_path/mod.rs index e34e64c7a..be94367f9 100644 --- a/lightning/src/blinded_path/mod.rs +++ b/lightning/src/blinded_path/mod.rs @@ -275,14 +275,16 @@ impl Writeable for BlindedPath { impl Readable for BlindedPath { fn read(r: &mut R) -> Result { - let mut first_byte: u8 = Readable::read(r)?; + let first_byte: u8 = Readable::read(r)?; let introduction_node = match first_byte { 0 => IntroductionNode::DirectedShortChannelId(Direction::NodeOne, Readable::read(r)?), 1 => IntroductionNode::DirectedShortChannelId(Direction::NodeTwo, Readable::read(r)?), 2|3 => { use io::Read; - let mut pubkey_read = core::slice::from_mut(&mut first_byte).chain(r.by_ref()); - IntroductionNode::NodeId(Readable::read(&mut pubkey_read)?) + let mut bytes = [0; 33]; + bytes[0] = first_byte; + r.read_exact(&mut bytes[1..])?; + IntroductionNode::NodeId(Readable::read(&mut &bytes[..])?) }, _ => return Err(DecodeError::InvalidValue), }; diff --git a/lightning/src/crypto/streams.rs b/lightning/src/crypto/streams.rs index e8217b8d9..7287eed84 100644 --- a/lightning/src/crypto/streams.rs +++ b/lightning/src/crypto/streams.rs @@ -57,12 +57,12 @@ impl LengthReadableArgs<[u8; 32]> for ChaChaPolyReadAdapter { // Simultaneously read and decrypt an object from a LengthRead, storing it in Self::readable. // LengthRead must be used instead of std::io::Read because we need the total length to separate // out the tag at the end. - fn read(mut r: &mut R, secret: [u8; 32]) -> Result { + fn read(r: &mut R, secret: [u8; 32]) -> Result { if r.total_bytes() < 16 { return Err(DecodeError::InvalidValue) } let mut chacha = ChaCha20Poly1305RFC::new(&secret, &[0; 12], &[]); let decrypted_len = r.total_bytes() - 16; - let s = FixedLengthReader::new(&mut r, decrypted_len); + let s = FixedLengthReader::new(r, decrypted_len); let mut chacha_stream = ChaChaPolyReader { chacha: &mut chacha, read: s }; let readable: T = Readable::read(&mut chacha_stream)?; chacha_stream.read.eat_remaining()?; @@ -194,7 +194,7 @@ mod tests { // Now deserialize the object back and make sure it matches the original. let mut read_adapter: Option> = None; - decode_tlv_stream!(&writer.0[..], { + decode_tlv_stream!(&mut &writer.0[..], { (1, read_adapter, (option: LengthReadableArgs, rho)), }); assert_eq!(writeable, read_adapter.unwrap().readable); diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index 54e394ced..d53f13743 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -144,7 +144,7 @@ pub mod io_extras { Ok(count) } - pub fn read_to_end(mut d: D) -> Result, io::Error> { + pub fn read_to_end(mut d: &mut D) -> Result, io::Error> { let mut result = vec![]; let mut buf = [0u8; 64]; loop { diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 85f1ae0aa..d04cfa7fa 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -2771,8 +2771,8 @@ impl ReadableArgs<(Option, &NS)> for InboundOnionPayload w let mut custom_tlvs = Vec::new(); let tlv_len = BigSize::read(r)?; - let rd = FixedLengthReader::new(r, tlv_len.0); - decode_tlv_stream_with_custom_tlv_decode!(rd, { + let mut rd = FixedLengthReader::new(r, tlv_len.0); + decode_tlv_stream_with_custom_tlv_decode!(&mut rd, { (2, amt, (option, encoding: (u64, HighZeroBytesDroppedBigSize))), (4, cltv_value, (option, encoding: (u32, HighZeroBytesDroppedBigSize))), (6, short_id, option), diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 29c52f6a0..02d57ebf6 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -164,18 +164,18 @@ impl<'a, R: Read> LengthRead for FixedLengthReader<'a, R> { /// 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, +pub struct ReadTrackingReader<'a, R: Read> { + read: &'a mut R, /// Returns whether we have read from this reader or not yet. pub have_read: bool, } -impl ReadTrackingReader { +impl<'a, R: Read> ReadTrackingReader<'a, R> { /// Returns a new [`ReadTrackingReader`]. - pub fn new(read: R) -> Self { + pub fn new(read: &'a mut R) -> Self { Self { read, have_read: false } } } -impl Read for ReadTrackingReader { +impl<'a, R: Read> Read for ReadTrackingReader<'a, R> { #[inline] fn read(&mut self, dest: &mut [u8]) -> Result { match self.read.read(dest) { @@ -669,7 +669,7 @@ impl Readable for WithoutLength> { fn read(mut reader: &mut R) -> Result { let mut values = Vec::new(); loop { - let mut track_read = ReadTrackingReader::new(&mut reader); + let mut track_read = ReadTrackingReader::new(reader); match MaybeReadable::read(&mut track_read) { Ok(Some(v)) => { values.push(v); }, Ok(None) => { }, diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 210d8ff6d..a6f3e08f6 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -456,7 +456,7 @@ macro_rules! _decode_tlv_stream_match_check { /// For example, /// ``` /// # use lightning::decode_tlv_stream; -/// # fn read (stream: R) -> Result<(), lightning::ln::msgs::DecodeError> { +/// # fn read (stream: &mut R) -> Result<(), lightning::ln::msgs::DecodeError> { /// let mut required_value = 0u64; /// let mut optional_value: Option = None; /// decode_tlv_stream!(stream, { @@ -509,7 +509,7 @@ macro_rules! _decode_tlv_stream_range { $(, $decode_custom_tlv: expr)?) => { { use $crate::ln::msgs::DecodeError; let mut last_seen_type: Option = None; - let mut stream_ref = $stream; + let stream_ref = $stream; 'tlv_read: loop { use $crate::util::ser; @@ -519,7 +519,7 @@ macro_rules! _decode_tlv_stream_range { // determine whether we should break or return ShortRead if we get an // UnexpectedEof. This should in every case be largely cosmetic, but its nice to // pass the TLV test vectors exactly, which require this distinction. - let mut tracking_reader = ser::ReadTrackingReader::new(&mut stream_ref); + let mut tracking_reader = ser::ReadTrackingReader::new(stream_ref); match <$crate::util::ser::BigSize as $crate::util::ser::Readable>::read(&mut tracking_reader) { Err(DecodeError::ShortRead) => { if !tracking_reader.have_read { @@ -555,8 +555,8 @@ macro_rules! _decode_tlv_stream_range { last_seen_type = Some(typ.0); // Finally, read the length and value itself: - let length: ser::BigSize = $crate::util::ser::Readable::read(&mut stream_ref)?; - let mut s = ser::FixedLengthReader::new(&mut stream_ref, length.0); + let length: ser::BigSize = $crate::util::ser::Readable::read(stream_ref)?; + let mut s = ser::FixedLengthReader::new(stream_ref, length.0); match typ.0 { $(_t if $crate::_decode_tlv_stream_match_check!(_t, $type, $fieldty) => { $crate::_decode_tlv!($stream, s, $field, $fieldty); @@ -1102,7 +1102,7 @@ macro_rules! impl_writeable_tlv_based_enum { }),* $($tuple_variant_id => { let length: $crate::util::ser::BigSize = $crate::util::ser::Readable::read(reader)?; - let mut s = $crate::util::ser::FixedLengthReader::new(&mut reader, length.0); + let mut s = $crate::util::ser::FixedLengthReader::new(reader, length.0); let res = $crate::util::ser::Readable::read(&mut s)?; if s.bytes_remain() { s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes @@ -1214,7 +1214,7 @@ macro_rules! impl_writeable_tlv_based_enum_upgradable { }),* $($tuple_variant_id => { let length: $crate::util::ser::BigSize = $crate::util::ser::Readable::read(reader)?; - let mut s = $crate::util::ser::FixedLengthReader::new(&mut reader, length.0); + let mut s = $crate::util::ser::FixedLengthReader::new(reader, length.0); let res = $crate::util::ser::Readable::read(&mut s)?; if s.bytes_remain() { s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes -- 2.39.5