diff --git a/eel/src/lib.rs b/eel/src/lib.rs index e6a8b491..2d6ffa93 100644 --- a/eel/src/lib.rs +++ b/eel/src/lib.rs @@ -52,7 +52,7 @@ use crate::payment::{FiatValues, Payment, PaymentState, PaymentType}; use crate::random::generate_random_bytes; use crate::rapid_sync_client::RapidSyncClient; use crate::storage_persister::StoragePersister; -use crate::task_manager::{RestartIfFailedPeriod, TaskManager, TaskPeriods}; +use crate::task_manager::{PeriodConfig, RestartIfFailedPeriod, TaskManager, TaskPeriods}; use crate::tx_broadcaster::TxBroadcaster; use crate::types::{ChainMonitor, ChannelManager, PeerManager, RapidGossipSync, Router, TxSync}; @@ -84,7 +84,10 @@ use tokio::time::Duration; const FOREGROUND_PERIODS: TaskPeriods = TaskPeriods { sync_blockchain: Duration::from_secs(5 * 60), - update_lsp_info: Some(Duration::from_secs(10 * 60)), + update_lsp_info: Some(PeriodConfig { + success_period: Duration::from_secs(10 * 60), + failure_period: Duration::from_secs(5), + }), reconnect_to_lsp: Duration::from_secs(10), update_fees: Some(Duration::from_secs(5 * 60)), update_graph: Some(RestartIfFailedPeriod::from_secs(2 * 60)), @@ -721,7 +724,10 @@ fn get_foreground_periods() -> TaskPeriods { let period = Duration::from_secs(period); TaskPeriods { sync_blockchain: period, - update_lsp_info: Some(period), + update_lsp_info: Some(PeriodConfig { + success_period: period, + failure_period: period, + }), reconnect_to_lsp: period, update_fees: Some(period), update_graph: Some(period), diff --git a/eel/src/task_manager.rs b/eel/src/task_manager.rs index 29ca4f42..94aa454a 100644 --- a/eel/src/task_manager.rs +++ b/eel/src/task_manager.rs @@ -16,9 +16,14 @@ use tokio::time::Duration; pub(crate) type RestartIfFailedPeriod = Duration; +pub(crate) struct PeriodConfig { + pub failure_period: Duration, + pub success_period: Duration, +} + pub(crate) struct TaskPeriods { pub sync_blockchain: Duration, - pub update_lsp_info: Option, + pub update_lsp_info: Option, pub reconnect_to_lsp: Duration, pub update_fees: Option, pub update_graph: Option, @@ -101,8 +106,8 @@ impl TaskManager { .push(self.start_blockchain_sync(periods.sync_blockchain)); // LSP info update. - if let Some(period) = periods.update_lsp_info { - self.task_handles.push(self.start_lsp_info_update(period)); + if let Some(config) = periods.update_lsp_info { + self.task_handles.push(self.start_lsp_info_update(config)); } // Reconnect to LSP LN node. @@ -155,11 +160,11 @@ impl TaskManager { }) } - fn start_lsp_info_update(&self, period: Duration) -> RepeatingTaskHandle { + fn start_lsp_info_update(&self, config: PeriodConfig) -> RepeatingTaskHandle { let peer_manager = Arc::clone(&self.peer_manager); let lsp_client = Arc::clone(&self.lsp_client); let lsp_info = Arc::clone(&self.lsp_info); - self.runtime_handle.spawn_repeating_task(period, move || { + self.runtime_handle.spawn_self_restarting_task(move || { let peer_manager = Arc::clone(&peer_manager); let lsp_client = Arc::clone(&lsp_client); let lsp_info = Arc::clone(&lsp_info); @@ -179,8 +184,12 @@ impl TaskManager { error!("Connecting to peer {} failed: {}", peer, e); } } + Some(config.success_period) + } + Err(e) => { + error!("Failed to query LSP, retrying in 10 seconds: {}", e); + Some(config.failure_period) } - Err(e) => error!("Failed to query LSP: {}", e), } } }) diff --git a/eel/tests/p2p_connection_test.rs b/eel/tests/p2p_connection_test.rs index 7cf1ff41..d7245364 100644 --- a/eel/tests/p2p_connection_test.rs +++ b/eel/tests/p2p_connection_test.rs @@ -7,6 +7,8 @@ mod setup_env; #[cfg(feature = "nigiri")] mod p2p_connection_test { use bitcoin::hashes::hex::ToHex; + use eel::errors::RuntimeErrorCode; + use perro::runtime_error; use serial_test::file_parallel; use serial_test::file_serial; use std::thread::sleep; @@ -14,7 +16,7 @@ mod p2p_connection_test { use crate::setup::mocked_storage_node; use crate::setup_env::nigiri; use crate::setup_env::nigiri::NodeInstance; - use crate::wait_for_eq; + use crate::{wait_for_eq, wait_for_ok}; #[test] #[file_parallel(key, "/tmp/3l-int-tests-lock")] @@ -30,24 +32,26 @@ mod p2p_connection_test { #[test] #[file_serial(key, "/tmp/3l-int-tests-lock")] fn test_p2p_connection_with_unreliable_lsp() { - nigiri::ensure_environment_running(); + // Start the node when lspd isn't available + nigiri::pause_lspd(); let node = mocked_storage_node().start_or_panic(); - // Test disconnect when LSP is down. - { - // Let's shutdown LSPD LND. - nigiri::pause_lspd(); - wait_for_eq!(node.get_node_info().num_peers, 0); - } + assert_eq!( + node.query_lsp_fee(), + Err(runtime_error( + RuntimeErrorCode::LspServiceUnavailable, + "Failed to get LSP info" + )) + ); + assert_eq!(node.get_node_info().num_peers, 0); // Test reconnect when LSP is back. - { - // Now let's start LSPD LND again. - nigiri::start_lspd(); - nigiri::wait_for_healthy_lspd(); - wait_for_eq!(node.get_node_info().num_peers, 1); - let peers = nigiri::list_peers(NodeInstance::LspdLnd).unwrap(); - assert!(peers.contains(&node.get_node_info().node_pubkey.to_hex())); - } + nigiri::start_lspd(); + nigiri::ensure_environment_running(); + nigiri::wait_for_healthy_lspd(); + wait_for_eq!(node.get_node_info().num_peers, 1); + let peers = nigiri::list_peers(NodeInstance::LspdLnd).unwrap(); + assert!(peers.contains(&node.get_node_info().node_pubkey.to_hex())); + wait_for_ok!(node.query_lsp_fee()); } }