Skip to content

Commit 5970132

Browse files
committed
Introduce Payment Dummy Hop parsing mechanism
1 parent 7defb72 commit 5970132

File tree

3 files changed

+102
-28
lines changed

3 files changed

+102
-28
lines changed

lightning/src/blinded_path/payment.rs

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use crate::util::ser::{
3434
Writeable, Writer,
3535
};
3636

37-
use core::mem;
3837
use core::ops::Deref;
3938

4039
#[allow(unused_imports)]
@@ -219,28 +218,31 @@ impl BlindedPaymentPath {
219218
NL::Target: NodeIdLookUp,
220219
T: secp256k1::Signing + secp256k1::Verification,
221220
{
222-
match self.decrypt_intro_payload::<NS>(node_signer) {
223-
Ok((
224-
BlindedPaymentTlvs::Forward(ForwardTlvs { short_channel_id, .. }),
225-
control_tlvs_ss,
226-
)) => {
227-
let next_node_id = match node_id_lookup.next_node_id(short_channel_id) {
228-
Some(node_id) => node_id,
229-
None => return Err(()),
230-
};
231-
let mut new_blinding_point = onion_utils::next_hop_pubkey(
232-
secp_ctx,
233-
self.inner_path.blinding_point,
234-
control_tlvs_ss.as_ref(),
235-
)
236-
.map_err(|_| ())?;
237-
mem::swap(&mut self.inner_path.blinding_point, &mut new_blinding_point);
238-
self.inner_path.introduction_node = IntroductionNode::NodeId(next_node_id);
239-
self.inner_path.blinded_hops.remove(0);
240-
Ok(())
241-
},
242-
_ => Err(()),
243-
}
221+
let (next_node_id, control_tlvs_ss) =
222+
match self.decrypt_intro_payload::<NS>(node_signer).map_err(|_| ())? {
223+
(BlindedPaymentTlvs::Forward(ForwardTlvs { short_channel_id, .. }), ss) => {
224+
let node_id = node_id_lookup.next_node_id(short_channel_id).ok_or(())?;
225+
(node_id, ss)
226+
},
227+
(BlindedPaymentTlvs::Dummy, ss) => {
228+
let node_id = node_signer.get_node_id(Recipient::Node)?;
229+
(node_id, ss)
230+
},
231+
_ => return Err(()),
232+
};
233+
234+
let new_blinding_point = onion_utils::next_hop_pubkey(
235+
secp_ctx,
236+
self.inner_path.blinding_point,
237+
control_tlvs_ss.as_ref(),
238+
)
239+
.map_err(|_| ())?;
240+
241+
self.inner_path.blinding_point = new_blinding_point;
242+
self.inner_path.introduction_node = IntroductionNode::NodeId(next_node_id);
243+
self.inner_path.blinded_hops.remove(0);
244+
245+
Ok(())
244246
}
245247

246248
pub(crate) fn decrypt_intro_payload<NS: Deref>(
@@ -262,9 +264,9 @@ impl BlindedPaymentPath {
262264
.map_err(|_| ())?;
263265

264266
match (&readable, used_aad) {
265-
(BlindedPaymentTlvs::Forward(_), false) | (BlindedPaymentTlvs::Receive(_), true) => {
266-
Ok((readable, control_tlvs_ss))
267-
},
267+
(BlindedPaymentTlvs::Forward(_), false)
268+
| (BlindedPaymentTlvs::Dummy, true)
269+
| (BlindedPaymentTlvs::Receive(_), true) => Ok((readable, control_tlvs_ss)),
268270
_ => Err(()),
269271
}
270272
}

lightning/src/ln/channelmanager.rs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use crate::ln::channel_state::ChannelDetails;
6666
use crate::ln::funding::SpliceContribution;
6767
use crate::ln::inbound_payment;
6868
use crate::ln::interactivetxs::InteractiveTxMessageSend;
69-
use crate::ln::msgs;
69+
use crate::ln::msgs::{self, OnionPacket, UpdateAddHTLC};
7070
use crate::ln::msgs::{
7171
BaseMessageHandler, ChannelMessageHandler, CommitmentUpdate, DecodeError, LightningError,
7272
MessageSendEvent,
@@ -6857,6 +6857,7 @@ where
68576857
pub(crate) fn process_pending_update_add_htlcs(&self) -> bool {
68586858
let mut should_persist = false;
68596859
let mut decode_update_add_htlcs = new_hash_map();
6860+
let mut dummy_update_add_htlcs = new_hash_map();
68606861
mem::swap(&mut decode_update_add_htlcs, &mut self.decode_update_add_htlcs.lock().unwrap());
68616862

68626863
let get_htlc_failure_type = |outgoing_scid_opt: Option<u64>, payment_hash: PaymentHash| {
@@ -6920,7 +6921,67 @@ where
69206921
&*self.logger,
69216922
&self.secp_ctx,
69226923
) {
6923-
Ok(decoded_onion) => decoded_onion,
6924+
Ok(decoded_onion) => match decoded_onion {
6925+
(
6926+
onion_utils::Hop::Dummy {
6927+
intro_node_blinding_point,
6928+
next_hop_hmac,
6929+
new_packet_bytes,
6930+
..
6931+
},
6932+
Some(NextPacketDetails {
6933+
next_packet_pubkey,
6934+
next_hop_forward_info,
6935+
}),
6936+
) => {
6937+
debug_assert!(
6938+
next_hop_forward_info.is_none(),
6939+
"Dummy hops must not contain any forward info, since they are not actually forwarded."
6940+
);
6941+
6942+
// Dummy hops are not forwarded. Instead, we reconstruct a new UpdateAddHTLC
6943+
// with the next onion packet (ephemeral pubkey, hop data, and HMAC) and push
6944+
// it back into our own processing queue. This lets us step through the dummy
6945+
// layers locally until we reach the next real hop.
6946+
let next_blinding_point = intro_node_blinding_point
6947+
.or(update_add_htlc.blinding_point)
6948+
.and_then(|blinding_point| {
6949+
let ss = self
6950+
.node_signer
6951+
.ecdh(Recipient::Node, &blinding_point, None)
6952+
.ok()?
6953+
.secret_bytes();
6954+
6955+
onion_utils::next_hop_pubkey(
6956+
&self.secp_ctx,
6957+
blinding_point,
6958+
&ss,
6959+
)
6960+
.ok()
6961+
});
6962+
6963+
let new_onion_packet = OnionPacket {
6964+
version: 0,
6965+
public_key: next_packet_pubkey,
6966+
hop_data: new_packet_bytes,
6967+
hmac: next_hop_hmac,
6968+
};
6969+
6970+
let new_update_add_htlc = UpdateAddHTLC {
6971+
onion_routing_packet: new_onion_packet,
6972+
blinding_point: next_blinding_point,
6973+
..update_add_htlc.clone()
6974+
};
6975+
6976+
dummy_update_add_htlcs
6977+
.entry(incoming_scid_alias)
6978+
.or_insert_with(Vec::new)
6979+
.push(new_update_add_htlc);
6980+
6981+
continue;
6982+
},
6983+
_ => decoded_onion,
6984+
},
69246985

69256986
Err((htlc_fail, reason)) => {
69266987
let failure_type = HTLCHandlingFailureType::InvalidOnion;
@@ -7077,6 +7138,11 @@ where
70777138
));
70787139
}
70797140
}
7141+
7142+
// Replace the decode queue with the peeled dummy HTLCs so they can be processed in the next iteration.
7143+
let mut decode_update_add_htlc_source = self.decode_update_add_htlcs.lock().unwrap();
7144+
mem::swap(&mut *decode_update_add_htlc_source, &mut dummy_update_add_htlcs);
7145+
70807146
should_persist
70817147
}
70827148

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)