diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 1203afa3736..be06d588dc4 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -635,64 +635,84 @@ impl Writeable for ChannelUpdateInfo { (2, self.enabled, required), (4, self.cltv_expiry_delta, required), (6, self.htlc_minimum_msat, required), - (8, self.htlc_maximum_msat, required), + (8, Some(self.htlc_maximum_msat), required), (10, self.fees, required), (12, self.last_update_message, required), }); Ok(()) } - - #[inline] - fn serialized_length(&self) -> usize { - use util::ser::BigSize; - let len = { - #[allow(unused_mut)] - let mut len = ::util::ser::LengthCalculatingWriter(0); - get_varint_length_prefixed_tlv_length!(len, 0, self.last_update, required); - get_varint_length_prefixed_tlv_length!(len, 2, self.enabled, required); - get_varint_length_prefixed_tlv_length!(len, 4, self.cltv_expiry_delta, required); - get_varint_length_prefixed_tlv_length!(len, 6, self.htlc_minimum_msat, required); - get_varint_length_prefixed_tlv_length!(len, 8, self.htlc_maximum_msat, required); - get_varint_length_prefixed_tlv_length!(len, 10, self.fees, required); - get_varint_length_prefixed_tlv_length!(len, 12, self.last_update_message, required); - len.0 - }; - let mut len_calc = ::util::ser::LengthCalculatingWriter(0); - BigSize(len as u64).write(&mut len_calc).expect("No in-memory data may fail to serialize"); - len + len_calc.0 - } - } impl MaybeReadable for ChannelUpdateInfo { fn read(reader: &mut R) -> Result, DecodeError> { - init_tlv_field_var!(last_update, required); - init_tlv_field_var!(enabled, required); - init_tlv_field_var!(cltv_expiry_delta, required); - init_tlv_field_var!(htlc_minimum_msat, required); - init_tlv_field_var!(htlc_maximum_msat, required); - init_tlv_field_var!(fees, required); - init_tlv_field_var!(last_update_message, required); + macro_rules! read_channel_update_tlv_fields { + ($reader: expr, {$(($type: expr, $field: ident)),* $(,)*}) => {{ + let mut stream_ref = $reader; + $({ + if stream_ref.bytes_remain() { + let tlv_type_res: Result<::util::ser::BigSize, DecodeError> = ::util::ser::Readable::read(stream_ref); + $field = if let Ok(ref tlv_type) = tlv_type_res { + println!("GOT TYPE: {}", tlv_type.0); + assert_eq!(tlv_type.0, $type); + + let tlv_len_res: Result<::util::ser::BigSize, DecodeError> = ::util::ser::Readable::read(&mut stream_ref); + if let Ok(ref tlv_len) = tlv_len_res { + println!("GOT LEN: {}", tlv_len.0); + let mut s = ::util::ser::FixedLengthReader::new(&mut stream_ref, tlv_len.0); + let tlv_value_res = ::util::ser::Readable::read(&mut s); + let _ = s.eat_remaining(); + tlv_value_res.ok() + } else { + None + } + } else { + None + }; + } + })* + }}; + } - read_tlv_fields!(reader, { - (0, last_update, required), - (2, enabled, required), - (4, cltv_expiry_delta, required), - (6, htlc_minimum_msat, required), - (8, htlc_maximum_msat, required), - (10, fees, required), - (12, last_update_message, required) + let outer_tlv_len: ::util::ser::BigSize = ::util::ser::Readable::read(reader)?; + if outer_tlv_len.0 == 0 { + return Ok(None); + } + let mut outer_fixed_reader = ::util::ser::FixedLengthReader::new(reader, outer_tlv_len.0); + + + let mut last_update: Option = None; + let mut enabled: Option = None; + let mut cltv_expiry_delta: Option = None; + let mut htlc_minimum_msat: Option = None; + let mut htlc_maximum_msat: Option> = None; + let mut fees: Option = None; + let mut last_update_message: Option> = None; + + read_channel_update_tlv_fields!(&mut outer_fixed_reader, { + (0, last_update), + (2, enabled), + (4, cltv_expiry_delta), + (6, htlc_minimum_msat), + (8, htlc_maximum_msat), + (10, fees), + (12, last_update_message), }); - - if let Some(htlc_maximum_msat) = htlc_maximum_msat.0 { + let decoding_success = last_update.is_some() && enabled.is_some() && + cltv_expiry_delta.is_some() && htlc_minimum_msat.is_some() && + htlc_maximum_msat.is_some() && fees.is_some() && + last_update_message.is_some(); + + outer_fixed_reader.eat_remaining()?; + if decoding_success { + println!("DECODING SUCCESS"); Ok(Some(ChannelUpdateInfo { - last_update: init_tlv_based_struct_field!(last_update, required), - enabled: init_tlv_based_struct_field!(enabled, required), - cltv_expiry_delta: init_tlv_based_struct_field!(cltv_expiry_delta, required), - htlc_minimum_msat: init_tlv_based_struct_field!(htlc_minimum_msat, required), - htlc_maximum_msat, - fees: init_tlv_based_struct_field!(fees, required), - last_update_message: init_tlv_based_struct_field!(last_update_message, required), + last_update: last_update.unwrap(), + enabled: enabled.unwrap(), + cltv_expiry_delta: cltv_expiry_delta.unwrap(), + htlc_minimum_msat: htlc_minimum_msat.unwrap(), + htlc_maximum_msat: htlc_maximum_msat.unwrap().unwrap(), + fees: fees.unwrap(), + last_update_message: last_update_message.unwrap(), })) } else { Ok(None) @@ -791,28 +811,6 @@ impl Writeable for ChannelInfo { }); Ok(()) } - - #[inline] - fn serialized_length(&self) -> usize { - use util::ser::BigSize; - let len = { - #[allow(unused_mut)] - let mut len = ::util::ser::LengthCalculatingWriter(0); - get_varint_length_prefixed_tlv_length!(len, 0, self.features, required); - get_varint_length_prefixed_tlv_length!(len, 1, self.announcement_received_time, (default_value, 0)); - get_varint_length_prefixed_tlv_length!(len, 2, self.node_one, required); - get_varint_length_prefixed_tlv_length!(len, 4, self.one_to_two, required); - get_varint_length_prefixed_tlv_length!(len, 6, self.node_two, required); - get_varint_length_prefixed_tlv_length!(len, 8, self.two_to_one, required); - get_varint_length_prefixed_tlv_length!(len, 10, self.capacity_sats, required); - get_varint_length_prefixed_tlv_length!(len, 12, self.announcement_message, required); - len.0 - }; - let mut len_calc = ::util::ser::LengthCalculatingWriter(0); - BigSize(len as u64).write(&mut len_calc).expect("No in-memory data may fail to serialize"); - len + len_calc.0 - } - } impl Readable for ChannelInfo { @@ -1799,7 +1797,7 @@ mod tests { use chain; use ln::PaymentHash; use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; - use routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY}; + use routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo}; use ln::msgs::{Init, RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement, UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, ReplyChannelRange, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT}; @@ -2925,6 +2923,71 @@ mod tests { assert_eq!(format_bytes_alias(b"\xFFI \0LDK!"), "\u{FFFD}I "); assert_eq!(format_bytes_alias(b"\xFFI \tLDK!"), "\u{FFFD}I \u{FFFD}LDK!"); } + + #[test] + fn written_channel_info_is_readable() { + let chanmon_cfgs = ::ln::functional_test_utils::create_chanmon_cfgs(2); + let node_cfgs = ::ln::functional_test_utils::create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = ::ln::functional_test_utils::create_node_chanmgrs(2, &node_cfgs, &[None, None, None, None]); + let nodes = ::ln::functional_test_utils::create_network(2, &node_cfgs, &node_chanmgrs); + + // First make sure we can encode/decode ChannelUpdateInfo. + let chan_update_info = ChannelUpdateInfo { + last_update: 23, + enabled: true, + cltv_expiry_delta: 42, + htlc_minimum_msat: 1234, + htlc_maximum_msat: 5678, + fees: RoutingFees { base_msat: 9, proportional_millionths: 10 }, + last_update_message: None, + }; + + let mut buf: Vec = Vec::new(); + assert!(chan_update_info.write(&mut buf).is_ok()); + + let read_chan_update_info_result: Option = ::util::ser::MaybeReadable::read(&mut buf.as_slice()).unwrap(); + if let Some(read_chan_update_info) = read_chan_update_info_result { + assert_eq!(chan_update_info, read_chan_update_info); + } else { + panic!(); + } + + // Then check we can encode/decode ChannelInfo without ChannelUpdateInfo fields present. + let chan_info_none_updates = ChannelInfo { + features: ChannelFeatures::known(), + node_one: NodeId::from_pubkey(&nodes[0].node.get_our_node_id()), + one_to_two: None, + node_two: NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), + two_to_one: None, + capacity_sats: None, + announcement_message: None, + announcement_received_time: 87654, + }; + + let mut buf: Vec = Vec::new(); + assert!(chan_info_none_updates.write(&mut buf).is_ok()); + + let read_chan_info: ChannelInfo = ::util::ser::Readable::read(&mut buf.as_slice()).unwrap(); + assert_eq!(chan_info_none_updates, read_chan_info); + + // Finally check we can encode/decode ChannelInfo with ChannelUpdateInfo fields present. + let chan_info_some_updates = ChannelInfo { + features: ChannelFeatures::known(), + node_one: NodeId::from_pubkey(&nodes[0].node.get_our_node_id()), + one_to_two: Some(chan_update_info.clone()), + node_two: NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), + two_to_one: Some(chan_update_info.clone()), + capacity_sats: None, + announcement_message: None, + announcement_received_time: 87654, + }; + + let mut buf: Vec = Vec::new(); + assert!(chan_info_some_updates.write(&mut buf).is_ok()); + + let read_chan_info: ChannelInfo = ::util::ser::Readable::read(&mut buf.as_slice()).unwrap(); + assert_eq!(chan_info_some_updates, read_chan_info); + } } #[cfg(all(test, feature = "_bench_unstable"))]