@@ -66,7 +66,7 @@ use crate::ln::channel_state::ChannelDetails;
6666use crate::ln::funding::SpliceContribution;
6767use crate::ln::inbound_payment;
6868use crate::ln::interactivetxs::InteractiveTxMessageSend;
69- use crate::ln::msgs;
69+ use crate::ln::msgs::{self, OnionPacket, UpdateAddHTLC} ;
7070use 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
0 commit comments