Skip to content

Commit 85117be

Browse files
Support held_htlc_available counterparty reply path
As part of supporting sending payments as an often-offline sender, the sender needs to send held_htlc_available onion messages such that the reply path to the message terminates at their always-online channel counterparty that is holding the HTLC. That way when the recipient responds with release_held_htlc, the sender's counterparty will receive that message. Here we lay some groundwork for using a counterparty-created reply path when sending held_htlc_available as an async sender in the next commit.
1 parent 99b7dba commit 85117be

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ use crate::ln::outbound_payment::{
9191
};
9292
use crate::ln::types::ChannelId;
9393
use crate::offers::async_receive_offer_cache::AsyncReceiveOfferCache;
94-
use crate::offers::flow::{InvreqResponseInstructions, OffersMessageFlow};
94+
use crate::offers::flow::{HeldHtlcReplyPath, InvreqResponseInstructions, OffersMessageFlow};
9595
use crate::offers::invoice::{
9696
Bolt12Invoice, DerivedSigningPubkey, InvoiceBuilder, DEFAULT_RELATIVE_EXPIRY,
9797
};
@@ -5500,11 +5500,12 @@ where
55005500
);
55015501
}
55025502
} else {
5503-
let enqueue_held_htlc_available_res = self.flow.enqueue_held_htlc_available(
5504-
invoice,
5503+
let reply_path = HeldHtlcReplyPath::ToUs {
55055504
payment_id,
5506-
self.get_peers_for_blinded_path(),
5507-
);
5505+
peers: self.get_peers_for_blinded_path(),
5506+
};
5507+
let enqueue_held_htlc_available_res =
5508+
self.flow.enqueue_held_htlc_available(invoice, reply_path);
55085509
if enqueue_held_htlc_available_res.is_err() {
55095510
self.abandon_payment_with_reason(
55105511
payment_id,

lightning/src/offers/flow.rs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,26 @@ pub enum InvreqResponseInstructions {
423423
},
424424
}
425425

426+
/// Parameters for the reply path to a [`HeldHtlcAvailable`] onion message.
427+
pub enum HeldHtlcReplyPath {
428+
/// The reply path to the [`HeldHtlcAvailable`] message should terminate at our node.
429+
ToUs {
430+
/// The id of the payment.
431+
payment_id: PaymentId,
432+
/// The peers to use when creating this reply path.
433+
peers: Vec<MessageForwardNode>,
434+
},
435+
/// The reply path to the [`HeldHtlcAvailable`] message should terminate at our next-hop channel
436+
/// counterparty, as they are holding our HTLC until they receive the corresponding
437+
/// [`ReleaseHeldHtlc`] message.
438+
///
439+
/// [`ReleaseHeldHtlc`]: crate::onion_message::async_payments::ReleaseHeldHtlc
440+
ToCounterparty {
441+
/// The blinded path provided to us by our counterparty.
442+
path: BlindedMessagePath,
443+
},
444+
}
445+
426446
impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>
427447
where
428448
MR::Target: MessageRouter,
@@ -1159,26 +1179,36 @@ where
11591179
/// Enqueues `held_htlc_available` onion messages to be sent to the payee via the reply paths
11601180
/// contained within the provided [`StaticInvoice`].
11611181
///
1162-
/// # Peers
1163-
///
1164-
/// The user must provide a list of [`MessageForwardNode`] that will be used to generate valid
1165-
/// reply paths for the recipient to send back the corresponding [`ReleaseHeldHtlc`] onion message.
1166-
///
11671182
/// [`ReleaseHeldHtlc`]: crate::onion_message::async_payments::ReleaseHeldHtlc
11681183
/// [`supports_onion_messages`]: crate::types::features::Features::supports_onion_messages
11691184
pub fn enqueue_held_htlc_available(
1170-
&self, invoice: &StaticInvoice, payment_id: PaymentId, peers: Vec<MessageForwardNode>,
1185+
&self, invoice: &StaticInvoice, reply_path_params: HeldHtlcReplyPath,
11711186
) -> Result<(), Bolt12SemanticError> {
1172-
let context =
1173-
MessageContext::AsyncPayments(AsyncPaymentsContext::OutboundPayment { payment_id });
1187+
let reply_path_terminates_at_us =
1188+
matches!(reply_path_params, HeldHtlcReplyPath::ToUs { .. });
11741189

1175-
let reply_paths = self
1176-
.create_blinded_paths(peers, context)
1177-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
1190+
let reply_paths = match reply_path_params {
1191+
HeldHtlcReplyPath::ToUs { payment_id, peers } => {
1192+
let context =
1193+
MessageContext::AsyncPayments(AsyncPaymentsContext::OutboundPayment {
1194+
payment_id,
1195+
});
1196+
self.create_blinded_paths(peers, context)
1197+
.map_err(|_| {
1198+
log_trace!(self.logger, "Failed to create blinded paths when enqueueing held_htlc_available message");
1199+
Bolt12SemanticError::MissingPaths
1200+
})?
1201+
},
1202+
HeldHtlcReplyPath::ToCounterparty { path } => vec![path],
1203+
};
11781204

1205+
log_trace!(
1206+
self.logger,
1207+
"Sending held_htlc_available message for async HTLC, with reply_path terminating at {}",
1208+
if reply_path_terminates_at_us { "our node" } else { "our always-online counterparty" }
1209+
);
11791210
let mut pending_async_payments_messages =
11801211
self.pending_async_payments_messages.lock().unwrap();
1181-
11821212
let message = AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable {});
11831213
enqueue_onion_message_with_reply_paths(
11841214
message,

0 commit comments

Comments
 (0)