From 443939cf9a7f321ff27ce42bc9372e8ce54e68ca Mon Sep 17 00:00:00 2001 From: Justin Moeller Date: Tue, 15 Oct 2024 16:40:14 -0500 Subject: [PATCH] fix: gateway registration exits early --- gateway/ln-gateway/src/lib.rs | 87 +++++++++++---------- gateway/ln-gateway/src/state_machine/mod.rs | 15 ++-- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/gateway/ln-gateway/src/lib.rs b/gateway/ln-gateway/src/lib.rs index 62af4d7db13..cc4ac72bb05 100644 --- a/gateway/ln-gateway/src/lib.rs +++ b/gateway/ln-gateway/src/lib.rs @@ -95,7 +95,7 @@ use rpc::{ }; use state_machine::{GatewayClientModule, GatewayExtPayStates}; use tokio::sync::RwLock; -use tracing::{debug, error, info, info_span, warn, Instrument}; +use tracing::{debug, error, info, info_span, warn}; use crate::config::LightningModuleMode; use crate::db::{get_gatewayd_database_migrations, FederationConfig}; @@ -1157,14 +1157,14 @@ impl Gateway { Self::check_lnv1_federation_network(&client, gateway_config.network).await?; client .get_first_module::()? - .register_with_federation( + .try_register_with_federation( // Route hints will be updated in the background Vec::new(), GW_ANNOUNCEMENT_TTL, federation_config.fees, lightning_context, ) - .await?; + .await; } if self.is_running_lnv2() { @@ -1355,14 +1355,23 @@ impl Gateway { // If 'num_route_hints' is provided, all federations must be re-registered. // Otherwise, only those affected by the new fees need to be re-registered. + let register_task_group = TaskGroup::new(); if num_route_hints.is_some() { let all_federations_configs: Vec<_> = dbtx.load_federation_configs().await.into_iter().collect(); - self.register_federations(&new_gateway_config, &all_federations_configs) - .await?; + self.register_federations( + &new_gateway_config, + &all_federations_configs, + ®ister_task_group, + ) + .await; } else { - self.register_federations(&new_gateway_config, ®ister_federations) - .await?; + self.register_federations( + &new_gateway_config, + ®ister_federations, + ®ister_task_group, + ) + .await; } dbtx.commit_tx().await; @@ -1623,7 +1632,8 @@ impl Gateway { &self, gateway_config: &GatewayConfiguration, federations: &[(FederationId, FederationConfig)], - ) -> AdminResult<()> { + register_task_group: &TaskGroup, + ) { if let Ok(lightning_context) = self.get_lightning_context().await { let route_hints = lightning_context .lnrpc @@ -1634,31 +1644,34 @@ impl Gateway { } for (federation_id, federation_config) in federations { - if let Some(client) = self.federation_manager.read().await.client(federation_id) { - if async { - client - .value() - .get_first_module::()? - .register_with_federation( - route_hints.clone(), - GW_ANNOUNCEMENT_TTL, - federation_config.fees, - lightning_context.clone(), - ) - .await - } - .instrument(client.span()) - .await - .is_err() + let fed_manager = self.federation_manager.read().await; + if let Some(client) = fed_manager.client(federation_id) { + let client_arc = client.clone().into_value(); + let route_hints = route_hints.clone(); + let lightning_context = lightning_context.clone(); + let federation_config = federation_config.clone(); + + if let Err(e) = register_task_group + .spawn_cancellable("register_federation", async move { + let gateway_client = client_arc + .get_first_module::() + .expect("No GatewayClientModule exists"); + gateway_client + .try_register_with_federation( + route_hints, + GW_ANNOUNCEMENT_TTL, + federation_config.fees, + lightning_context, + ) + .await; + }) + .await { - Err(AdminGatewayError::RegistrationError { - federation_id: *federation_id, - })?; + warn!(?e, "Failed to shutdown register federation task"); } } } } - Ok(()) } /// This function will return a `GatewayConfiguration` one of two @@ -1798,17 +1811,16 @@ impl Gateway { let lightning_module_mode = self.lightning_module_mode; info!(?lightning_module_mode, "Spawning register task..."); let gateway = self.clone(); + let register_task_group = task_group.make_subgroup(); task_group.spawn_cancellable("register clients", async move { loop { - let mut registration_result: Option> = None; let gateway_config = gateway.clone_gateway_config().await; if let Some(gateway_config) = gateway_config { let gateway_state = gateway.get_state().await; if let GatewayState::Running { .. } = &gateway_state { let mut dbtx = gateway.gateway_db.begin_transaction_nc().await; let all_federations_configs: Vec<_> = dbtx.load_federation_configs().await.into_iter().collect(); - let result = gateway.register_federations(&gateway_config, &all_federations_configs).await; - registration_result = Some(result); + gateway.register_federations(&gateway_config, &all_federations_configs, ®ister_task_group).await; } else { // We need to retry more often if the gateway is not in the Running state const NOT_RUNNING_RETRY: Duration = Duration::from_secs(10); @@ -1820,16 +1832,9 @@ impl Gateway { warn!("Cannot register clients because gateway configuration is not set."); } - let registration_delay: Duration = if let Some(Err(AdminGatewayError::RegistrationError { .. })) = registration_result { - // Retry to register gateway with federations in 10 seconds since it failed - Duration::from_secs(10) - } else { - // Allow a 15% buffer of the TTL before the re-registering gateway - // with the federations. - GW_ANNOUNCEMENT_TTL.mul_f32(0.85) - }; - - sleep(registration_delay).await; + // Allow a 15% buffer of the TTL before the re-registering gateway + // with the federations. + sleep(GW_ANNOUNCEMENT_TTL.mul_f32(0.85)).await; } }); } diff --git a/gateway/ln-gateway/src/state_machine/mod.rs b/gateway/ln-gateway/src/state_machine/mod.rs index f81de979d80..0bf7996d9f1 100644 --- a/gateway/ln-gateway/src/state_machine/mod.rs +++ b/gateway/ln-gateway/src/state_machine/mod.rs @@ -345,13 +345,13 @@ impl GatewayClientModule { } /// Register gateway with federation - pub async fn register_with_federation( + pub async fn try_register_with_federation( &self, route_hints: Vec, time_to_live: Duration, fees: RoutingFees, lightning_context: LightningContext, - ) -> anyhow::Result<()> { + ) { let registration_info = self.to_gateway_registration_info(route_hints, time_to_live, fees, lightning_context); let gateway_id = registration_info.info.gateway_id; @@ -362,9 +362,14 @@ impl GatewayClientModule { .await .global .calculate_federation_id(); - self.module_api.register_gateway(®istration_info).await?; - debug!("Successfully registered gateway {gateway_id} with federation {federation_id}"); - Ok(()) + if let Err(e) = self.module_api.register_gateway(®istration_info).await { + warn!( + ?e, + "Failed to register gateway {gateway_id} with federation {federation_id}" + ); + } else { + info!("Successfully registered gateway {gateway_id} with federation {federation_id}"); + } } /// Attempts to remove a gateway's registration from the federation. Since