@@ -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 ,
@@ -759,6 +794,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
759
794
pending_events : Mutex :: new ( Vec :: new ( ) ) ,
760
795
total_consistency_lock : RwLock :: new ( ( ) ) ,
761
796
797
+ persistence_lock : Arc :: new ( ( Mutex :: new ( false ) , Condvar :: new ( ) ) ) ,
798
+
762
799
keys_manager,
763
800
764
801
logger,
@@ -912,6 +949,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
912
949
// the latest local state, which is the best we can do anyway. Thus, it is safe to
913
950
// ignore the result here.
914
951
let _ = self . chain_monitor . update_channel ( funding_txo, monitor_update) ;
952
+ self . persist_updates ( ) ;
915
953
}
916
954
}
917
955
@@ -1312,6 +1350,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
1312
1350
commitment_signed,
1313
1351
} ,
1314
1352
} ) ;
1353
+ self . persist_updates ( ) ;
1315
1354
} ,
1316
1355
None => { } ,
1317
1356
}
@@ -1706,6 +1745,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
1706
1745
commitment_signed : commitment_msg,
1707
1746
} ,
1708
1747
} ) ;
1748
+ self . persist_updates ( ) ;
1709
1749
}
1710
1750
} else {
1711
1751
unreachable ! ( ) ;
@@ -2125,6 +2165,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2125
2165
}
2126
2166
} ) ;
2127
2167
}
2168
+ self . persist_updates ( ) ;
2128
2169
return Ok ( ( ) )
2129
2170
} ,
2130
2171
Err ( e) => {
@@ -2339,6 +2380,15 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2339
2380
Ok ( ( ) )
2340
2381
}
2341
2382
2383
+ // Signal to the ChannelManager persister that there are updates necessitating persisting to disk.
2384
+ fn persist_updates ( & self ) {
2385
+ let & ( ref persist_mtx, ref cnd) = & * self . persistence_lock ;
2386
+ let mut persistence_lock = persist_mtx. lock ( ) . unwrap ( ) ;
2387
+ * persistence_lock = true ;
2388
+ cnd. notify_all ( ) ;
2389
+
2390
+ }
2391
+
2342
2392
fn internal_funding_created ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: FundingCreated ) -> Result < ( ) , MsgHandleErrInternal > {
2343
2393
let ( ( funding_msg, monitor) , mut chan) = {
2344
2394
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
@@ -2373,6 +2423,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2373
2423
} ,
2374
2424
}
2375
2425
}
2426
+
2427
+ self . persist_updates ( ) ;
2428
+
2376
2429
let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2377
2430
let channel_state = & mut * channel_state_lock;
2378
2431
match channel_state. by_id . entry ( funding_msg. channel_id ) {
@@ -2411,6 +2464,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2411
2464
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
2412
2465
}
2413
2466
} ;
2467
+
2468
+ self . persist_updates ( ) ;
2469
+
2414
2470
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
2415
2471
pending_events. push ( events:: Event :: FundingBroadcastSafe {
2416
2472
funding_txo,
@@ -2706,6 +2762,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2706
2762
msg,
2707
2763
} ) ;
2708
2764
}
2765
+ self . persist_updates ( ) ;
2709
2766
Ok ( ( ) )
2710
2767
} ,
2711
2768
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
@@ -2797,9 +2854,13 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2797
2854
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , failure. 0 , & failure. 1 , failure. 2 ) ;
2798
2855
}
2799
2856
self . forward_htlcs ( & mut [ ( short_channel_id, channel_outpoint, pending_forwards) ] ) ;
2857
+ self . persist_updates ( ) ;
2800
2858
Ok ( ( ) )
2801
2859
} ,
2802
- Err ( e) => Err ( e)
2860
+ Err ( e) => {
2861
+ self . persist_updates ( ) ;
2862
+ Err ( e)
2863
+ }
2803
2864
}
2804
2865
}
2805
2866
@@ -2940,6 +3001,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2940
3001
msg,
2941
3002
} ) ;
2942
3003
}
3004
+ self . persist_updates ( ) ;
2943
3005
Ok ( ( ) )
2944
3006
} ,
2945
3007
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
@@ -2989,6 +3051,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2989
3051
commitment_signed,
2990
3052
} ,
2991
3053
} ) ;
3054
+ self . persist_updates ( ) ;
2992
3055
}
2993
3056
} ,
2994
3057
}
@@ -3988,6 +4051,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De
3988
4051
3989
4052
pending_events : Mutex :: new ( pending_events_read) ,
3990
4053
total_consistency_lock : RwLock :: new ( ( ) ) ,
4054
+ persistence_lock : Arc :: new ( ( Mutex :: new ( false ) , Condvar :: new ( ) ) ) ,
3991
4055
keys_manager : args. keys_manager ,
3992
4056
logger : args. logger ,
3993
4057
default_configuration : args. default_config ,
0 commit comments