@@ -58,7 +58,7 @@ use util::errors::APIError;
58
58
use std:: { cmp, mem} ;
59
59
use std:: collections:: { HashMap , hash_map, HashSet } ;
60
60
use std:: io:: { Cursor , Read } ;
61
- use std:: sync:: { Arc , Mutex , MutexGuard , RwLock } ;
61
+ use std:: sync:: { Arc , Mutex , MutexGuard , RwLock , Condvar } ;
62
62
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
63
63
use std:: time:: Duration ;
64
64
use std:: marker:: { Sync , Send } ;
@@ -439,6 +439,41 @@ pub struct ChannelManager<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref,
439
439
/// Taken first everywhere where we are making changes before any other locks.
440
440
total_consistency_lock : RwLock < ( ) > ,
441
441
442
+ /// Used to signal to the ChannelManager persister that the manager needs to be re-persisted to
443
+ /// disk/backups.
444
+ /// Example usage:
445
+ /// ```
446
+ /// use std::sync::Arc;
447
+ /// type TxBroadcaster = dyn lightning::chain::chaininterface::BroadcasterInterface;
448
+ /// type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator;
449
+ /// type Logger = dyn lightning::util::logger::Logger;
450
+ /// type ChainAccess = dyn lightning::chain::Access;
451
+ /// type ChainFilter = dyn lightning::chain::Filter;
452
+ /// type DataPersister = dyn lightning::chain::channelmonitor::Persist<lightning::chain::keysinterface::InMemoryChannelKeys>;
453
+ /// type ChainMonitor = lightning::chain::chainmonitor::ChainMonitor<lightning::chain::keysinterface::InMemoryChannelKeys, Arc<ChainFilter>, Arc<TxBroadcaster>, Arc<FeeEstimator>, Arc<Logger>, Arc<DataPersister>>;
454
+ /// type ChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager<ChainMonitor, TxBroadcaster, FeeEstimator, Logger>;
455
+ /// fn start(manager: ChannelManager) {
456
+ /// let mutcond = Arc::clone(&manager.persistence_lock);
457
+ /// // ChannelManager persistence should generally be run in a background thread since it can be
458
+ /// // time-consuming to persist.
459
+ /// std::thread::spawn(move || {
460
+ /// let &(ref mtx, ref cnd) = &*mutcond;
461
+ /// loop {
462
+ /// let mut guard = mtx.lock().unwrap();
463
+ /// // If there's a new update, we break out of the while loop, reset the condition variable,
464
+ /// // and persist the ChannelManager to disk/backups.
465
+ /// while !*guard {
466
+ /// guard = cnd.wait(guard).unwrap();
467
+ /// }
468
+ /// *guard = false;
469
+ /// std::mem::drop(guard); // Don't hold the lock while persisting the ChannelManager.
470
+ /// // Persist the ChannelManager here.
471
+ /// }
472
+ /// });
473
+ /// }
474
+ /// ```
475
+ pub persistence_lock : Arc < ( Mutex < bool > , Condvar ) > ,
476
+
442
477
keys_manager : K ,
443
478
444
479
logger : L ,
@@ -760,6 +795,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
760
795
pending_events : Mutex :: new ( Vec :: new ( ) ) ,
761
796
total_consistency_lock : RwLock :: new ( ( ) ) ,
762
797
798
+ persistence_lock : Arc :: new ( ( Mutex :: new ( false ) , Condvar :: new ( ) ) ) ,
799
+
763
800
keys_manager,
764
801
765
802
logger,
@@ -913,6 +950,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
913
950
// the latest local state, which is the best we can do anyway. Thus, it is safe to
914
951
// ignore the result here.
915
952
let _ = self . chain_monitor . update_channel ( funding_txo, monitor_update) ;
953
+ self . persist_updates ( ) ;
916
954
}
917
955
}
918
956
@@ -1313,6 +1351,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
1313
1351
commitment_signed,
1314
1352
} ,
1315
1353
} ) ;
1354
+ self . persist_updates ( ) ;
1316
1355
} ,
1317
1356
None => { } ,
1318
1357
}
@@ -1707,6 +1746,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
1707
1746
commitment_signed : commitment_msg,
1708
1747
} ,
1709
1748
} ) ;
1749
+ self . persist_updates ( ) ;
1710
1750
}
1711
1751
} else {
1712
1752
unreachable ! ( ) ;
@@ -2126,6 +2166,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2126
2166
}
2127
2167
} ) ;
2128
2168
}
2169
+ self . persist_updates ( ) ;
2129
2170
return Ok ( ( ) )
2130
2171
} ,
2131
2172
Err ( e) => {
@@ -2340,6 +2381,15 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2340
2381
Ok ( ( ) )
2341
2382
}
2342
2383
2384
+ // Signal to the ChannelManager persister that there are updates necessitating persisting to disk.
2385
+ fn persist_updates ( & self ) {
2386
+ let & ( ref persist_mtx, ref cnd) = & * self . persistence_lock ;
2387
+ let mut persistence_lock = persist_mtx. lock ( ) . unwrap ( ) ;
2388
+ * persistence_lock = true ;
2389
+ cnd. notify_all ( ) ;
2390
+
2391
+ }
2392
+
2343
2393
fn internal_funding_created ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: FundingCreated ) -> Result < ( ) , MsgHandleErrInternal > {
2344
2394
let ( ( funding_msg, monitor) , mut chan) = {
2345
2395
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
@@ -2379,6 +2429,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2379
2429
} ,
2380
2430
}
2381
2431
}
2432
+
2433
+ self . persist_updates ( ) ;
2434
+
2382
2435
let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2383
2436
let channel_state = & mut * channel_state_lock;
2384
2437
match channel_state. by_id . entry ( funding_msg. channel_id ) {
@@ -2417,6 +2470,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2417
2470
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
2418
2471
}
2419
2472
} ;
2473
+
2474
+ self . persist_updates ( ) ;
2475
+
2420
2476
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
2421
2477
pending_events. push ( events:: Event :: FundingBroadcastSafe {
2422
2478
funding_txo,
@@ -2712,6 +2768,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2712
2768
msg,
2713
2769
} ) ;
2714
2770
}
2771
+ self . persist_updates ( ) ;
2715
2772
Ok ( ( ) )
2716
2773
} ,
2717
2774
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
@@ -2803,9 +2860,13 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2803
2860
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , failure. 0 , & failure. 1 , failure. 2 ) ;
2804
2861
}
2805
2862
self . forward_htlcs ( & mut [ ( short_channel_id, channel_outpoint, pending_forwards) ] ) ;
2863
+ self . persist_updates ( ) ;
2806
2864
Ok ( ( ) )
2807
2865
} ,
2808
- Err ( e) => Err ( e)
2866
+ Err ( e) => {
2867
+ self . persist_updates ( ) ;
2868
+ Err ( e)
2869
+ }
2809
2870
}
2810
2871
}
2811
2872
@@ -2946,6 +3007,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2946
3007
msg,
2947
3008
} ) ;
2948
3009
}
3010
+ self . persist_updates ( ) ;
2949
3011
Ok ( ( ) )
2950
3012
} ,
2951
3013
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
@@ -2995,6 +3057,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2995
3057
commitment_signed,
2996
3058
} ,
2997
3059
} ) ;
3060
+ self . persist_updates ( ) ;
2998
3061
}
2999
3062
} ,
3000
3063
}
@@ -3994,6 +4057,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De
3994
4057
3995
4058
pending_events : Mutex :: new ( pending_events_read) ,
3996
4059
total_consistency_lock : RwLock :: new ( ( ) ) ,
4060
+ persistence_lock : Arc :: new ( ( Mutex :: new ( false ) , Condvar :: new ( ) ) ) ,
3997
4061
keys_manager : args. keys_manager ,
3998
4062
logger : args. logger ,
3999
4063
default_configuration : args. default_config ,
0 commit comments