@@ -51,7 +51,7 @@ use crate::messagehandler::CommonLnEventCallback;
5151use crate :: nodemanager:: NodeManager ;
5252use crate :: nodemanager:: { ChannelClosure , MutinyBip21RawMaterials } ;
5353pub 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 } ;
5555use crate :: utils:: { now, sleep, spawn, spawn_with_handle, StopHandle } ;
5656use crate :: vss:: VSS_MANAGER ;
5757use crate :: { authclient:: MutinyAuthClient , logging:: MutinyLogger } ;
@@ -93,10 +93,12 @@ use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription};
9393use reqwest:: Client ;
9494use serde:: { Deserialize , Serialize } ;
9595
96- use std:: collections:: HashMap ;
97- use std:: collections:: HashSet ;
96+ use std:: collections:: { HashMap , HashSet } ;
9897use std:: str:: FromStr ;
99- use std:: sync:: Arc ;
98+ use std:: sync:: {
99+ atomic:: { AtomicBool , Ordering } ,
100+ Arc ,
101+ } ;
100102use std:: time:: Duration ;
101103#[ cfg( not( target_arch = "wasm32" ) ) ]
102104use 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 }
0 commit comments