Skip to content

Commit b51e5de

Browse files
committed
Deduplicate PaymentReceived events on restart (#5)
PaymentClaimed events can be replayed on every Node startup. Since nodes are pinged at minimum every 30 minutes, this causes duplicate PaymentReceived events to stack up in the queue when the event queue is not being actively processed. These stacked events can cause payouts to fail as they timeout before the queue is drained to the actual events related to a payout. Add a check before queuing PaymentReceived to skip if an event for that payment_id already exists in the queue, preventing duplicates.
1 parent 099dd42 commit b51e5de

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

src/event.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,13 @@ where
417417
})?;
418418
Ok(())
419419
}
420+
421+
fn contains_payment_received(&self, payment_id: &PaymentId) -> bool {
422+
let locked_queue = self.queue.lock().unwrap();
423+
locked_queue.iter().any(|event| {
424+
matches!(event, Event::PaymentReceived { payment_id: Some(id), .. } if id == payment_id)
425+
})
426+
}
420427
}
421428

422429
impl<L: Deref> ReadableArgs<(Arc<DynStore>, L)> for EventQueue<L>
@@ -1010,6 +1017,18 @@ where
10101017
},
10111018
}
10121019

1020+
// Check if a PaymentReceived event for this payment already exists in the queue.
1021+
// This handles the case where PaymentClaimed is replayed on restart - we only
1022+
// want to queue one PaymentReceived event per payment.
1023+
if self.event_queue.contains_payment_received(&payment_id) {
1024+
log_debug!(
1025+
self.logger,
1026+
"Skipping duplicate PaymentReceived for payment {}: event already queued",
1027+
payment_id,
1028+
);
1029+
return Ok(());
1030+
}
1031+
10131032
let event = Event::PaymentReceived {
10141033
payment_id: Some(payment_id),
10151034
payment_hash,

0 commit comments

Comments
 (0)