Skip to content

Commit a8bfa10

Browse files
committed
Make DirectionalChannelInfo optional
1 parent 77a2aee commit a8bfa10

File tree

2 files changed

+129
-84
lines changed

2 files changed

+129
-84
lines changed

lightning/src/routing/network_graph.rs

Lines changed: 107 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,16 @@ impl RoutingMessageHandler for NetGraphMsgHandler {
149149
while result.len() < batch_amount as usize {
150150
if let Some((_, ref chan)) = iter.next() {
151151
if chan.announcement_message.is_some() {
152-
result.push((chan.announcement_message.clone().unwrap(),
153-
chan.one_to_two.last_update_message.clone(),
154-
chan.two_to_one.last_update_message.clone()));
152+
let chan_announcement = chan.announcement_message.clone().unwrap();
153+
let mut one_to_two_announcement: Option<msgs::ChannelUpdate> = None;
154+
let mut two_to_one_announcement: Option<msgs::ChannelUpdate> = None;
155+
if let Some(one_to_two) = chan.one_to_two.as_ref() {
156+
one_to_two_announcement = one_to_two.last_update_message.clone();
157+
}
158+
if let Some(two_to_one) = chan.two_to_one.as_ref() {
159+
two_to_one_announcement = two_to_one.last_update_message.clone();
160+
}
161+
result.push((chan_announcement, one_to_two_announcement, two_to_one_announcement));
155162
} else {
156163
// TODO: We may end up sending un-announced channel_updates if we are sending
157164
// initial sync data while receiving announce/updates for this channel.
@@ -246,11 +253,9 @@ impl ReadableArgs<NetGraphMsgHandlerReadArgs> for NetGraphMsgHandler {
246253
}
247254
}
248255

249-
#[derive(PartialEq)]
256+
#[derive(PartialEq, Debug)]
250257
/// Details regarding one direction of a channel
251258
pub struct DirectionalChannelInfo {
252-
/// A node from which the channel direction starts
253-
pub src_node_id: PublicKey,
254259
/// When the last update to the channel direction was issued
255260
pub last_update: u32,
256261
/// Whether the channel can be currently used for payments
@@ -267,13 +272,12 @@ pub struct DirectionalChannelInfo {
267272

268273
impl std::fmt::Display for DirectionalChannelInfo {
269274
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
270-
write!(f, "src_node_id {}, last_update {}, enabled {}, cltv_expiry_delta {}, htlc_minimum_msat {}, fees {:?}", log_pubkey!(self.src_node_id), self.last_update, self.enabled, self.cltv_expiry_delta, self.htlc_minimum_msat, self.fees)?;
275+
write!(f, "last_update {}, enabled {}, cltv_expiry_delta {}, htlc_minimum_msat {}, fees {:?}", self.last_update, self.enabled, self.cltv_expiry_delta, self.htlc_minimum_msat, self.fees)?;
271276
Ok(())
272277
}
273278
}
274279

275280
impl_writeable!(DirectionalChannelInfo, 0, {
276-
src_node_id,
277281
last_update,
278282
enabled,
279283
cltv_expiry_delta,
@@ -287,10 +291,14 @@ impl_writeable!(DirectionalChannelInfo, 0, {
287291
pub struct ChannelInfo {
288292
/// Protocol features of a channel communicated during its announcement
289293
pub features: ChannelFeatures,
294+
/// Source node of one of the directions of a channel
295+
pub one_src_node: PublicKey,
290296
/// Details regarding one of the directions of a channel
291-
pub one_to_two: DirectionalChannelInfo,
297+
pub one_to_two: Option<DirectionalChannelInfo>,
298+
/// Source node of another direction of a channel
299+
pub two_src_node: PublicKey,
292300
/// Details regarding another direction of a channel
293-
pub two_to_one: DirectionalChannelInfo,
301+
pub two_to_one: Option<DirectionalChannelInfo>,
294302
/// An initial announcement of the channel
295303
//this is cached here so we can send out it later if required by initial routing sync
296304
//keep an eye on this to see if the extra memory is a problem
@@ -299,14 +307,17 @@ pub struct ChannelInfo {
299307

300308
impl std::fmt::Display for ChannelInfo {
301309
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
302-
write!(f, "features: {}, one_to_two: {}, two_to_one: {}", log_bytes!(self.features.encode()), self.one_to_two, self.two_to_one)?;
310+
write!(f, "features: {}, one_src_node: {}, one_to_two: {:?}, two_src_node: {}, two_to_one: {:?}",
311+
log_bytes!(self.features.encode()), log_pubkey!(self.one_src_node), self.one_to_two, log_pubkey!(self.two_src_node), self.two_to_one)?;
303312
Ok(())
304313
}
305314
}
306315

307316
impl_writeable!(ChannelInfo, 0, {
308317
features,
318+
one_src_node,
309319
one_to_two,
320+
two_src_node,
310321
two_to_one,
311322
announcement_message
312323
});
@@ -555,30 +566,10 @@ impl NetworkGraph {
555566

556567
let chan_info = ChannelInfo {
557568
features: msg.contents.features.clone(),
558-
one_to_two: DirectionalChannelInfo {
559-
src_node_id: msg.contents.node_id_1.clone(),
560-
last_update: 0,
561-
enabled: false,
562-
cltv_expiry_delta: u16::max_value(),
563-
htlc_minimum_msat: u64::max_value(),
564-
fees: RoutingFees {
565-
base_msat: u32::max_value(),
566-
proportional_millionths: u32::max_value(),
567-
},
568-
last_update_message: None,
569-
},
570-
two_to_one: DirectionalChannelInfo {
571-
src_node_id: msg.contents.node_id_2.clone(),
572-
last_update: 0,
573-
enabled: false,
574-
cltv_expiry_delta: u16::max_value(),
575-
htlc_minimum_msat: u64::max_value(),
576-
fees: RoutingFees {
577-
base_msat: u32::max_value(),
578-
proportional_millionths: u32::max_value(),
579-
},
580-
last_update_message: None,
581-
},
569+
one_src_node: msg.contents.node_id_1.clone(),
570+
one_to_two: None,
571+
two_src_node: msg.contents.node_id_2.clone(),
572+
two_to_one: None,
582573
announcement_message: if should_relay { Some(msg.clone()) } else { None },
583574
};
584575

@@ -641,8 +632,12 @@ impl NetworkGraph {
641632
}
642633
} else {
643634
if let Some(chan) = self.channels.get_mut(&short_channel_id) {
644-
chan.one_to_two.enabled = false;
645-
chan.two_to_one.enabled = false;
635+
if let Some(one_to_two) = chan.one_to_two.as_ref() {
636+
one_to_two.enabled = false;
637+
}
638+
if let Some(two_to_one) = chan.two_to_one.as_ref() {
639+
two_to_one.enabled = false;
640+
}
646641
}
647642
}
648643
}
@@ -666,33 +661,46 @@ impl NetworkGraph {
666661
None => return Err(LightningError{err: "Couldn't find channel for update", action: ErrorAction::IgnoreError}),
667662
Some(channel) => {
668663
macro_rules! maybe_update_channel_info {
669-
( $target: expr) => {
670-
if $target.last_update >= msg.contents.timestamp {
671-
return Err(LightningError{err: "Update older than last processed update", action: ErrorAction::IgnoreError});
664+
( $target: expr, $src_node: expr) => {
665+
if let Some(existing_chan_info) = $target.as_ref() {
666+
if existing_chan_info.last_update >= msg.contents.timestamp {
667+
return Err(LightningError{err: "Update older than last processed update", action: ErrorAction::IgnoreError});
668+
}
669+
chan_was_enabled = existing_chan_info.enabled;
670+
} else {
671+
chan_was_enabled = false;
672672
}
673-
chan_was_enabled = $target.enabled;
674-
$target.last_update = msg.contents.timestamp;
675-
$target.enabled = chan_enabled;
676-
$target.cltv_expiry_delta = msg.contents.cltv_expiry_delta;
677-
$target.htlc_minimum_msat = msg.contents.htlc_minimum_msat;
678-
$target.fees.base_msat = msg.contents.fee_base_msat;
679-
$target.fees.proportional_millionths = msg.contents.fee_proportional_millionths;
680-
$target.last_update_message = if msg.contents.excess_data.is_empty() {
673+
674+
let last_update_message = if msg.contents.excess_data.is_empty() {
681675
Some(msg.clone())
682676
} else {
683677
None
684678
};
679+
680+
let updated_channel_dir_info = DirectionalChannelInfo {
681+
enabled: chan_enabled,
682+
last_update: msg.contents.timestamp,
683+
cltv_expiry_delta: msg.contents.cltv_expiry_delta,
684+
htlc_minimum_msat: msg.contents.htlc_minimum_msat,
685+
fees: RoutingFees {
686+
base_msat: msg.contents.fee_base_msat,
687+
proportional_millionths: msg.contents.fee_proportional_millionths,
688+
},
689+
last_update_message
690+
};
691+
$target = Some(updated_channel_dir_info);
685692
}
686693
}
694+
687695
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
688696
if msg.contents.flags & 1 == 1 {
689-
dest_node_id = channel.one_to_two.src_node_id.clone();
690-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.two_to_one.src_node_id);
691-
maybe_update_channel_info!(channel.two_to_one);
697+
dest_node_id = channel.one_src_node.clone();
698+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.two_src_node);
699+
maybe_update_channel_info!(channel.two_to_one, channel.two_src_node);
692700
} else {
693-
dest_node_id = channel.two_to_one.src_node_id.clone();
694-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.one_to_two.src_node_id);
695-
maybe_update_channel_info!(channel.one_to_two);
701+
dest_node_id = channel.two_src_node.clone();
702+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.one_src_node);
703+
maybe_update_channel_info!(channel.one_to_two, channel.one_src_node);
696704
}
697705
}
698706
}
@@ -718,13 +726,15 @@ impl NetworkGraph {
718726

719727
for chan_id in node.channels.iter() {
720728
let chan = self.channels.get(chan_id).unwrap();
721-
if chan.one_to_two.src_node_id == dest_node_id {
722-
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan.two_to_one.fees.base_msat);
723-
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan.two_to_one.fees.proportional_millionths);
729+
// Since direction was enabled, the channel indeed had directional info
730+
let chan_info;
731+
if chan.one_src_node == dest_node_id {
732+
chan_info = chan.two_to_one.as_ref().unwrap();
724733
} else {
725-
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan.one_to_two.fees.base_msat);
726-
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan.one_to_two.fees.proportional_millionths);
734+
chan_info = chan.one_to_two.as_ref().unwrap();
727735
}
736+
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan_info.fees.base_msat);
737+
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan_info.fees.proportional_millionths);
728738
}
729739
}
730740

@@ -756,8 +766,9 @@ impl NetworkGraph {
756766
}
757767
}
758768
}
759-
remove_from_node!(chan.one_to_two.src_node_id);
760-
remove_from_node!(chan.two_to_one.src_node_id);
769+
770+
remove_from_node!(chan.one_src_node);
771+
remove_from_node!(chan.two_src_node);
761772
}
762773
}
763774

@@ -1168,8 +1179,8 @@ mod tests {
11681179
match network.get_channels().get(&short_channel_id) {
11691180
None => panic!(),
11701181
Some(channel_info) => {
1171-
assert_eq!(channel_info.one_to_two.cltv_expiry_delta, 144);
1172-
assert_eq!(channel_info.two_to_one.cltv_expiry_delta, u16::max_value());
1182+
assert_eq!(channel_info.one_to_two.as_ref().unwrap().cltv_expiry_delta, 144);
1183+
assert!(channel_info.two_to_one.is_none());
11731184
}
11741185
}
11751186
}
@@ -1274,6 +1285,38 @@ mod tests {
12741285
Err(_) => panic!()
12751286
};
12761287

1288+
let unsigned_channel_update = UnsignedChannelUpdate {
1289+
chain_hash,
1290+
short_channel_id,
1291+
timestamp: 100,
1292+
flags: 0,
1293+
cltv_expiry_delta: 144,
1294+
htlc_minimum_msat: 1000000,
1295+
fee_base_msat: 10000,
1296+
fee_proportional_millionths: 20,
1297+
excess_data: Vec::new()
1298+
};
1299+
let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_channel_update.encode()[..])[..]);
1300+
let valid_channel_update = ChannelUpdate {
1301+
signature: secp_ctx.sign(&msghash, node_1_privkey),
1302+
contents: unsigned_channel_update.clone()
1303+
};
1304+
1305+
match net_graph_msg_handler.handle_channel_update(&valid_channel_update) {
1306+
Ok(res) => assert!(res),
1307+
_ => panic!()
1308+
};
1309+
}
1310+
1311+
// Non-permanent closing just disables a channel
1312+
{
1313+
let network = net_graph_msg_handler.network_graph.read().unwrap();
1314+
match network.get_channels().get(&short_channel_id) {
1315+
None => panic!(),
1316+
Some(channel_info) => {
1317+
assert!(channel_info.one_to_two.is_some());
1318+
}
1319+
}
12771320
}
12781321

12791322
let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed {
@@ -1289,8 +1332,7 @@ mod tests {
12891332
match network.get_channels().get(&short_channel_id) {
12901333
None => panic!(),
12911334
Some(channel_info) => {
1292-
assert!(!channel_info.one_to_two.enabled);
1293-
assert!(!channel_info.two_to_one.enabled);
1335+
assert!(!channel_info.one_to_two.as_ref().unwrap().enabled);
12941336
}
12951337
}
12961338
}

0 commit comments

Comments
 (0)