Skip to content

Commit

Permalink
Read ChannelUpdateInfo without failing.
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull committed Jul 12, 2022
1 parent 2634839 commit e3fe348
Showing 1 changed file with 132 additions and 69 deletions.
201 changes: 132 additions & 69 deletions lightning/src/routing/gossip.rs
Expand Up @@ -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<R: io::Read>(reader: &mut R) -> Result<Option<Self>, 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<u32> = None;
let mut enabled: Option<bool> = None;
let mut cltv_expiry_delta: Option<u16> = None;
let mut htlc_minimum_msat: Option<u64> = None;
let mut htlc_maximum_msat: Option<Option<u64>> = None;
let mut fees: Option<RoutingFees> = None;
let mut last_update_message: Option<Option<ChannelUpdate>> = 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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -2925,6 +2923,71 @@ mod tests {
assert_eq!(format_bytes_alias(b"\xFFI <heart>\0LDK!"), "\u{FFFD}I <heart>");
assert_eq!(format_bytes_alias(b"\xFFI <heart>\tLDK!"), "\u{FFFD}I <heart>\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<u8> = Vec::new();
assert!(chan_update_info.write(&mut buf).is_ok());

let read_chan_update_info_result: Option<ChannelUpdateInfo> = ::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<u8> = 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<u8> = 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"))]
Expand Down

0 comments on commit e3fe348

Please sign in to comment.