From 494e3aad9f551da6de319c40ba9ae10c3fa00696 Mon Sep 17 00:00:00 2001 From: Gleb Naumenko Date: Tue, 1 Nov 2022 10:10:49 +0200 Subject: [PATCH 1/3] Non-mandatory "fix" enabling future tests --- lightning/src/routing/gossip.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 14df033b6..cf7eb3817 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -2532,10 +2532,15 @@ mod tests { assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source).is_ok()); assert!(network_graph.read_only().channels().get(&short_channel_id).is_some()); + // Submit two channel updates for each channel direction (update.flags bit). let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx); assert!(gossip_sync.handle_channel_update(&valid_channel_update).is_ok()); assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); + let valid_channel_update_2 = get_signed_channel_update(|update| {update.flags |=1;}, node_2_privkey, &secp_ctx); + gossip_sync.handle_channel_update(&valid_channel_update_2).unwrap(); + assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().two_to_one.is_some()); + network_graph.remove_stale_channels_and_tracking_with_time(100 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS); assert_eq!(network_graph.read_only().channels().len(), 1); assert_eq!(network_graph.read_only().nodes().len(), 2); From a39d9bfa0395a2a5c02b04f4ad7936e37cada613 Mon Sep 17 00:00:00 2001 From: Gleb Naumenko Date: Thu, 27 Oct 2022 12:30:44 +0300 Subject: [PATCH 2/3] Prune channels if *either* not updated --- lightning/src/routing/gossip.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index cf7eb3817..4e4d86e4b 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -1653,7 +1653,7 @@ impl NetworkGraph where L::Target: Logger { if info.two_to_one.is_some() && info.two_to_one.as_ref().unwrap().last_update < min_time_unix { info.two_to_one = None; } - if info.one_to_two.is_none() && info.two_to_one.is_none() { + if info.one_to_two.is_none() || info.two_to_one.is_none() { // We check the announcement_received_time here to ensure we don't drop // announcements that we just received and are just waiting for our peer to send a // channel_update for. @@ -2550,14 +2550,21 @@ mod tests { { // In std mode, a further check is performed before fully removing the channel - // the channel_announcement must have been received at least two weeks ago. We - // fudge that here by indicating the time has jumped two weeks. Note that the - // directional channel information will have been removed already.. + // fudge that here by indicating the time has jumped two weeks. assert_eq!(network_graph.read_only().channels().len(), 1); assert_eq!(network_graph.read_only().nodes().len(), 2); - assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none()); + // Note that the directional channel information will have been removed already.. + // We want to check that this will work even if *one* of the channel updates is recent, + // so we should add it with a recent timestamp. + assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none()); use std::time::{SystemTime, UNIX_EPOCH}; let announcement_time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs(); + let valid_channel_update = get_signed_channel_update(|unsigned_channel_update| { + unsigned_channel_update.timestamp = (announcement_time + 1 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS) as u32; + }, node_1_privkey, &secp_ctx); + assert!(gossip_sync.handle_channel_update(&valid_channel_update).is_ok()); + assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); network_graph.remove_stale_channels_and_tracking_with_time(announcement_time + 1 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS); } From 080c70f98f8b96bae965ca90ca690f06cead4b3b Mon Sep 17 00:00:00 2001 From: Gleb Naumenko Date: Thu, 27 Oct 2022 12:52:34 +0300 Subject: [PATCH 3/3] Track the time a stale channel was pruned --- lightning/src/routing/gossip.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 4e4d86e4b..6b0f88d09 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -1667,6 +1667,7 @@ impl NetworkGraph where L::Target: Logger { for scid in scids_to_remove { let info = channels.remove(&scid).expect("We just accessed this scid, it should be present"); Self::remove_channel_in_nodes(&mut nodes, &info, scid); + self.removed_channels.lock().unwrap().insert(scid, Some(current_time_unix)); } } @@ -2546,6 +2547,13 @@ mod tests { assert_eq!(network_graph.read_only().nodes().len(), 2); network_graph.remove_stale_channels_and_tracking_with_time(101 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS); + #[cfg(not(feature = "std"))] { + // Make sure removed channels are tracked. + assert_eq!(network_graph.removed_channels.lock().unwrap().len(), 1); + } + network_graph.remove_stale_channels_and_tracking_with_time(101 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS + + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS); + #[cfg(feature = "std")] { // In std mode, a further check is performed before fully removing the channel - @@ -2566,10 +2574,16 @@ mod tests { assert!(gossip_sync.handle_channel_update(&valid_channel_update).is_ok()); assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); network_graph.remove_stale_channels_and_tracking_with_time(announcement_time + 1 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS); + // Make sure removed channels are tracked. + assert_eq!(network_graph.removed_channels.lock().unwrap().len(), 1); + // Provide a later time so that sufficient time has passed + network_graph.remove_stale_channels_and_tracking_with_time(announcement_time + 1 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS + + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS); } assert_eq!(network_graph.read_only().channels().len(), 0); assert_eq!(network_graph.read_only().nodes().len(), 0); + assert!(network_graph.removed_channels.lock().unwrap().is_empty()); #[cfg(feature = "std")] {