Skip to content

Commit 1a59e68

Browse files
Support creating reply_path for HeldHtlcAvailable
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 add a method for creating said reply path, which will be used in the next commit.
1 parent 2c5c2df commit 1a59e68

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

lightning/src/blinded_path/message.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::blinded_path::{BlindedHop, BlindedPath, Direction, IntroductionNode,
1919
use crate::crypto::streams::ChaChaPolyReadAdapter;
2020
use crate::io;
2121
use crate::io::Cursor;
22-
use crate::ln::channelmanager::PaymentId;
22+
use crate::ln::channelmanager::{InterceptId, PaymentId};
2323
use crate::ln::msgs::DecodeError;
2424
use crate::ln::onion_utils;
2525
use crate::offers::nonce::Nonce;
@@ -561,7 +561,7 @@ pub enum AsyncPaymentsContext {
561561
},
562562
/// Context contained within the reply [`BlindedMessagePath`] we put in outbound
563563
/// [`HeldHtlcAvailable`] messages, provided back to us in corresponding [`ReleaseHeldHtlc`]
564-
/// messages.
564+
/// messages if we are an always-online sender paying an async recipient.
565565
///
566566
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
567567
/// [`ReleaseHeldHtlc`]: crate::onion_message::async_payments::ReleaseHeldHtlc
@@ -582,6 +582,17 @@ pub enum AsyncPaymentsContext {
582582
/// able to trivially ask if we're online forever.
583583
path_absolute_expiry: core::time::Duration,
584584
},
585+
/// Context contained within the reply [`BlindedMessagePath`] put in outbound
586+
/// [`HeldHtlcAvailable`] messages, provided back to the async sender's always-online counterparty
587+
/// in corresponding [`ReleaseHeldHtlc`] messages.
588+
///
589+
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
590+
/// [`ReleaseHeldHtlc`]: crate::onion_message::async_payments::ReleaseHeldHtlc
591+
ReleaseHeldHtlc {
592+
/// An identifier for the HTLC that should be released by us as the sender's always-online
593+
/// channel counterparty to the often-offline recipient.
594+
intercept_id: InterceptId,
595+
},
585596
}
586597

587598
impl_writeable_tlv_based_enum!(MessageContext,
@@ -637,6 +648,9 @@ impl_writeable_tlv_based_enum!(AsyncPaymentsContext,
637648
(2, invoice_slot, required),
638649
(4, path_absolute_expiry, required),
639650
},
651+
(6, ReleaseHeldHtlc) => {
652+
(0, intercept_id, required),
653+
},
640654
);
641655

642656
/// Contains a simple nonce for use in a blinded path's context.

lightning/src/ln/channelmanager.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5440,6 +5440,17 @@ where
54405440
res
54415441
}
54425442

5443+
/// If we are holding an HTLC on behalf of an often-offline sender, this method allows us to
5444+
/// create a path for the sender to use as the reply path when they send the recipient a
5445+
/// [`HeldHtlcAvailable`] onion message, so the recipient's [`ReleaseHeldHtlc`] response will be
5446+
/// received to our node.
5447+
fn path_for_release_held_htlc(
5448+
&self, scid: u64, htlc_id: u64,
5449+
) -> Result<BlindedMessagePath, ()> {
5450+
let intercept_id = InterceptId::from_scid_and_htlc_id(scid, htlc_id);
5451+
self.flow.path_for_release_held_htlc(intercept_id)
5452+
}
5453+
54435454
/// Signals that no further attempts for the given payment should occur. Useful if you have a
54445455
/// pending outbound payment with retries remaining, but wish to stop retrying the payment before
54455456
/// retries are exhausted.

lightning/src/offers/flow.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::prelude::*;
3232

3333
use crate::chain::BestBlock;
3434
use crate::ln::channel_state::ChannelDetails;
35-
use crate::ln::channelmanager::{PaymentId, CLTV_FAR_FAR_AWAY};
35+
use crate::ln::channelmanager::{InterceptId, PaymentId, CLTV_FAR_FAR_AWAY};
3636
use crate::ln::inbound_payment;
3737
use crate::offers::async_receive_offer_cache::AsyncReceiveOfferCache;
3838
use crate::offers::invoice::{
@@ -1157,6 +1157,21 @@ where
11571157
Ok(())
11581158
}
11591159

1160+
/// If we are holding an HTLC on behalf of an often-offline sender, this method allows us to
1161+
/// create a path for the sender to use as the reply path when they send the recipient a
1162+
/// [`HeldHtlcAvailable`] onion message, so the recipient's [`ReleaseHeldHtlc`] response will be
1163+
/// received to our node.
1164+
pub fn path_for_release_held_htlc(
1165+
&self, intercept_id: InterceptId,
1166+
) -> Result<BlindedMessagePath, ()> {
1167+
// TODO: don't error in this method because it doesn't get handled? Instead fall back to
1168+
// returning a 1-hop blinded path?
1169+
let peers = self.peers_cache.lock().unwrap().iter().map(|(peer, _)| *peer).collect();
1170+
let context =
1171+
MessageContext::AsyncPayments(AsyncPaymentsContext::ReleaseHeldHtlc { intercept_id });
1172+
self.create_blinded_paths(peers, context)?.pop().ok_or(())
1173+
}
1174+
11601175
/// Enqueues the created [`DNSSECQuery`] to be sent to the counterparty.
11611176
///
11621177
/// # Peers

0 commit comments

Comments
 (0)