Skip to content

Commit 461e13f

Browse files
authored
Merge pull request #101 from EthanYuan/fix-set-device-internal
fix: `set_device_lock` loop internal and `update_lnd_snapshot` being unwritable for a long time
2 parents b473226 + 2575ff4 commit 461e13f

4 files changed

Lines changed: 80 additions & 45 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mutiny-core/src/lib.rs

Lines changed: 77 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use crate::messagehandler::CommonLnEventCallback;
5151
use crate::nodemanager::NodeManager;
5252
use crate::nodemanager::{ChannelClosure, MutinyBip21RawMaterials};
5353
pub use crate::onchain::BroadcastTx1InMultiOut;
54-
use crate::storage::{get_invoice_by_hash, LND_CHANNELS_SNAPSHOT_KEY};
54+
use crate::storage::{get_invoice_by_hash, DEVICE_LOCK_KEY, LND_CHANNELS_SNAPSHOT_KEY};
5555
use crate::utils::{now, sleep, spawn, spawn_with_handle, StopHandle};
5656
use crate::vss::VSS_MANAGER;
5757
use crate::{authclient::MutinyAuthClient, logging::MutinyLogger};
@@ -93,10 +93,12 @@ use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription};
9393
use reqwest::Client;
9494
use serde::{Deserialize, Serialize};
9595

96-
use std::collections::HashMap;
97-
use std::collections::HashSet;
96+
use std::collections::{HashMap, HashSet};
9897
use std::str::FromStr;
99-
use std::sync::Arc;
98+
use std::sync::{
99+
atomic::{AtomicBool, Ordering},
100+
Arc,
101+
};
100102
use std::time::Duration;
101103
#[cfg(not(target_arch = "wasm32"))]
102104
use std::time::Instant;
@@ -826,42 +828,56 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
826828
storage: &S,
827829
config: &MutinyWalletConfig,
828830
) {
829-
if let (Some(lsp_url), Ok(Some(node_id))) = (config.lsp_url.as_ref(), storage.get_node_id())
830-
{
831+
let (Some(lsp_url), Ok(Some(node_id))) = (config.lsp_url.as_ref(), storage.get_node_id())
832+
else {
833+
log_warn!(logger, "LSP URL or node ID not found");
834+
return;
835+
};
836+
837+
let first_lnd_snapshot =
831838
match fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger).await {
832-
Ok(first_lnd_snapshot) => {
833-
log_debug!(
834-
logger,
835-
"First fetched lnd snapshot: {:?}",
836-
first_lnd_snapshot
837-
);
838-
if !VSS_MANAGER.has_in_progress() {
839-
if let Ok(second_lnd_snapshot) =
840-
fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger)
841-
.await
842-
{
843-
log_debug!(
844-
logger,
845-
"Second fetched lnd snapshot: {:?}",
846-
second_lnd_snapshot
847-
);
848-
if first_lnd_snapshot.snapshot == second_lnd_snapshot.snapshot {
849-
log_debug!(logger, "Saving lnd snapshot");
850-
if let Err(e) = storage.write_data(
851-
LND_CHANNELS_SNAPSHOT_KEY.to_string(),
852-
&second_lnd_snapshot,
853-
Some(now().as_secs() as u32),
854-
) {
855-
log_error!(logger, "Error saving lnd snapshot: {e}");
856-
}
857-
}
858-
}
859-
}
839+
Ok(snapshot) => {
840+
log_debug!(logger, "First fetched lnd snapshot: {:?}", snapshot);
841+
snapshot
860842
}
861843
Err(e) => {
862-
log_error!(logger, "Error fetching lnd channels: {e}");
844+
log_error!(logger, "First lnd snapshot fetch failed: {e}");
845+
return;
846+
}
847+
};
848+
849+
let pending = VSS_MANAGER.get_pending_writes();
850+
if pending.is_empty()
851+
|| (pending.len() == 1 && pending.iter().any(|(key, _)| key == DEVICE_LOCK_KEY))
852+
{
853+
let second_lnd_snapshot =
854+
match fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger).await
855+
{
856+
Ok(snapshot) => {
857+
log_debug!(logger, "Second fetched lnd snapshot: {:?}", snapshot);
858+
snapshot
859+
}
860+
Err(e) => {
861+
log_error!(logger, "Second lnd snapshot fetch failed: {e}");
862+
return;
863+
}
864+
};
865+
if first_lnd_snapshot.snapshot == second_lnd_snapshot.snapshot {
866+
log_debug!(logger, "Saving lnd snapshot");
867+
if let Err(e) = storage.write_data(
868+
LND_CHANNELS_SNAPSHOT_KEY.to_string(),
869+
&second_lnd_snapshot,
870+
Some(now().as_secs() as u32),
871+
) {
872+
log_error!(logger, "Error saving lnd snapshot: {e}");
863873
}
864874
}
875+
} else {
876+
log_info!(
877+
logger,
878+
"VSS writing in progress: {:?}, skipping lnd snapshot update",
879+
pending
880+
);
865881
}
866882
}
867883

@@ -960,6 +976,7 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
960976
let storage_clone = self.storage.clone();
961977
let logger_clone = logger.clone();
962978
let device_lock_stop_handle = spawn_with_handle(|stop_signal| async move {
979+
let is_updating_lnd_snapshot = Arc::new(AtomicBool::new(false));
963980
loop {
964981
if stop_signal.stopping() {
965982
log_debug!(logger_clone, "stopping claim device lock");
@@ -982,21 +999,38 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
982999
)
9831000
.await
9841001
{
985-
log_error!(logger_clone, "Error setting device lock: {e}");
986-
} else {
987-
log_debug!(logger_clone, "Device lock set");
988-
Self::update_lnd_snapshot(logger_clone.clone(), &storage_clone, config).await;
1002+
log_warn!(logger_clone, "Error setting device lock: {e} ");
1003+
if MutinyError::AlreadyRunning == e {
1004+
sleep((DEVICE_LOCK_INTERVAL_SECS * 1000) as i32).await;
1005+
}
1006+
continue;
9891007
}
9901008

9911009
log_debug!(
9921010
logger_clone,
993-
"Vss pending writes: {:?}",
994-
VSS_MANAGER.get_pending_writes()
1011+
"Device lock set. VSS write is async and may still be in progress."
9951012
);
9961013

997-
let mut remained_sleep_ms = (DEVICE_LOCK_INTERVAL_SECS * 1000) as i32;
1014+
if !is_updating_lnd_snapshot.swap(true, Ordering::SeqCst) {
1015+
let logger_for_task = logger_clone.clone();
1016+
let storage_for_task = storage_clone.clone();
1017+
let config_for_task = config.clone();
1018+
let snapshot_flag = is_updating_lnd_snapshot.clone();
1019+
1020+
spawn(async move {
1021+
Self::update_lnd_snapshot(
1022+
logger_for_task.clone(),
1023+
&storage_for_task,
1024+
&config_for_task,
1025+
)
1026+
.await;
1027+
snapshot_flag.store(false, Ordering::SeqCst);
1028+
});
1029+
}
1030+
1031+
let sleep_ms = 300;
1032+
let mut remained_sleep_ms = (DEVICE_LOCK_INTERVAL_SECS * 1000) as i32 - sleep_ms;
9981033
while !stop_signal.stopping() && remained_sleep_ms > 0 {
999-
let sleep_ms = 300;
10001034
sleep(sleep_ms).await;
10011035
remained_sleep_ms -= sleep_ms;
10021036
}

mutiny-core/src/vss.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ impl VssManager {
249249
}
250250

251251
pub fn get_pending_writes(&self) -> Vec<(String, VssPendingWrite)> {
252+
self.check_timeout();
252253
let writes = self.pending_writes.lock().expect(
253254
"
254255
Failed to lock pending writes",

mutiny-wasm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cargo-features = ["per-package-target"]
22

33
[package]
44
name = "mutiny-wasm"
5-
version = "1.14.3"
5+
version = "1.14.4"
66
edition = "2021"
77
authors = ["utxostack"]
88
forced-target = "wasm32-unknown-unknown"

0 commit comments

Comments
 (0)