Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit f543c92

Browse files
committed
Add helper function for changing LSP config
1 parent ccf3631 commit f543c92

File tree

3 files changed

+95
-30
lines changed

3 files changed

+95
-30
lines changed

mutiny-core/src/nodemanager.rs

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
24072451
mod tests {
24082452
use crate::{

mutiny-core/src/storage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ pub trait MutinyStorage: Clone + Sized + Send + Sync + 'static {
344344
}
345345

346346
/// Inserts the node indexes into storage
347-
fn insert_nodes(&self, nodes: NodeStorage) -> Result<(), MutinyError> {
347+
fn insert_nodes(&self, nodes: &NodeStorage) -> Result<(), MutinyError> {
348348
let version = Some(nodes.version);
349349
self.set_data(NODES_KEY.to_string(), nodes, version)
350350
}

mutiny-wasm/src/lib.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ use mutiny_core::redshift::RedshiftRecipient;
4040
use mutiny_core::storage::{DeviceLock, MutinyStorage, DEVICE_LOCK_KEY};
4141
use mutiny_core::utils::{now, sleep};
4242
use mutiny_core::vss::MutinyVssClient;
43-
use mutiny_core::{labels::LabelStorage, nodemanager::NodeManager};
43+
use mutiny_core::{
44+
labels::LabelStorage,
45+
nodemanager::{create_lsp_config, NodeManager},
46+
};
4447
use mutiny_core::{logging::MutinyLogger, nostr::ProfileType};
4548
use nostr::key::XOnlyPublicKey;
4649
use nostr::prelude::FromBech32;
@@ -636,6 +639,24 @@ impl MutinyWallet {
636639
)?)
637640
}
638641

642+
/// Changes all the node's LSPs to the given config. If any of the nodes have an active channel with the
643+
/// current LSP, it will fail to change the LSP.
644+
///
645+
/// Requires a restart of the node manager to take effect.
646+
pub async fn change_lsp(
647+
&self,
648+
lsp_url: Option<String>,
649+
lsp_connection_string: Option<String>,
650+
lsp_token: Option<String>,
651+
) -> Result<(), MutinyJsError> {
652+
let lsp_config = create_lsp_config(lsp_url, lsp_connection_string, lsp_token)?;
653+
654+
self.inner.node_manager.change_lsp(lsp_config).await?;
655+
// sleep 250ms to let storage take effect
656+
sleep(250).await;
657+
Ok(())
658+
}
659+
639660
/// Attempts to connect to a peer from the selected node.
640661
#[wasm_bindgen]
641662
pub async fn connect_to_peer(

0 commit comments

Comments
 (0)