Skip to content

Commit ec2c005

Browse files
committed
Make DirectionalChannelInfo optional
1 parent eb1703a commit ec2c005

File tree

2 files changed

+131
-86
lines changed

2 files changed

+131
-86
lines changed

lightning/src/routing/network_graph.rs

Lines changed: 109 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,16 @@ impl RoutingMessageHandler for NetGraphMsgHandler {
141141
while result.len() < batch_amount as usize {
142142
if let Some((_, ref chan)) = iter.next() {
143143
if chan.announcement_message.is_some() {
144-
result.push((chan.announcement_message.clone().unwrap(),
145-
chan.one_to_two.last_update_message.clone(),
146-
chan.two_to_one.last_update_message.clone()));
144+
let chan_announcement = chan.announcement_message.clone().unwrap();
145+
let mut one_to_two_announcement: Option<msgs::ChannelUpdate> = None;
146+
let mut two_to_one_announcement: Option<msgs::ChannelUpdate> = None;
147+
if let Some(one_to_two) = chan.one_to_two.as_ref() {
148+
one_to_two_announcement = one_to_two.last_update_message.clone();
149+
}
150+
if let Some(two_to_one) = chan.two_to_one.as_ref() {
151+
two_to_one_announcement = two_to_one.last_update_message.clone();
152+
}
153+
result.push((chan_announcement, one_to_two_announcement, two_to_one_announcement));
147154
} else {
148155
// TODO: We may end up sending un-announced channel_updates if we are sending
149156
// initial sync data while receiving announce/updates for this channel.
@@ -238,11 +245,9 @@ impl ReadableArgs<NetGraphMsgHandlerReadArgs> for NetGraphMsgHandler {
238245
}
239246
}
240247

241-
#[derive(PartialEq)]
248+
#[derive(PartialEq, Debug)]
242249
/// Details regarding one direction of a channel
243250
pub struct DirectionalChannelInfo {
244-
/// A node from which the channel direction starts
245-
pub src_node_id: PublicKey,
246251
/// When the last update to the channel direction was issued
247252
pub last_update: u32,
248253
/// Whether the channel can be currently used for payments
@@ -259,13 +264,12 @@ pub struct DirectionalChannelInfo {
259264

260265
impl std::fmt::Display for DirectionalChannelInfo {
261266
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
262-
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)?;
267+
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)?;
263268
Ok(())
264269
}
265270
}
266271

267272
impl_writeable!(DirectionalChannelInfo, 0, {
268-
src_node_id,
269273
last_update,
270274
enabled,
271275
cltv_expiry_delta,
@@ -279,10 +283,14 @@ impl_writeable!(DirectionalChannelInfo, 0, {
279283
pub struct ChannelInfo {
280284
/// Protocol features of a channel communicated during its announcement
281285
pub features: ChannelFeatures,
282-
/// Details regarding one of the directions of a channel
283-
pub one_to_two: DirectionalChannelInfo,
284-
/// Details regarding another direction of a channel
285-
pub two_to_one: DirectionalChannelInfo,
286+
/// Source node of the first direction of a channel
287+
pub node_one: PublicKey,
288+
/// Details about the first direction of a channel
289+
pub one_to_two: Option<DirectionalChannelInfo>,
290+
/// Source node of the second direction of a channel
291+
pub node_two: PublicKey,
292+
/// Details about the second direction of a channel
293+
pub two_to_one: Option<DirectionalChannelInfo>,
286294
/// An initial announcement of the channel
287295
//this is cached here so we can send out it later if required by initial routing sync
288296
//keep an eye on this to see if the extra memory is a problem
@@ -291,14 +299,17 @@ pub struct ChannelInfo {
291299

292300
impl std::fmt::Display for ChannelInfo {
293301
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
294-
write!(f, "features: {}, one_to_two: {}, two_to_one: {}", log_bytes!(self.features.encode()), self.one_to_two, self.two_to_one)?;
302+
write!(f, "features: {}, node_one: {}, one_to_two: {:?}, node_two: {}, two_to_one: {:?}",
303+
log_bytes!(self.features.encode()), log_pubkey!(self.node_one), self.one_to_two, log_pubkey!(self.node_two), self.two_to_one)?;
295304
Ok(())
296305
}
297306
}
298307

299308
impl_writeable!(ChannelInfo, 0, {
300309
features,
310+
node_one,
301311
one_to_two,
312+
node_two,
302313
two_to_one,
303314
announcement_message
304315
});
@@ -560,30 +571,10 @@ impl NetworkGraph {
560571

561572
let chan_info = ChannelInfo {
562573
features: msg.contents.features.clone(),
563-
one_to_two: DirectionalChannelInfo {
564-
src_node_id: msg.contents.node_id_1.clone(),
565-
last_update: 0,
566-
enabled: false,
567-
cltv_expiry_delta: u16::max_value(),
568-
htlc_minimum_msat: u64::max_value(),
569-
fees: RoutingFees {
570-
base_msat: u32::max_value(),
571-
proportional_millionths: u32::max_value(),
572-
},
573-
last_update_message: None,
574-
},
575-
two_to_one: DirectionalChannelInfo {
576-
src_node_id: msg.contents.node_id_2.clone(),
577-
last_update: 0,
578-
enabled: false,
579-
cltv_expiry_delta: u16::max_value(),
580-
htlc_minimum_msat: u64::max_value(),
581-
fees: RoutingFees {
582-
base_msat: u32::max_value(),
583-
proportional_millionths: u32::max_value(),
584-
},
585-
last_update_message: None,
586-
},
574+
node_one: msg.contents.node_id_1.clone(),
575+
one_to_two: None,
576+
node_two: msg.contents.node_id_2.clone(),
577+
two_to_one: None,
587578
announcement_message: if should_relay { Some(msg.clone()) } else { None },
588579
};
589580

@@ -646,8 +637,12 @@ impl NetworkGraph {
646637
}
647638
} else {
648639
if let Some(chan) = self.channels.get_mut(&short_channel_id) {
649-
chan.one_to_two.enabled = false;
650-
chan.two_to_one.enabled = false;
640+
if let Some(one_to_two) = chan.one_to_two.as_mut() {
641+
one_to_two.enabled = false;
642+
}
643+
if let Some(two_to_one) = chan.two_to_one.as_mut() {
644+
two_to_one.enabled = false;
645+
}
651646
}
652647
}
653648
}
@@ -671,37 +666,50 @@ impl NetworkGraph {
671666
None => return Err(LightningError{err: "Couldn't find channel for update", action: ErrorAction::IgnoreError}),
672667
Some(channel) => {
673668
macro_rules! maybe_update_channel_info {
674-
( $target: expr) => {
675-
if $target.last_update >= msg.contents.timestamp {
676-
return Err(LightningError{err: "Update older than last processed update", action: ErrorAction::IgnoreError});
669+
( $target: expr, $src_node: expr) => {
670+
if let Some(existing_chan_info) = $target.as_ref() {
671+
if existing_chan_info.last_update >= msg.contents.timestamp {
672+
return Err(LightningError{err: "Update older than last processed update", action: ErrorAction::IgnoreError});
673+
}
674+
chan_was_enabled = existing_chan_info.enabled;
675+
} else {
676+
chan_was_enabled = false;
677677
}
678-
chan_was_enabled = $target.enabled;
679-
$target.last_update = msg.contents.timestamp;
680-
$target.enabled = chan_enabled;
681-
$target.cltv_expiry_delta = msg.contents.cltv_expiry_delta;
682-
$target.htlc_minimum_msat = msg.contents.htlc_minimum_msat;
683-
$target.fees.base_msat = msg.contents.fee_base_msat;
684-
$target.fees.proportional_millionths = msg.contents.fee_proportional_millionths;
685-
$target.last_update_message = if msg.contents.excess_data.is_empty() {
678+
679+
let last_update_message = if msg.contents.excess_data.is_empty() {
686680
Some(msg.clone())
687681
} else {
688682
None
689683
};
684+
685+
let updated_channel_dir_info = DirectionalChannelInfo {
686+
enabled: chan_enabled,
687+
last_update: msg.contents.timestamp,
688+
cltv_expiry_delta: msg.contents.cltv_expiry_delta,
689+
htlc_minimum_msat: msg.contents.htlc_minimum_msat,
690+
fees: RoutingFees {
691+
base_msat: msg.contents.fee_base_msat,
692+
proportional_millionths: msg.contents.fee_proportional_millionths,
693+
},
694+
last_update_message
695+
};
696+
$target = Some(updated_channel_dir_info);
690697
}
691698
}
699+
692700
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
693701
if msg.contents.flags & 1 == 1 {
694-
dest_node_id = channel.one_to_two.src_node_id.clone();
702+
dest_node_id = channel.node_one.clone();
695703
if let Some(sig_verifier) = secp_ctx {
696-
secp_verify_sig!(sig_verifier, &msg_hash, &msg.signature, &channel.two_to_one.src_node_id);
704+
secp_verify_sig!(sig_verifier, &msg_hash, &msg.signature, &channel.node_two);
697705
}
698-
maybe_update_channel_info!(channel.two_to_one);
706+
maybe_update_channel_info!(channel.two_to_one, channel.node_two);
699707
} else {
700-
dest_node_id = channel.two_to_one.src_node_id.clone();
708+
dest_node_id = channel.node_two.clone();
701709
if let Some(sig_verifier) = secp_ctx {
702-
secp_verify_sig!(sig_verifier, &msg_hash, &msg.signature, &channel.one_to_two.src_node_id);
710+
secp_verify_sig!(sig_verifier, &msg_hash, &msg.signature, &channel.node_one);
703711
}
704-
maybe_update_channel_info!(channel.one_to_two);
712+
maybe_update_channel_info!(channel.one_to_two, channel.node_one);
705713
}
706714
}
707715
}
@@ -727,13 +735,15 @@ impl NetworkGraph {
727735

728736
for chan_id in node.channels.iter() {
729737
let chan = self.channels.get(chan_id).unwrap();
730-
if chan.one_to_two.src_node_id == dest_node_id {
731-
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan.two_to_one.fees.base_msat);
732-
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan.two_to_one.fees.proportional_millionths);
738+
// Since direction was enabled, the channel indeed had directional info
739+
let chan_info;
740+
if chan.node_one == dest_node_id {
741+
chan_info = chan.two_to_one.as_ref().unwrap();
733742
} else {
734-
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan.one_to_two.fees.base_msat);
735-
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan.one_to_two.fees.proportional_millionths);
743+
chan_info = chan.one_to_two.as_ref().unwrap();
736744
}
745+
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan_info.fees.base_msat);
746+
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan_info.fees.proportional_millionths);
737747
}
738748
}
739749

@@ -765,8 +775,9 @@ impl NetworkGraph {
765775
}
766776
}
767777
}
768-
remove_from_node!(chan.one_to_two.src_node_id);
769-
remove_from_node!(chan.two_to_one.src_node_id);
778+
779+
remove_from_node!(chan.node_one);
780+
remove_from_node!(chan.node_two);
770781
}
771782
}
772783

@@ -1177,8 +1188,8 @@ mod tests {
11771188
match network.get_channels().get(&short_channel_id) {
11781189
None => panic!(),
11791190
Some(channel_info) => {
1180-
assert_eq!(channel_info.one_to_two.cltv_expiry_delta, 144);
1181-
assert_eq!(channel_info.two_to_one.cltv_expiry_delta, u16::max_value());
1191+
assert_eq!(channel_info.one_to_two.as_ref().unwrap().cltv_expiry_delta, 144);
1192+
assert!(channel_info.two_to_one.is_none());
11821193
}
11831194
}
11841195
}
@@ -1283,6 +1294,38 @@ mod tests {
12831294
Err(_) => panic!()
12841295
};
12851296

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

12881331
let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed {
@@ -1298,8 +1341,7 @@ mod tests {
12981341
match network.get_channels().get(&short_channel_id) {
12991342
None => panic!(),
13001343
Some(channel_info) => {
1301-
assert!(!channel_info.one_to_two.enabled);
1302-
assert!(!channel_info.two_to_one.enabled);
1344+
assert!(!channel_info.one_to_two.as_ref().unwrap().enabled);
13031345
}
13041346
}
13051347
}

0 commit comments

Comments
 (0)