Skip to content

Prune channels if either not updated + track pruning time #1735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions lightning/src/routing/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1653,7 +1653,7 @@ impl<L: Deref> NetworkGraph<L> 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.
Expand All @@ -1667,6 +1667,7 @@ impl<L: Deref> NetworkGraph<L> 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));
}
}

Expand Down Expand Up @@ -2532,32 +2533,57 @@ 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);

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 -
// 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);
// 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")]
{
Expand Down