@@ -3509,6 +3509,7 @@ macro_rules! emit_initial_channel_ready_event {
3509
3509
macro_rules! handle_monitor_update_completion {
3510
3510
($self: ident, $peer_state_lock: expr, $peer_state: expr, $per_peer_state_lock: expr, $chan: expr) => { {
3511
3511
let channel_id = $chan.context.channel_id();
3512
+ let outbound_scid_alias = $chan.context().outbound_scid_alias();
3512
3513
let counterparty_node_id = $chan.context.get_counterparty_node_id();
3513
3514
#[cfg(debug_assertions)]
3514
3515
{
@@ -3521,7 +3522,7 @@ macro_rules! handle_monitor_update_completion {
3521
3522
let mut updates = $chan.monitor_updating_restored(&&logger,
3522
3523
&$self.node_signer, $self.chain_hash, &*$self.config.read().unwrap(),
3523
3524
$self.best_block.read().unwrap().height,
3524
- |htlc_id| $self.path_for_release_held_htlc(htlc_id, &channel_id, &counterparty_node_id));
3525
+ |htlc_id| $self.path_for_release_held_htlc(htlc_id, outbound_scid_alias, &channel_id, &counterparty_node_id));
3525
3526
let channel_update = if updates.channel_ready.is_some()
3526
3527
&& $chan.context.is_usable()
3527
3528
&& $peer_state.is_connected
@@ -5623,11 +5624,17 @@ where
5623
5624
/// [`HeldHtlcAvailable`] onion message, so the recipient's [`ReleaseHeldHtlc`] response will be
5624
5625
/// received to our node.
5625
5626
fn path_for_release_held_htlc(
5626
- &self, htlc_id: u64, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
5627
+ &self, htlc_id: u64, prev_outbound_scid_alias: u64, channel_id: &ChannelId,
5628
+ counterparty_node_id: &PublicKey,
5627
5629
) -> BlindedMessagePath {
5628
5630
let intercept_id =
5629
5631
InterceptId::from_htlc_id_and_chan_id(htlc_id, channel_id, counterparty_node_id);
5630
- self.flow.path_for_release_held_htlc(intercept_id, &*self.entropy_source)
5632
+ self.flow.path_for_release_held_htlc(
5633
+ intercept_id,
5634
+ prev_outbound_scid_alias,
5635
+ htlc_id,
5636
+ &*self.entropy_source,
5637
+ )
5631
5638
}
5632
5639
5633
5640
/// Signals that no further attempts for the given payment should occur. Useful if you have a
@@ -11302,14 +11309,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
11302
11309
// disconnect, so Channel's reestablish will never hand us any holding cell
11303
11310
// freed HTLCs to fail backwards. If in the future we no longer drop pending
11304
11311
// add-HTLCs on disconnect, we may be handed HTLCs to fail backwards here.
11312
+ let outbound_scid_alias = chan.context.outbound_scid_alias();
11305
11313
let res = chan.channel_reestablish(
11306
11314
msg,
11307
11315
&&logger,
11308
11316
&self.node_signer,
11309
11317
self.chain_hash,
11310
11318
&self.config.read().unwrap(),
11311
11319
&*self.best_block.read().unwrap(),
11312
- |htlc_id| self.path_for_release_held_htlc(htlc_id, &msg.channel_id, counterparty_node_id)
11320
+ |htlc_id| self.path_for_release_held_htlc(htlc_id, outbound_scid_alias, &msg.channel_id, counterparty_node_id)
11313
11321
);
11314
11322
let responses = try_channel_entry!(self, peer_state, res, chan_entry);
11315
11323
let mut channel_update = None;
@@ -11786,11 +11794,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
11786
11794
// Returns whether we should remove this channel as it's just been closed.
11787
11795
let unblock_chan = |chan: &mut Channel<SP>, pending_msg_events: &mut Vec<MessageSendEvent>| -> Option<ShutdownResult> {
11788
11796
let channel_id = chan.context().channel_id();
11797
+ let outbound_scid_alias = chan.context().outbound_scid_alias();
11789
11798
let logger = WithChannelContext::from(&self.logger, &chan.context(), None);
11790
11799
let node_id = chan.context().get_counterparty_node_id();
11791
11800
if let Some(msgs) = chan.signer_maybe_unblocked(
11792
11801
self.chain_hash, &&logger,
11793
- |htlc_id| self.path_for_release_held_htlc(htlc_id, &channel_id, &node_id)
11802
+ |htlc_id| self.path_for_release_held_htlc(htlc_id, outbound_scid_alias, &channel_id, &node_id)
11794
11803
) {
11795
11804
if chan.context().is_connected() {
11796
11805
if let Some(msg) = msgs.open_channel {
@@ -15029,7 +15038,34 @@ where
15029
15038
);
15030
15039
}
15031
15040
},
15032
- AsyncPaymentsContext::ReleaseHeldHtlc { intercept_id } => {
15041
+ AsyncPaymentsContext::ReleaseHeldHtlc {
15042
+ intercept_id,
15043
+ prev_outbound_scid_alias,
15044
+ htlc_id,
15045
+ } => {
15046
+ // It's possible the release_held_htlc message raced ahead of us transitioning the pending
15047
+ // update_add to `Self::pending_intercept_htlcs`. If that's the case, update the pending
15048
+ // update_add to indicate that the HTLC should be released immediately.
15049
+ //
15050
+ // Check for the HTLC here before checking `pending_intercept_htlcs` to avoid a different
15051
+ // race where the HTLC gets transitioned to `pending_intercept_htlcs` after we drop that
15052
+ // map's lock but before acquiring the `decode_update_add_htlcs` lock.
15053
+ let mut decode_update_add_htlcs = self.decode_update_add_htlcs.lock().unwrap();
15054
+ if let Some(htlcs) = decode_update_add_htlcs.get_mut(&prev_outbound_scid_alias) {
15055
+ for update_add in htlcs.iter_mut() {
15056
+ if update_add.htlc_id == htlc_id {
15057
+ log_trace!(
15058
+ self.logger,
15059
+ "Marking held htlc with intercept_id {} as ready to release",
15060
+ intercept_id
15061
+ );
15062
+ update_add.hold_htlc.take();
15063
+ return;
15064
+ }
15065
+ }
15066
+ }
15067
+ core::mem::drop(decode_update_add_htlcs);
15068
+
15033
15069
let mut htlc = {
15034
15070
let mut pending_intercept_htlcs =
15035
15071
self.pending_intercepted_htlcs.lock().unwrap();
0 commit comments