Skip to content

Commit 6f1184f

Browse files
Include release_held_htlc blinded paths in RAA
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 the counterparty starts including said reply paths in the revoke_and_ack message destined for the sender, so the sender can use these paths in subsequent held_htlc_available messages. We put the paths in the RAA to ensure the sender receives the blinded paths, because failure to deliver the paths means the HTLC will timeout/fail.
1 parent 1a59e68 commit 6f1184f

File tree

2 files changed

+75
-19
lines changed

2 files changed

+75
-19
lines changed

lightning/src/ln/channel.rs

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use bitcoin::{secp256k1, sighash, TxIn};
2828
#[cfg(splicing)]
2929
use bitcoin::{FeeRate, Sequence};
3030

31+
use crate::blinded_path::message::BlindedMessagePath;
3132
use crate::chain::chaininterface::{
3233
fee_for_weight, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator,
3334
};
@@ -282,6 +283,29 @@ impl InboundHTLCState {
282283
_ => None,
283284
}
284285
}
286+
287+
/// Whether we need to hold onto this HTLC until receipt of a corresponding [`ReleaseHeldHtlc`]
288+
/// onion message.
289+
///
290+
///[`ReleaseHeldHtlc`]: crate::onion_message::async_payments::ReleaseHeldHtlc
291+
fn should_hold_htlc(&self) -> bool {
292+
match self {
293+
InboundHTLCState::RemoteAnnounced(res)
294+
| InboundHTLCState::AwaitingRemoteRevokeToAnnounce(res)
295+
| InboundHTLCState::AwaitingAnnouncedRemoteRevoke(res) => match res {
296+
InboundHTLCResolution::Resolved { pending_htlc_status } => {
297+
match pending_htlc_status {
298+
PendingHTLCStatus::Forward(info) => info.routing.should_hold_htlc(),
299+
_ => false,
300+
}
301+
},
302+
InboundHTLCResolution::Pending { update_add_htlc } => {
303+
update_add_htlc.hold_htlc.is_some()
304+
},
305+
},
306+
InboundHTLCState::Committed | InboundHTLCState::LocalRemoved(_) => false,
307+
}
308+
}
285309
}
286310

287311
struct InboundHTLCOutput {
@@ -1602,12 +1626,12 @@ where
16021626
}
16031627

16041628
#[rustfmt::skip]
1605-
pub fn signer_maybe_unblocked<L: Deref>(
1606-
&mut self, chain_hash: ChainHash, logger: &L,
1607-
) -> Option<SignerResumeUpdates> where L::Target: Logger {
1629+
pub fn signer_maybe_unblocked<L: Deref, CBP>(
1630+
&mut self, chain_hash: ChainHash, logger: &L, path_for_release_htlc: CBP
1631+
) -> Option<SignerResumeUpdates> where L::Target: Logger, CBP: Fn(u64, u64) -> Result<BlindedMessagePath, ()> {
16081632
match &mut self.phase {
16091633
ChannelPhase::Undefined => unreachable!(),
1610-
ChannelPhase::Funded(chan) => Some(chan.signer_maybe_unblocked(logger)),
1634+
ChannelPhase::Funded(chan) => Some(chan.signer_maybe_unblocked(logger, path_for_release_htlc)),
16111635
ChannelPhase::UnfundedOutboundV1(chan) => {
16121636
let (open_channel, funding_created) = chan.signer_maybe_unblocked(chain_hash, logger);
16131637
Some(SignerResumeUpdates {
@@ -8707,13 +8731,14 @@ where
87078731
/// successfully and we should restore normal operation. Returns messages which should be sent
87088732
/// to the remote side.
87098733
#[rustfmt::skip]
8710-
pub fn monitor_updating_restored<L: Deref, NS: Deref>(
8734+
pub fn monitor_updating_restored<L: Deref, NS: Deref, CBP>(
87118735
&mut self, logger: &L, node_signer: &NS, chain_hash: ChainHash,
8712-
user_config: &UserConfig, best_block_height: u32
8736+
user_config: &UserConfig, best_block_height: u32, path_for_release_htlc: CBP
87138737
) -> MonitorRestoreUpdates
87148738
where
87158739
L::Target: Logger,
8716-
NS::Target: NodeSigner
8740+
NS::Target: NodeSigner,
8741+
CBP: Fn(u64, u64) -> Result<BlindedMessagePath, ()>
87178742
{
87188743
assert!(self.context.channel_state.is_monitor_update_in_progress());
87198744
self.context.channel_state.clear_monitor_update_in_progress();
@@ -8770,7 +8795,7 @@ where
87708795
}
87718796

87728797
let mut raa = if self.context.monitor_pending_revoke_and_ack {
8773-
self.get_last_revoke_and_ack(logger)
8798+
self.get_last_revoke_and_ack(path_for_release_htlc, logger)
87748799
} else { None };
87758800
let mut commitment_update = if self.context.monitor_pending_commitment_signed {
87768801
self.get_last_commitment_update_for_send(logger).ok()
@@ -8859,7 +8884,9 @@ where
88598884
/// Indicates that the signer may have some signatures for us, so we should retry if we're
88608885
/// blocked.
88618886
#[rustfmt::skip]
8862-
pub fn signer_maybe_unblocked<L: Deref>(&mut self, logger: &L) -> SignerResumeUpdates where L::Target: Logger {
8887+
pub fn signer_maybe_unblocked<L: Deref, CBP>(
8888+
&mut self, logger: &L, path_for_release_htlc: CBP
8889+
) -> SignerResumeUpdates where L::Target: Logger, CBP: Fn(u64, u64) -> Result<BlindedMessagePath, ()> {
88638890
if !self.holder_commitment_point.can_advance() {
88648891
log_trace!(logger, "Attempting to update holder per-commitment point...");
88658892
self.holder_commitment_point.try_resolve_pending(&self.context.holder_signer, &self.context.secp_ctx, logger);
@@ -8887,7 +8914,7 @@ where
88878914
} else { None };
88888915
let mut revoke_and_ack = if self.context.signer_pending_revoke_and_ack {
88898916
log_trace!(logger, "Attempting to generate pending revoke and ack...");
8890-
self.get_last_revoke_and_ack(logger)
8917+
self.get_last_revoke_and_ack(path_for_release_htlc, logger)
88918918
} else { None };
88928919

88938920
if self.context.resend_order == RAACommitmentOrder::CommitmentFirst
@@ -8958,9 +8985,12 @@ where
89588985
}
89598986
}
89608987

8961-
fn get_last_revoke_and_ack<L: Deref>(&mut self, logger: &L) -> Option<msgs::RevokeAndACK>
8988+
fn get_last_revoke_and_ack<CBP, L: Deref>(
8989+
&mut self, path_for_release_htlc: CBP, logger: &L,
8990+
) -> Option<msgs::RevokeAndACK>
89628991
where
89638992
L::Target: Logger,
8993+
CBP: Fn(u64, u64) -> Result<BlindedMessagePath, ()>,
89648994
{
89658995
debug_assert!(
89668996
self.holder_commitment_point.next_transaction_number() <= INITIAL_COMMITMENT_NUMBER - 2
@@ -8973,14 +9003,32 @@ where
89739003
.ok();
89749004
if let Some(per_commitment_secret) = per_commitment_secret {
89759005
if self.holder_commitment_point.can_advance() {
9006+
let mut release_htlc_message_paths = Vec::new();
9007+
for htlc in &self.context.pending_inbound_htlcs {
9008+
// TODO: how to handle the errors here
9009+
let held_htlc = htlc.state.should_hold_htlc();
9010+
if held_htlc {
9011+
let scid = match self.funding.short_channel_id {
9012+
Some(scid) => scid,
9013+
None => {
9014+
continue;
9015+
},
9016+
};
9017+
match path_for_release_htlc(scid, htlc.htlc_id) {
9018+
Ok(path) => release_htlc_message_paths.push((htlc.htlc_id, path)),
9019+
Err(()) => continue,
9020+
}
9021+
}
9022+
}
9023+
89769024
self.context.signer_pending_revoke_and_ack = false;
89779025
return Some(msgs::RevokeAndACK {
89789026
channel_id: self.context.channel_id,
89799027
per_commitment_secret,
89809028
next_per_commitment_point: self.holder_commitment_point.next_point(),
89819029
#[cfg(taproot)]
89829030
next_local_nonce: None,
8983-
release_htlc_message_paths: Vec::new(),
9031+
release_htlc_message_paths,
89849032
});
89859033
}
89869034
}
@@ -9128,13 +9176,15 @@ where
91289176
/// May panic if some calls other than message-handling calls (which will all Err immediately)
91299177
/// have been called between remove_uncommitted_htlcs_and_mark_paused and this call.
91309178
#[rustfmt::skip]
9131-
pub fn channel_reestablish<L: Deref, NS: Deref>(
9179+
pub fn channel_reestablish<L: Deref, NS: Deref, CBP>(
91329180
&mut self, msg: &msgs::ChannelReestablish, logger: &L, node_signer: &NS,
9133-
chain_hash: ChainHash, user_config: &UserConfig, best_block: &BestBlock
9181+
chain_hash: ChainHash, user_config: &UserConfig, best_block: &BestBlock,
9182+
path_for_release_htlc: CBP,
91349183
) -> Result<ReestablishResponses, ChannelError>
91359184
where
91369185
L::Target: Logger,
9137-
NS::Target: NodeSigner
9186+
NS::Target: NodeSigner,
9187+
CBP: Fn(u64, u64) -> Result<BlindedMessagePath, ()>
91389188
{
91399189
if !self.context.channel_state.is_peer_disconnected() {
91409190
// While BOLT 2 doesn't indicate explicitly we should error this channel here, it
@@ -9235,7 +9285,7 @@ where
92359285
self.context.monitor_pending_revoke_and_ack = true;
92369286
None
92379287
} else {
9238-
self.get_last_revoke_and_ack(logger)
9288+
self.get_last_revoke_and_ack(path_for_release_htlc, logger)
92399289
}
92409290
} else {
92419291
debug_assert!(false, "All values should have been handled in the four cases above");
@@ -16433,6 +16483,7 @@ mod tests {
1643316483
chain_hash,
1643416484
&config,
1643516485
0,
16486+
|_, _| Err(())
1643616487
);
1643716488

1643816489
// Receive funding_signed, but the channel will be configured to hold sending channel_ready and
@@ -16447,6 +16498,7 @@ mod tests {
1644716498
chain_hash,
1644816499
&config,
1644916500
0,
16501+
|_, _| Err(())
1645016502
);
1645116503
// Our channel_ready shouldn't be sent yet, even with trust_own_funding_0conf set,
1645216504
// as the funding transaction depends on all channels in the batch becoming ready.

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ impl PendingHTLCRouting {
377377

378378
/// Whether this HTLC should be held by our node until we receive a corresponding
379379
/// [`ReleaseHeldHtlc`] onion message.
380-
fn should_hold_htlc(&self) -> bool {
380+
pub(super) fn should_hold_htlc(&self) -> bool {
381381
match self {
382382
Self::Forward { hold_htlc: Some(()), .. } => true,
383383
_ => false,
@@ -3430,7 +3430,8 @@ macro_rules! handle_monitor_update_completion {
34303430
let logger = WithChannelContext::from(&$self.logger, &$chan.context, None);
34313431
let mut updates = $chan.monitor_updating_restored(&&logger,
34323432
&$self.node_signer, $self.chain_hash, &*$self.config.read().unwrap(),
3433-
$self.best_block.read().unwrap().height);
3433+
$self.best_block.read().unwrap().height,
3434+
|scid, htlc_id| $self.path_for_release_held_htlc(scid, htlc_id));
34343435
let counterparty_node_id = $chan.context.get_counterparty_node_id();
34353436
let channel_update = if updates.channel_ready.is_some() && $chan.context.is_usable() {
34363437
// We only send a channel_update in the case where we are just now sending a
@@ -11102,6 +11103,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1110211103
self.chain_hash,
1110311104
&self.config.read().unwrap(),
1110411105
&*self.best_block.read().unwrap(),
11106+
|scid, htlc_id| self.path_for_release_held_htlc(scid, htlc_id)
1110511107
);
1110611108
let responses = try_channel_entry!(self, peer_state, res, chan_entry);
1110711109
let mut channel_update = None;
@@ -11567,7 +11569,9 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1156711569
let unblock_chan = |chan: &mut Channel<SP>, pending_msg_events: &mut Vec<MessageSendEvent>| -> Option<ShutdownResult> {
1156811570
let logger = WithChannelContext::from(&self.logger, &chan.context(), None);
1156911571
let node_id = chan.context().get_counterparty_node_id();
11570-
if let Some(msgs) = chan.signer_maybe_unblocked(self.chain_hash, &&logger) {
11572+
if let Some(msgs) = chan.signer_maybe_unblocked(
11573+
self.chain_hash, &&logger, |scid, htlc_id| self.path_for_release_held_htlc(scid, htlc_id)
11574+
) {
1157111575
if let Some(msg) = msgs.open_channel {
1157211576
pending_msg_events.push(MessageSendEvent::SendOpenChannel {
1157311577
node_id,

0 commit comments

Comments
 (0)