@@ -519,32 +519,11 @@ impl<S: MutinyStorage> NodeManager<S> {
519519
520520 let gossip_sync = Arc :: new ( gossip_sync) ;
521521
522- let lsp_config: Option < LspConfig > =
523- match ( c. lsp_url . clone ( ) , c. lsp_connection_string . clone ( ) ) {
524- ( Some ( lsp_url) , None ) => {
525- if !lsp_url. is_empty ( ) && !c. safe_mode {
526- Some ( LspConfig :: new_voltage_flow ( lsp_url) )
527- } else {
528- None
529- }
530- }
531- ( None , Some ( lsp_connection_string) ) => {
532- if !lsp_connection_string. is_empty ( ) && !c. safe_mode {
533- Some ( LspConfig :: new_lsps ( lsp_connection_string, c. lsp_token ) )
534- } else {
535- None
536- }
537- }
538- ( Some ( _) , Some ( _) ) => {
539- // both shouldn't be set, surface error
540- log_error ! (
541- logger,
542- "Both lsp_url and lsp_connection_string should not be set."
543- ) ;
544- return Err ( MutinyError :: InvalidArgumentsError ) ;
545- }
546- ( None , None ) => None ,
547- } ;
522+ let lsp_config = if c. safe_mode {
523+ None
524+ } else {
525+ create_lsp_config ( c. lsp_url , c. lsp_connection_string , c. lsp_token ) ?
526+ } ;
548527
549528 let node_storage = storage. get_nodes ( ) ?;
550529
@@ -602,7 +581,7 @@ impl<S: MutinyStorage> NodeManager<S> {
602581
603582 log_info ! ( logger, "inserting updated nodes" ) ;
604583
605- storage. insert_nodes ( NodeStorage {
584+ storage. insert_nodes ( & NodeStorage {
606585 nodes : updated_nodes,
607586 version : node_storage. version + 1 ,
608587 } ) ?;
@@ -1492,6 +1471,45 @@ impl<S: MutinyStorage> NodeManager<S> {
14921471 Ok ( peers)
14931472 }
14941473
1474+ /// Changes all the node's LSPs to the given config. If any of the nodes have an active channel with the
1475+ /// current LSP, it will fail to change the LSP.
1476+ ///
1477+ /// Requires a restart of the node manager to take effect.
1478+ pub async fn change_lsp ( & self , lsp_config : Option < LspConfig > ) -> Result < ( ) , MutinyError > {
1479+ // if we are in safe mode we don't load the lightning state so we can't know if it is safe to change the LSP.
1480+ if self . safe_mode {
1481+ return Err ( MutinyError :: NotRunning ) ;
1482+ }
1483+
1484+ // check if any nodes have active channels with the current LSP
1485+ // if they do, we can't change the LSP
1486+ let nodes = self . nodes . lock ( ) . await ;
1487+ if nodes. iter ( ) . any ( |( _, n) | {
1488+ if let Some ( lsp_pk) = n. lsp_client . as_ref ( ) . map ( |x| x. get_lsp_pubkey ( ) ) {
1489+ !n. channel_manager
1490+ . list_channels_with_counterparty ( & lsp_pk)
1491+ . is_empty ( )
1492+ } else {
1493+ false
1494+ }
1495+ } ) {
1496+ return Err ( MutinyError :: LspGenericError ) ;
1497+ }
1498+ drop ( nodes) ;
1499+
1500+ // edit node storage
1501+ let mut node_storage = self . node_storage . lock ( ) . await ;
1502+ node_storage. nodes . iter_mut ( ) . for_each ( |( _, n) | {
1503+ n. lsp = lsp_config. clone ( ) ;
1504+ } ) ;
1505+ node_storage. version += 1 ; // update version for VSS
1506+
1507+ // save updated lsp to storage
1508+ self . storage . insert_nodes ( & node_storage) ?;
1509+
1510+ Ok ( ( ) )
1511+ }
1512+
14951513 /// Attempts to connect to a peer using either a specified node or the first available node.
14961514 pub async fn connect_to_peer (
14971515 & self ,
@@ -2359,7 +2377,7 @@ pub(crate) async fn create_new_node_from_node_manager<S: MutinyStorage>(
23592377 . nodes
23602378 . insert ( next_node_uuid. clone ( ) , next_node. clone ( ) ) ;
23612379
2362- node_manager. storage . insert_nodes ( existing_nodes. clone ( ) ) ?;
2380+ node_manager. storage . insert_nodes ( & existing_nodes) ?;
23632381 node_mutex. nodes = existing_nodes. nodes . clone ( ) ;
23642382
23652383 // now create the node process and init it
@@ -2403,6 +2421,32 @@ pub(crate) async fn create_new_node_from_node_manager<S: MutinyStorage>(
24032421 } )
24042422}
24052423
2424+ /// Turn parameterized LSP options into a [`LspConfig`].
2425+ pub fn create_lsp_config (
2426+ lsp_url : Option < String > ,
2427+ lsp_connection_string : Option < String > ,
2428+ lsp_token : Option < String > ,
2429+ ) -> Result < Option < LspConfig > , MutinyError > {
2430+ match ( lsp_url. clone ( ) , lsp_connection_string. clone ( ) ) {
2431+ ( Some ( lsp_url) , None ) => {
2432+ if !lsp_url. is_empty ( ) {
2433+ Ok ( Some ( LspConfig :: new_voltage_flow ( lsp_url) ) )
2434+ } else {
2435+ Ok ( None )
2436+ }
2437+ }
2438+ ( None , Some ( lsp_connection_string) ) => {
2439+ if !lsp_connection_string. is_empty ( ) {
2440+ Ok ( Some ( LspConfig :: new_lsps ( lsp_connection_string, lsp_token) ) )
2441+ } else {
2442+ Ok ( None )
2443+ }
2444+ }
2445+ ( Some ( _) , Some ( _) ) => Err ( MutinyError :: InvalidArgumentsError ) ,
2446+ ( None , None ) => Ok ( None ) ,
2447+ }
2448+ }
2449+
24062450#[ cfg( test) ]
24072451mod tests {
24082452 use crate :: {
0 commit comments