From 70653d0ccb52bcea57fb956770fa2d3940b5e0e6 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 4 Aug 2021 16:21:36 +0000 Subject: [PATCH 1/3] Suggest faster ping in `PeerManager::timer_tick_occurred` docs This clarifies the docs for `PeerManager::timer_tick_occurred` to note that the call rate is entirely up to the user, and also suggests a faster ping rate of "once every five to ten seconds" instead of "every 30 seconds". There isn't a lot of reason to want to ping less often, and faster ping means we detect disconnects sooner, which is important. --- lightning/src/ln/peer_handler.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index be12a32e9..42b269411 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -1372,9 +1372,12 @@ impl PeerManager Date: Thu, 5 Aug 2021 17:04:18 +0000 Subject: [PATCH 2/3] Update lightning-background-processor to ping every five seconds This updates lightning-background-processor calls to PeerManager::timer_tick_occurred to match the new suggested rate in the documentation. --- lightning-background-processor/src/lib.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 55ac14c04..5573b101e 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -49,6 +49,8 @@ const FRESHNESS_TIMER: u64 = 60; #[cfg(test)] const FRESHNESS_TIMER: u64 = 1; +const PING_TIMER: u64 = 5; + /// Trait which handles persisting a [`ChannelManager`] to disk. /// /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager @@ -137,7 +139,8 @@ impl BackgroundProcessor { let stop_thread = Arc::new(AtomicBool::new(false)); let stop_thread_clone = stop_thread.clone(); let handle = thread::spawn(move || -> Result<(), std::io::Error> { - let mut current_time = Instant::now(); + let mut last_freshness_call = Instant::now(); + let mut last_ping_call = Instant::now(); loop { peer_manager.process_events(); channel_manager.process_pending_events(&event_handler); @@ -152,11 +155,15 @@ impl BackgroundProcessor { log_trace!(logger, "Terminating background processor."); return Ok(()); } - if current_time.elapsed().as_secs() > FRESHNESS_TIMER { - log_trace!(logger, "Calling ChannelManager's and PeerManager's timer_tick_occurred"); + if last_freshness_call.elapsed().as_secs() > FRESHNESS_TIMER { + log_trace!(logger, "Calling ChannelManager's timer_tick_occurred"); channel_manager.timer_tick_occurred(); + last_freshness_call = Instant::now(); + } + if last_ping_call.elapsed().as_secs() > PING_TIMER { + log_trace!(logger, "Calling PeerManager's timer_tick_occurred"); peer_manager.timer_tick_occurred(); - current_time = Instant::now(); + last_ping_call = Instant::now(); } } }); @@ -440,8 +447,10 @@ mod tests { let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); loop { let log_entries = nodes[0].logger.lines.lock().unwrap(); - let desired_log = "Calling ChannelManager's and PeerManager's timer_tick_occurred".to_string(); - if log_entries.get(&("lightning_background_processor".to_string(), desired_log)).is_some() { + let desired_log = "Calling ChannelManager's timer_tick_occurred".to_string(); + let second_desired_log = "Calling PeerManager's timer_tick_occurred".to_string(); + if log_entries.get(&("lightning_background_processor".to_string(), desired_log)).is_some() && + log_entries.get(&("lightning_background_processor".to_string(), second_desired_log)).is_some() { break } } From 0f1a3b16984063d9a7e745d2e4a0afb532d634d0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 7 Aug 2021 20:45:01 +0000 Subject: [PATCH 3/3] Handle being asleep for more than double our ping time gracefully If we've been asleep for double our ping time, for whatever reason, disconnect all open sockets. --- lightning-background-processor/src/lib.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 5573b101e..c75c47262 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -160,7 +160,19 @@ impl BackgroundProcessor { channel_manager.timer_tick_occurred(); last_freshness_call = Instant::now(); } - if last_ping_call.elapsed().as_secs() > PING_TIMER { + if last_ping_call.elapsed().as_secs() > PING_TIMER * 2 { + // On various platforms, we may be starved of CPU cycles for several reasons. + // E.g. on iOS, if we've been in the background, we will be entirely paused. + // Similarly, if we're on a desktop platform and the device has been asleep, we + // may not get any cycles. + // In any case, if we've been entirely paused for more than double our ping + // timer, we should have disconnected all sockets by now (and they're probably + // dead anyway), so disconnect them by calling `timer_tick_occurred()` twice. + log_trace!(logger, "Awoke after more than double our ping timer, disconnecting peers."); + peer_manager.timer_tick_occurred(); + peer_manager.timer_tick_occurred(); + last_ping_call = Instant::now(); + } else if last_ping_call.elapsed().as_secs() > PING_TIMER { log_trace!(logger, "Calling PeerManager's timer_tick_occurred"); peer_manager.timer_tick_occurred(); last_ping_call = Instant::now();