Skip to content

Commit 96368a0

Browse files
committed
Introduce Payment Dummy Hop parsing mechanism
1 parent a24efed commit 96368a0

File tree

4 files changed

+91
-8
lines changed

4 files changed

+91
-8
lines changed

lightning/src/blinded_path/payment.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,19 @@ impl BlindedPaymentPath {
239239
self.inner_path.blinded_hops.remove(0);
240240
Ok(())
241241
},
242+
Ok((BlindedPaymentTlvs::Dummy, control_tlvs_ss)) => {
243+
let next_node_id = node_signer.get_node_id(Recipient::Node)?;
244+
let mut new_blinding_point = onion_utils::next_hop_pubkey(
245+
secp_ctx,
246+
self.inner_path.blinding_point,
247+
control_tlvs_ss.as_ref(),
248+
)
249+
.map_err(|_| ())?;
250+
mem::swap(&mut self.inner_path.blinding_point, &mut new_blinding_point);
251+
self.inner_path.introduction_node = IntroductionNode::NodeId(next_node_id);
252+
self.inner_path.blinded_hops.remove(0);
253+
Ok(())
254+
},
242255
_ => Err(()),
243256
}
244257
}
@@ -262,9 +275,9 @@ impl BlindedPaymentPath {
262275
.map_err(|_| ())?;
263276

264277
match (&readable, used_aad) {
265-
(BlindedPaymentTlvs::Forward(_), false) | (BlindedPaymentTlvs::Receive(_), true) => {
266-
Ok((readable, control_tlvs_ss))
267-
},
278+
(BlindedPaymentTlvs::Forward(_), false)
279+
| (BlindedPaymentTlvs::Dummy, true)
280+
| (BlindedPaymentTlvs::Receive(_), true) => Ok((readable, control_tlvs_ss)),
268281
_ => Err(()),
269282
}
270283
}

lightning/src/ln/channelmanager.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ use crate::ln::msgs::{
7272
MessageSendEvent,
7373
};
7474
use crate::ln::onion_payment::{
75-
check_incoming_htlc_cltv, create_fwd_pending_htlc_info, create_recv_pending_htlc_info,
76-
decode_incoming_update_add_htlc_onion, invalid_payment_err_data, ForwardInfo, HopConnector,
77-
InboundHTLCErr, NextPacketDetails,
75+
check_incoming_htlc_cltv, create_fwd_pending_htlc_info, create_new_update_add_htlc,
76+
create_recv_pending_htlc_info, decode_incoming_update_add_htlc_onion, invalid_payment_err_data,
77+
ForwardInfo, HopConnector, InboundHTLCErr, NextPacketDetails,
7878
};
7979
use crate::ln::onion_utils::{self};
8080
use crate::ln::onion_utils::{
@@ -6851,6 +6851,7 @@ where
68516851
pub(crate) fn process_pending_update_add_htlcs(&self) -> bool {
68526852
let mut should_persist = false;
68536853
let mut decode_update_add_htlcs = new_hash_map();
6854+
let mut dummy_update_add_htlcs = new_hash_map();
68546855
mem::swap(&mut decode_update_add_htlcs, &mut self.decode_update_add_htlcs.lock().unwrap());
68556856

68566857
let get_htlc_failure_type = |outgoing_scid_opt: Option<u64>, payment_hash: PaymentHash| {
@@ -6914,7 +6915,39 @@ where
69146915
&*self.logger,
69156916
&self.secp_ctx,
69166917
) {
6917-
Ok(decoded_onion) => decoded_onion,
6918+
Ok(decoded_onion) => match decoded_onion {
6919+
(
6920+
onion_utils::Hop::Dummy {
6921+
intro_node_blinding_point,
6922+
next_hop_hmac,
6923+
new_packet_bytes,
6924+
..
6925+
},
6926+
Some(NextPacketDetails { next_packet_pubkey, forward_info }),
6927+
) => {
6928+
debug_assert!(
6929+
forward_info.is_none(),
6930+
"Dummy hops must not contain any forward info, since they are not actually forwarded."
6931+
);
6932+
let new_update_add_htlc = create_new_update_add_htlc(
6933+
update_add_htlc.clone(),
6934+
&*self.node_signer,
6935+
&self.secp_ctx,
6936+
intro_node_blinding_point,
6937+
next_packet_pubkey,
6938+
next_hop_hmac,
6939+
new_packet_bytes,
6940+
);
6941+
6942+
dummy_update_add_htlcs
6943+
.entry(incoming_scid_alias)
6944+
.or_insert_with(Vec::new)
6945+
.push(new_update_add_htlc);
6946+
6947+
continue;
6948+
},
6949+
_ => decoded_onion,
6950+
},
69186951

69196952
Err((htlc_fail, reason)) => {
69206953
let failure_type = HTLCHandlingFailureType::InvalidOnion;
@@ -7071,6 +7104,11 @@ where
70717104
));
70727105
}
70737106
}
7107+
7108+
// Replace the decode queue with the peeled dummy HTLCs so they can be processed in the next iteration.
7109+
let mut decode_update_add_htlc_source = self.decode_update_add_htlcs.lock().unwrap();
7110+
mem::swap(&mut *decode_update_add_htlc_source, &mut dummy_update_add_htlcs);
7111+
70747112
should_persist
70757113
}
70767114

lightning/src/ln/onion_payment.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::ln::channelmanager::{
1515
BlindedFailure, BlindedForward, HTLCFailureMsg, PendingHTLCInfo, PendingHTLCRouting,
1616
CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA,
1717
};
18-
use crate::ln::msgs;
18+
use crate::ln::msgs::{self, OnionPacket, UpdateAddHTLC};
1919
use crate::ln::onion_utils;
2020
use crate::ln::onion_utils::{HTLCFailReason, LocalHTLCFailureReason, ONION_DATA_LEN};
2121
use crate::sign::{NodeSigner, Recipient};
@@ -651,6 +651,32 @@ where
651651
Ok((next_hop, next_packet_details))
652652
}
653653

654+
pub(super) fn create_new_update_add_htlc<NS: Deref, T: secp256k1::Verification>(
655+
msg: msgs::UpdateAddHTLC, node_signer: NS, secp_ctx: &Secp256k1<T>,
656+
intro_node_blinding_point: Option<PublicKey>,
657+
new_packet_pubkey: Result<PublicKey, secp256k1::Error>, next_hop_hmac: [u8; 32],
658+
new_packet_bytes: [u8; 1300],
659+
) -> UpdateAddHTLC
660+
where
661+
NS::Target: NodeSigner,
662+
{
663+
let new_packet = OnionPacket {
664+
version: 0,
665+
public_key: new_packet_pubkey,
666+
hop_data: new_packet_bytes,
667+
hmac: next_hop_hmac,
668+
};
669+
670+
let next_blinding_point =
671+
intro_node_blinding_point.or(msg.blinding_point).and_then(|blinding_point| {
672+
let encrypted_tlvs_ss =
673+
node_signer.ecdh(Recipient::Node, &blinding_point, None).unwrap().secret_bytes();
674+
onion_utils::next_hop_pubkey(&secp_ctx, blinding_point, &encrypted_tlvs_ss).ok()
675+
});
676+
677+
UpdateAddHTLC { onion_routing_packet: new_packet, blinding_point: next_blinding_point, ..msg }
678+
}
679+
654680
pub(super) fn check_incoming_htlc_cltv(
655681
cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32,
656682
) -> Result<(), LocalHTLCFailureReason> {

lightning/src/ln/onion_utils.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,12 @@ where
23352335
new_packet_bytes,
23362336
})
23372337
},
2338+
msgs::InboundOnionPayload::Dummy { intro_node_blinding_point } => Ok(Hop::Dummy {
2339+
intro_node_blinding_point,
2340+
shared_secret,
2341+
next_hop_hmac,
2342+
new_packet_bytes,
2343+
}),
23382344
_ => {
23392345
if blinding_point.is_some() {
23402346
return Err(OnionDecodeErr::Malformed {

0 commit comments

Comments
 (0)