@@ -1277,7 +1277,11 @@ enum BackgroundEvent {
12771277 /// Some [`ChannelMonitorUpdate`] (s) completed before we were serialized but we still have
12781278 /// them marked pending, thus we need to run any [`MonitorUpdateCompletionAction`] (s) pending
12791279 /// on a channel.
1280- MonitorUpdatesComplete { counterparty_node_id: PublicKey, channel_id: ChannelId },
1280+ MonitorUpdatesComplete {
1281+ counterparty_node_id: PublicKey,
1282+ channel_id: ChannelId,
1283+ highest_update_id_completed: u64,
1284+ },
12811285}
12821286
12831287/// A pointer to a channel that is unblocked when an event is surfaced
@@ -8153,7 +8157,36 @@ impl<
81538157 BackgroundEvent::MonitorUpdateRegeneratedOnStartup { counterparty_node_id, funding_txo, channel_id, update } => {
81548158 self.apply_post_close_monitor_update(counterparty_node_id, channel_id, funding_txo, update);
81558159 },
8156- BackgroundEvent::MonitorUpdatesComplete { counterparty_node_id, channel_id } => {
8160+ BackgroundEvent::MonitorUpdatesComplete {
8161+ counterparty_node_id,
8162+ channel_id,
8163+ highest_update_id_completed,
8164+ } => {
8165+ // Now that we can finally handle the background event, remove all in-flight
8166+ // monitor updates for this channel that we've known to complete, as they have
8167+ // already been persisted to the monitor and can be applied to our internal
8168+ // state such that the channel resumes operation if no new updates have been
8169+ // made since.
8170+ {
8171+ let per_peer_state = self.per_peer_state.read().unwrap();
8172+ let mut peer_state_lock;
8173+ let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
8174+ if peer_state_mutex_opt.is_none() {
8175+ continue;
8176+ }
8177+ peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
8178+ let peer_state = &mut *peer_state_lock;
8179+ if let btree_map::Entry::Occupied(mut e) =
8180+ peer_state.in_flight_monitor_updates.entry(channel_id)
8181+ {
8182+ let (_, in_flight_updates) = e.get_mut();
8183+ in_flight_updates
8184+ .retain(|update| update.update_id > highest_update_id_completed);
8185+ if in_flight_updates.is_empty() {
8186+ e.remove();
8187+ }
8188+ }
8189+ }
81578190 self.channel_monitor_updated(&channel_id, None, &counterparty_node_id);
81588191 },
81598192 }
@@ -18134,39 +18167,58 @@ impl<
1813418167 ($counterparty_node_id: expr, $chan_in_flight_upds: expr, $monitor: expr,
1813518168 $peer_state: expr, $logger: expr, $channel_info_log: expr
1813618169 ) => { {
18170+ // When all in-flight updates have completed after we were last serialized, we
18171+ // need to remove them. However, we can't guarantee that the next serialization
18172+ // will have happened after processing the
18173+ // `BackgroundEvent::MonitorUpdatesComplete`, so removing them now could lead to the
18174+ // channel never being resumed as the event would not be regenerated after another
18175+ // reload. At the same time, we don't want to resume the channel now because there
18176+ // may be post-update actions to handle. Therefore, we're forced to keep tracking
18177+ // the completed in-flight updates (but only when they have all completed) until we
18178+ // are processing the `BackgroundEvent::MonitorUpdatesComplete`.
1813718179 let mut max_in_flight_update_id = 0;
18138- let starting_len = $chan_in_flight_upds.len();
18139- $chan_in_flight_upds.retain(|upd| upd.update_id > $monitor.get_latest_update_id());
18140- if $chan_in_flight_upds.len() < starting_len {
18180+ let num_updates_completed = $chan_in_flight_upds
18181+ .iter()
18182+ .filter(|update| {
18183+ max_in_flight_update_id = cmp::max(max_in_flight_update_id, update.update_id);
18184+ update.update_id <= $monitor.get_latest_update_id()
18185+ })
18186+ .count();
18187+ if num_updates_completed > 0 {
1814118188 log_debug!(
1814218189 $logger,
1814318190 "{} ChannelMonitorUpdates completed after ChannelManager was last serialized",
18144- starting_len - $chan_in_flight_upds.len()
18191+ num_updates_completed,
1814518192 );
1814618193 }
18194+ let all_updates_completed = num_updates_completed == $chan_in_flight_upds.len();
18195+
1814718196 let funding_txo = $monitor.get_funding_txo();
18148- for update in $chan_in_flight_upds.iter() {
18149- log_debug!($logger, "Replaying ChannelMonitorUpdate {} for {}channel {}",
18150- update.update_id, $channel_info_log, &$monitor.channel_id());
18151- max_in_flight_update_id = cmp::max(max_in_flight_update_id, update.update_id);
18152- pending_background_events.push(
18153- BackgroundEvent::MonitorUpdateRegeneratedOnStartup {
18154- counterparty_node_id: $counterparty_node_id,
18155- funding_txo: funding_txo,
18156- channel_id: $monitor.channel_id(),
18157- update: update.clone(),
18158- });
18159- }
18160- if $chan_in_flight_upds.is_empty() {
18161- // We had some updates to apply, but it turns out they had completed before we
18162- // were serialized, we just weren't notified of that. Thus, we may have to run
18163- // the completion actions for any monitor updates, but otherwise are done.
18197+ if all_updates_completed {
18198+ log_debug!($logger, "All monitor updates completed since the ChannelManager was last serialized");
1816418199 pending_background_events.push(
1816518200 BackgroundEvent::MonitorUpdatesComplete {
1816618201 counterparty_node_id: $counterparty_node_id,
1816718202 channel_id: $monitor.channel_id(),
18203+ highest_update_id_completed: max_in_flight_update_id,
1816818204 });
1816918205 } else {
18206+ $chan_in_flight_upds.retain(|update| {
18207+ let replay = update.update_id > $monitor.get_latest_update_id();
18208+ if replay {
18209+ log_debug!($logger, "Replaying ChannelMonitorUpdate {} for {}channel {}",
18210+ update.update_id, $channel_info_log, &$monitor.channel_id());
18211+ pending_background_events.push(
18212+ BackgroundEvent::MonitorUpdateRegeneratedOnStartup {
18213+ counterparty_node_id: $counterparty_node_id,
18214+ funding_txo: funding_txo,
18215+ channel_id: $monitor.channel_id(),
18216+ update: update.clone(),
18217+ }
18218+ );
18219+ }
18220+ replay
18221+ });
1817018222 $peer_state.closed_channel_monitor_update_ids.entry($monitor.channel_id())
1817118223 .and_modify(|v| *v = cmp::max(max_in_flight_update_id, *v))
1817218224 .or_insert(max_in_flight_update_id);
0 commit comments