diff --git a/src/event.rs b/src/event.rs index 70e02207e..8d475d20e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -358,6 +358,14 @@ where Ok(()) } + /// Check if a PaymentReceived event with the given payment_id already exists in the queue. + pub(crate) fn contains_payment_received(&self, payment_id: &PaymentId) -> bool { + let locked_queue = self.queue.lock().unwrap(); + locked_queue.iter().any(|event| { + matches!(event, Event::PaymentReceived { payment_id: Some(id), .. } if id == payment_id) + }) + } + fn persist_queue(&self, locked_queue: &VecDeque) -> Result<(), Error> { let data = EventQueueSerWrapper(locked_queue).encode(); self.kv_store @@ -938,6 +946,18 @@ where }, } + // Check if a PaymentReceived event for this payment already exists in the queue. + // This handles the case where PaymentClaimed is replayed on restart - we only + // want to queue one PaymentReceived event per payment. + if self.event_queue.contains_payment_received(&payment_id) { + log_debug!( + self.logger, + "Skipping duplicate PaymentReceived for payment {}: event already queued", + payment_id, + ); + return Ok(()); + } + let event = Event::PaymentReceived { payment_id: Some(payment_id), payment_hash,