Skip to content

Commit 8999d38

Browse files
committed
Make DirectionalChannelInfo optional
1 parent 051f764 commit 8999d38

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
});
@@ -556,30 +567,10 @@ impl NetworkGraph {
556567

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

@@ -642,8 +633,12 @@ impl NetworkGraph {
642633
}
643634
} else {
644635
if let Some(chan) = self.channels.get_mut(&short_channel_id) {
645-
chan.one_to_two.enabled = false;
646-
chan.two_to_one.enabled = false;
636+
if let Some(one_to_two) = chan.one_to_two.as_mut() {
637+
one_to_two.enabled = false;
638+
}
639+
if let Some(two_to_one) = chan.two_to_one.as_mut() {
640+
two_to_one.enabled = false;
641+
}
647642
}
648643
}
649644
}
@@ -667,33 +662,46 @@ impl NetworkGraph {
667662
None => return Err(LightningError{err: "Couldn't find channel for update", action: ErrorAction::IgnoreError}),
668663
Some(channel) => {
669664
macro_rules! maybe_update_channel_info {
670-
( $target: expr) => {
671-
if $target.last_update >= msg.contents.timestamp {
672-
return Err(LightningError{err: "Update older than last processed update", action: ErrorAction::IgnoreError});
665+
( $target: expr, $src_node: expr) => {
666+
if let Some(existing_chan_info) = $target.as_ref() {
667+
if existing_chan_info.last_update >= msg.contents.timestamp {
668+
return Err(LightningError{err: "Update older than last processed update", action: ErrorAction::IgnoreError});
669+
}
670+
chan_was_enabled = existing_chan_info.enabled;
671+
} else {
672+
chan_was_enabled = false;
673673
}
674-
chan_was_enabled = $target.enabled;
675-
$target.last_update = msg.contents.timestamp;
676-
$target.enabled = chan_enabled;
677-
$target.cltv_expiry_delta = msg.contents.cltv_expiry_delta;
678-
$target.htlc_minimum_msat = msg.contents.htlc_minimum_msat;
679-
$target.fees.base_msat = msg.contents.fee_base_msat;
680-
$target.fees.proportional_millionths = msg.contents.fee_proportional_millionths;
681-
$target.last_update_message = if msg.contents.excess_data.is_empty() {
674+
675+
let last_update_message = if msg.contents.excess_data.is_empty() {
682676
Some(msg.clone())
683677
} else {
684678
None
685679
};
680+
681+
let updated_channel_dir_info = DirectionalChannelInfo {
682+
enabled: chan_enabled,
683+
last_update: msg.contents.timestamp,
684+
cltv_expiry_delta: msg.contents.cltv_expiry_delta,
685+
htlc_minimum_msat: msg.contents.htlc_minimum_msat,
686+
fees: RoutingFees {
687+
base_msat: msg.contents.fee_base_msat,
688+
proportional_millionths: msg.contents.fee_proportional_millionths,
689+
},
690+
last_update_message
691+
};
692+
$target = Some(updated_channel_dir_info);
686693
}
687694
}
695+
688696
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
689697
if msg.contents.flags & 1 == 1 {
690-
dest_node_id = channel.one_to_two.src_node_id.clone();
691-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.two_to_one.src_node_id);
692-
maybe_update_channel_info!(channel.two_to_one);
698+
dest_node_id = channel.node_one.clone();
699+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.node_two);
700+
maybe_update_channel_info!(channel.two_to_one, channel.node_two);
693701
} else {
694-
dest_node_id = channel.two_to_one.src_node_id.clone();
695-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.one_to_two.src_node_id);
696-
maybe_update_channel_info!(channel.one_to_two);
702+
dest_node_id = channel.node_two.clone();
703+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &channel.node_one);
704+
maybe_update_channel_info!(channel.one_to_two, channel.node_one);
697705
}
698706
}
699707
}
@@ -719,13 +727,15 @@ impl NetworkGraph {
719727

720728
for chan_id in node.channels.iter() {
721729
let chan = self.channels.get(chan_id).unwrap();
722-
if chan.one_to_two.src_node_id == dest_node_id {
723-
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan.two_to_one.fees.base_msat);
724-
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan.two_to_one.fees.proportional_millionths);
730+
// Since direction was enabled, the channel indeed had directional info
731+
let chan_info;
732+
if chan.node_one == dest_node_id {
733+
chan_info = chan.two_to_one.as_ref().unwrap();
725734
} else {
726-
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan.one_to_two.fees.base_msat);
727-
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan.one_to_two.fees.proportional_millionths);
735+
chan_info = chan.one_to_two.as_ref().unwrap();
728736
}
737+
lowest_inbound_channel_fee_base_msat = cmp::min(lowest_inbound_channel_fee_base_msat, chan_info.fees.base_msat);
738+
lowest_inbound_channel_fee_proportional_millionths = cmp::min(lowest_inbound_channel_fee_proportional_millionths, chan_info.fees.proportional_millionths);
729739
}
730740
}
731741

@@ -757,8 +767,9 @@ impl NetworkGraph {
757767
}
758768
}
759769
}
760-
remove_from_node!(chan.one_to_two.src_node_id);
761-
remove_from_node!(chan.two_to_one.src_node_id);
770+
771+
remove_from_node!(chan.node_one);
772+
remove_from_node!(chan.node_two);
762773
}
763774
}
764775

@@ -1169,8 +1180,8 @@ mod tests {
11691180
match network.get_channels().get(&short_channel_id) {
11701181
None => panic!(),
11711182
Some(channel_info) => {
1172-
assert_eq!(channel_info.one_to_two.cltv_expiry_delta, 144);
1173-
assert_eq!(channel_info.two_to_one.cltv_expiry_delta, u16::max_value());
1183+
assert_eq!(channel_info.one_to_two.as_ref().unwrap().cltv_expiry_delta, 144);
1184+
assert!(channel_info.two_to_one.is_none());
11741185
}
11751186
}
11761187
}
@@ -1275,6 +1286,38 @@ mod tests {
12751286
Err(_) => panic!()
12761287
};
12771288

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

12801323
let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed {
@@ -1290,8 +1333,7 @@ mod tests {
12901333
match network.get_channels().get(&short_channel_id) {
12911334
None => panic!(),
12921335
Some(channel_info) => {
1293-
assert!(!channel_info.one_to_two.enabled);
1294-
assert!(!channel_info.two_to_one.enabled);
1336+
assert!(!channel_info.one_to_two.as_ref().unwrap().enabled);
12951337
}
12961338
}
12971339
}

0 commit comments

Comments
 (0)