@@ -2558,6 +2558,8 @@ pub struct ChannelManager<
2558
2558
/// See `ChannelManager` struct-level documentation for lock order requirements.
2559
2559
pending_intercepted_htlcs: Mutex<HashMap<InterceptId, PendingAddHTLCInfo>>,
2560
2560
2561
+ pending_held_htlcs: Mutex<HashMap<(u64, u64), PendingAddHTLCInfo>>,
2562
+
2561
2563
/// SCID/SCID Alias -> pending `update_add_htlc`s to decode.
2562
2564
///
2563
2565
/// Note that because we may have an SCID Alias as the key we can have two entries per channel,
@@ -6050,6 +6052,40 @@ where
6050
6052
Ok(())
6051
6053
}
6052
6054
6055
+ fn forward_held_htlc(&self, short_channel_id: u64, htlc_id: u64) -> Result<(), APIError> {
6056
+ let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
6057
+
6058
+ let held_htlc_id = (short_channel_id, htlc_id);
6059
+ let mut htlc =
6060
+ self.pending_held_htlcs.lock().unwrap().remove(&held_htlc_id).ok_or_else(|| {
6061
+ APIError::APIMisuseError {
6062
+ err: format!("Held htlc {}:{} not found", short_channel_id, htlc_id),
6063
+ }
6064
+ })?;
6065
+
6066
+ if let PendingHTLCRouting::Forward { ref mut hold_htlc, .. } = htlc.forward_info.routing {
6067
+ // Clear hold flag.
6068
+ *hold_htlc = false;
6069
+ } else {
6070
+ return Err(APIError::APIMisuseError {
6071
+ err: "Only PendingHTLCRouting::Forward HTLCs can be held".to_owned(),
6072
+ });
6073
+ }
6074
+
6075
+ let mut per_source_pending_forward = [(
6076
+ htlc.prev_short_channel_id,
6077
+ htlc.prev_counterparty_node_id,
6078
+ htlc.prev_funding_outpoint,
6079
+ htlc.prev_channel_id,
6080
+ htlc.prev_user_channel_id,
6081
+ vec![(htlc.forward_info, htlc.prev_htlc_id)],
6082
+ )];
6083
+
6084
+ // Re-forward this time without the hold flag.
6085
+ self.forward_htlcs(&mut per_source_pending_forward);
6086
+ Ok(())
6087
+ }
6088
+
6053
6089
/// Fails the intercepted HTLC indicated by intercept_id. Should only be called in response to
6054
6090
/// an [`HTLCIntercepted`] event. See [`ChannelManager::forward_intercepted_htlc`].
6055
6091
///
@@ -10278,6 +10314,13 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
10278
10314
let mut failed_intercept_forwards = Vec::new();
10279
10315
if !pending_forwards.is_empty() {
10280
10316
for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
10317
+ if let PendingHTLCRouting::Forward { hold_htlc: true, .. } =
10318
+ forward_info.routing
10319
+ {
10320
+ let mut held_htlcs = self.pending_held_htlcs.lock().unwrap();
10321
+ held_htlcs.entry((prev_short_channel_id, prev_htlc_id));
10322
+ }
10323
+
10281
10324
let scid = match forward_info.routing {
10282
10325
PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id,
10283
10326
PendingHTLCRouting::TrampolineForward { .. } => 0,
0 commit comments