Skip to content

Commit 7fa499c

Browse files
committed
Separate ChannelManager needing persistence from having events
Currently, when a ChannelManager generates a notification for the background processor, any pending events are handled and the ChannelManager is always re-persisted. Many channel related messages don't actually change the channel state in a way that changes the persisted channel. For example, an `update_add_htlc` or `update_fail_htlc` message simply adds the change to a queue, changing the channel state when we receive a `commitment_signed` message. In these cases we shouldn't be re-persisting the ChannelManager as it hasn't changed (persisted) state at all. In anticipation of doing so in the next few commits, here we make the public API handle the two concepts (somewhat) separately. The notification still goes out via a single waker, however whether or not to persist is now handled via a separate atomic bool.
1 parent 63e6b80 commit 7fa499c

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ macro_rules! define_run_body {
315315
// see `await_start`'s use below.
316316
let mut await_start = None;
317317
if $check_slow_await { await_start = Some($get_timer(1)); }
318-
let updates_available = $await;
318+
$await;
319319
let await_slow = if $check_slow_await { $timer_elapsed(&mut await_start.unwrap(), 1) } else { false };
320320

321321
// Exit the loop if the background processor was requested to stop.
@@ -324,7 +324,7 @@ macro_rules! define_run_body {
324324
break;
325325
}
326326

327-
if updates_available {
327+
if $channel_manager.get_and_clear_needs_persistence() {
328328
log_trace!($logger, "Persisting ChannelManager...");
329329
$persister.persist_manager(&*$channel_manager)?;
330330
log_trace!($logger, "Done persisting ChannelManager.");
@@ -660,11 +660,9 @@ where
660660
c: sleeper(if mobile_interruptable_platform { Duration::from_millis(100) } else { Duration::from_secs(FASTEST_TIMER) }),
661661
};
662662
match fut.await {
663-
SelectorOutput::A => true,
664-
SelectorOutput::B => false,
663+
SelectorOutput::A|SelectorOutput::B => {},
665664
SelectorOutput::C(exit) => {
666665
should_break = exit;
667-
false
668666
}
669667
}
670668
}, |t| sleeper(Duration::from_secs(t)),
@@ -787,10 +785,10 @@ impl BackgroundProcessor {
787785
define_run_body!(persister, chain_monitor, chain_monitor.process_pending_events(&event_handler),
788786
channel_manager, channel_manager.process_pending_events(&event_handler),
789787
gossip_sync, peer_manager, logger, scorer, stop_thread.load(Ordering::Acquire),
790-
Sleeper::from_two_futures(
788+
{ Sleeper::from_two_futures(
791789
channel_manager.get_event_or_persistence_needed_future(),
792790
chain_monitor.get_update_future()
793-
).wait_timeout(Duration::from_millis(100)),
791+
).wait_timeout(Duration::from_millis(100)); },
794792
|_| Instant::now(), |time: &Instant, dur| time.elapsed().as_secs() > dur, false)
795793
});
796794
Self { stop_thread: stop_thread_clone, thread_handle: Some(handle) }

lightning/src/ln/channelmanager.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,7 @@ where
11861186
background_events_processed_since_startup: AtomicBool,
11871187

11881188
event_persist_notifier: Notifier,
1189+
needs_persist_flag: AtomicBool,
11891190

11901191
entropy_source: ES,
11911192
node_signer: NS,
@@ -1229,6 +1230,7 @@ enum NotifyOption {
12291230
/// `optionally_notify` which returns a `NotifyOption`.
12301231
struct PersistenceNotifierGuard<'a, F: Fn() -> NotifyOption> {
12311232
event_persist_notifier: &'a Notifier,
1233+
needs_persist_flag: &'a AtomicBool,
12321234
should_persist: F,
12331235
// We hold onto this result so the lock doesn't get released immediately.
12341236
_read_guard: RwLockReadGuard<'a, ()>,
@@ -1246,6 +1248,7 @@ impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> { // We don't care w
12461248

12471249
PersistenceNotifierGuard {
12481250
event_persist_notifier: &cm.get_cm().event_persist_notifier,
1251+
needs_persist_flag: &cm.get_cm().needs_persist_flag,
12491252
should_persist: move || {
12501253
// Pick the "most" action between `persist_check` and the background events
12511254
// processing and return that.
@@ -1266,6 +1269,7 @@ impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> { // We don't care w
12661269

12671270
PersistenceNotifierGuard {
12681271
event_persist_notifier: &cm.get_cm().event_persist_notifier,
1272+
needs_persist_flag: &cm.get_cm().needs_persist_flag,
12691273
should_persist: persist_check,
12701274
_read_guard: read_guard,
12711275
}
@@ -1275,6 +1279,7 @@ impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> { // We don't care w
12751279
impl<'a, F: Fn() -> NotifyOption> Drop for PersistenceNotifierGuard<'a, F> {
12761280
fn drop(&mut self) {
12771281
if (self.should_persist)() == NotifyOption::DoPersist {
1282+
self.needs_persist_flag.store(true, Ordering::Release);
12781283
self.event_persist_notifier.notify();
12791284
}
12801285
}
@@ -2137,6 +2142,7 @@ macro_rules! process_events_body {
21372142
}
21382143

21392144
if result == NotifyOption::DoPersist {
2145+
$self.needs_persist_flag.store(true, Ordering::Release);
21402146
$self.event_persist_notifier.notify();
21412147
}
21422148
}
@@ -2216,7 +2222,9 @@ where
22162222
pending_background_events: Mutex::new(Vec::new()),
22172223
total_consistency_lock: RwLock::new(()),
22182224
background_events_processed_since_startup: AtomicBool::new(false),
2225+
22192226
event_persist_notifier: Notifier::new(),
2227+
needs_persist_flag: AtomicBool::new(false),
22202228

22212229
entropy_source,
22222230
node_signer,
@@ -7381,15 +7389,23 @@ where
73817389
}
73827390
}
73837391

7384-
/// Gets a [`Future`] that completes when this [`ChannelManager`] needs to be persisted.
7392+
/// Gets a [`Future`] that completes when this [`ChannelManager`] may need to be persisted or
7393+
/// may have events that need processing.
7394+
///
7395+
/// In order to check if this [`ChannelManager`] needs persisting, call
7396+
/// [`Self::get_and_clear_needs_persistence`].
73857397
///
73867398
/// Note that callbacks registered on the [`Future`] MUST NOT call back into this
73877399
/// [`ChannelManager`] and should instead register actions to be taken later.
7388-
///
73897400
pub fn get_event_or_persistence_needed_future(&self) -> Future {
73907401
self.event_persist_notifier.get_future()
73917402
}
73927403

7404+
/// Returns true if this [`ChannelManager`] needs to be persisted.
7405+
pub fn get_and_clear_needs_persistence(&self) -> bool {
7406+
self.needs_persist_flag.swap(false, Ordering::AcqRel)
7407+
}
7408+
73937409
#[cfg(any(test, feature = "_test_utils"))]
73947410
pub fn get_event_or_persist_condvar_value(&self) -> bool {
73957411
self.event_persist_notifier.notify_pending()
@@ -9562,7 +9578,9 @@ where
95629578
pending_background_events: Mutex::new(pending_background_events),
95639579
total_consistency_lock: RwLock::new(()),
95649580
background_events_processed_since_startup: AtomicBool::new(false),
9581+
95659582
event_persist_notifier: Notifier::new(),
9583+
needs_persist_flag: AtomicBool::new(false),
95669584

95679585
entropy_source: args.entropy_source,
95689586
node_signer: args.node_signer,

0 commit comments

Comments
 (0)