+ // Used to check for duplicate HTLC resolutions.
+ #[cfg(debug_assertions)]
+ let unmatured_htlcs: Vec<_> = self.onchain_events_waiting_threshold_conf
+ .iter()
+ .filter_map(|entry| match &entry.event {
+ OnchainEvent::HTLCUpdate { htlc_update } => Some(htlc_update.0.clone()),
+ OnchainEvent::MaturingOutput { .. } => None,
+ })
+ .collect();
+ #[cfg(debug_assertions)]
+ let mut matured_htlcs = Vec::new();
+
+ // Produce actionable events from on-chain events having reached their threshold.
+ for entry in onchain_events_reaching_threshold_conf.drain(..) {
+ match entry.event {
+ OnchainEvent::HTLCUpdate { htlc_update } => {
+ // Check for duplicate HTLC resolutions.
+ #[cfg(debug_assertions)]
+ {
+ debug_assert!(
+ unmatured_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none(),
+ "An unmature HTLC transaction conflicts with a maturing one; failed to \
+ call block_disconnected for a block containing the conflicting \
+ transaction.");
+ debug_assert!(
+ matured_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none(),
+ "A matured HTLC transaction conflicts with a maturing one; failed to \
+ call block_disconnected for a block containing the conflicting \
+ transaction.");
+ matured_htlcs.push(htlc_update.0.clone());
+ }
+
+ log_trace!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0));
+ self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
+ payment_hash: htlc_update.1,
+ payment_preimage: None,
+ source: htlc_update.0,
+ }));
+ },
+ OnchainEvent::MaturingOutput { descriptor } => {
+ log_trace!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor));
+ self.pending_events.push(Event::SpendableOutputs {
+ outputs: vec![descriptor]
+ });
+ }
+ }
+ }
+