@@ -10365,11 +10365,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1036510365 // During startup, we push monitor updates as background events through to here in
1036610366 // order to replay updates that were in-flight when we shut down. Thus, we have to
1036710367 // filter for uniqueness here.
10368- let update_idx =
10369- in_flight_updates.iter().position(|upd| upd == &new_update).unwrap_or_else(|| {
10370- in_flight_updates.push(new_update);
10371- in_flight_updates.len() - 1
10372- });
10368+ let existing_idx = in_flight_updates.iter().position(|upd| upd == &new_update);
10369+ let is_replay = existing_idx.is_some();
10370+ let update_idx = existing_idx.unwrap_or_else(|| {
10371+ in_flight_updates.push(new_update);
10372+ in_flight_updates.len() - 1
10373+ });
1037310374
1037410375 if self.background_events_processed_since_startup.load(Ordering::Acquire) {
1037510376 let update_res =
@@ -10382,11 +10383,18 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1038210383 }
1038310384 // A Watch implementation must not return Completed while prior updates are
1038410385 // still InProgress, as this would violate the async persistence contract.
10386+ // We skip this check for replayed updates (startup background events)
10387+ // because during startup replay, the remaining in-flight updates may not
10388+ // have been submitted to the Watch yet and will be processed by subsequent
10389+ // background events. This is specifically necessary when switching from
10390+ // async to sync persistence across a restart: the replayed update
10391+ // returns Completed from the now-sync Watch while earlier in-flight
10392+ // updates are still queued as background events.
1038510393 #[cfg(test)]
1038610394 let skip_check = self.skip_monitor_update_assertion.load(Ordering::Relaxed);
1038710395 #[cfg(not(test))]
1038810396 let skip_check = false;
10389- if !skip_check && update_completed && !in_flight_updates.is_empty() {
10397+ if !skip_check && !is_replay && update_completed && !in_flight_updates.is_empty() {
1039010398 panic!("Watch::update_channel returned Completed while prior updates are still InProgress");
1039110399 }
1039210400 (update_completed, update_completed && in_flight_updates.is_empty())
0 commit comments