Skip to content

Commit dff9cf4

Browse files
committed
Refactor: Introduce ForwardInfo
NextPacketDetails currently bundles four fields used to define the forwarding details for the packet. With the introduction of dummy hops, not all of these fields apply in those paths. To avoid overloading NextPacketDetails with conditional semantics, this refactor extracts the forwarding-specific pieces into a dedicated ForwardInfo struct. This keeps the data model clean, reusable, and makes the logic around dummy hops easier to follow.
1 parent 679001c commit dff9cf4

File tree

3 files changed

+66
-32
lines changed

3 files changed

+66
-32
lines changed

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,8 +1663,9 @@ fn route_blinding_spec_test_vector() {
16631663
hop_data: carol_packet_bytes,
16641664
hmac: carol_hmac,
16651665
};
1666+
let carol_forward_info = carol_packet_details.forward_info.unwrap();
16661667
let carol_update_add = update_add_msg(
1667-
carol_packet_details.outgoing_amt_msat, carol_packet_details.outgoing_cltv_value,
1668+
carol_forward_info.outgoing_amt_msat, carol_forward_info.outgoing_cltv_value,
16681669
Some(pubkey_from_hex("034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0")),
16691670
carol_onion
16701671
);
@@ -1697,8 +1698,9 @@ fn route_blinding_spec_test_vector() {
16971698
hop_data: dave_packet_bytes,
16981699
hmac: dave_hmac,
16991700
};
1701+
let dave_forward_info = dave_packet_details.forward_info.unwrap();
17001702
let dave_update_add = update_add_msg(
1701-
dave_packet_details.outgoing_amt_msat, dave_packet_details.outgoing_cltv_value,
1703+
dave_forward_info.outgoing_amt_msat, dave_forward_info.outgoing_cltv_value,
17021704
Some(pubkey_from_hex("031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f")),
17031705
dave_onion
17041706
);
@@ -1731,8 +1733,9 @@ fn route_blinding_spec_test_vector() {
17311733
hop_data: eve_packet_bytes,
17321734
hmac: eve_hmac,
17331735
};
1736+
let eve_forward_info = eve_packet_details.forward_info.unwrap();
17341737
let eve_update_add = update_add_msg(
1735-
eve_packet_details.outgoing_amt_msat, eve_packet_details.outgoing_cltv_value,
1738+
eve_forward_info.outgoing_amt_msat, eve_forward_info.outgoing_cltv_value,
17361739
Some(pubkey_from_hex("03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a")),
17371740
eve_onion
17381741
);
@@ -1963,7 +1966,8 @@ fn test_trampoline_inbound_payment_decoding() {
19631966
hop_data: carol_packet_bytes,
19641967
hmac: carol_hmac,
19651968
};
1966-
let carol_update_add = update_add_msg(carol_packet_details.outgoing_amt_msat, carol_packet_details.outgoing_cltv_value, None, carol_onion);
1969+
let carol_forward_info = carol_packet_details.forward_info.unwrap();
1970+
let carol_update_add = update_add_msg(carol_forward_info.outgoing_amt_msat, carol_forward_info.outgoing_cltv_value, None, carol_onion);
19671971

19681972
let carol_node_signer = TestEcdhSigner { node_secret: carol_secret };
19691973
let (carol_peeled_onion, _) = onion_payment::decode_incoming_update_add_htlc_onion(

lightning/src/ln/channelmanager.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ use crate::ln::msgs::{
7373
};
7474
use crate::ln::onion_payment::{
7575
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, HopConnector, InboundHTLCErr,
77-
NextPacketDetails,
76+
decode_incoming_update_add_htlc_onion, invalid_payment_err_data, ForwardInfo, HopConnector,
77+
InboundHTLCErr, NextPacketDetails,
7878
};
7979
use crate::ln::onion_utils::{self};
8080
use crate::ln::onion_utils::{
@@ -4888,7 +4888,7 @@ where
48884888

48894889
#[rustfmt::skip]
48904890
fn can_forward_htlc_to_outgoing_channel(
4891-
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, next_packet: &NextPacketDetails
4891+
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, forward_info: &ForwardInfo
48924892
) -> Result<(), LocalHTLCFailureReason> {
48934893
if !chan.context.should_announce()
48944894
&& !self.config.read().unwrap().accept_forwards_to_priv_channels
@@ -4898,7 +4898,7 @@ where
48984898
// we don't allow forwards outbound over them.
48994899
return Err(LocalHTLCFailureReason::PrivateChannelForward);
49004900
}
4901-
if let HopConnector::ShortChannelId(outgoing_scid) = next_packet.outgoing_connector {
4901+
if let HopConnector::ShortChannelId(outgoing_scid) = forward_info.outgoing_connector {
49024902
if chan.funding.get_channel_type().supports_scid_privacy() && outgoing_scid != chan.context.outbound_scid_alias() {
49034903
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
49044904
// "refuse to forward unless the SCID alias was used", so we pretend
@@ -4921,10 +4921,10 @@ where
49214921
return Err(LocalHTLCFailureReason::ChannelNotReady);
49224922
}
49234923
}
4924-
if next_packet.outgoing_amt_msat < chan.context.get_counterparty_htlc_minimum_msat() {
4924+
if forward_info.outgoing_amt_msat < chan.context.get_counterparty_htlc_minimum_msat() {
49254925
return Err(LocalHTLCFailureReason::AmountBelowMinimum);
49264926
}
4927-
chan.htlc_satisfies_config(msg, next_packet.outgoing_amt_msat, next_packet.outgoing_cltv_value)?;
4927+
chan.htlc_satisfies_config(msg, forward_info.outgoing_amt_msat, forward_info.outgoing_cltv_value)?;
49284928

49294929
Ok(())
49304930
}
@@ -4956,14 +4956,20 @@ where
49564956
fn can_forward_htlc(
49574957
&self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails
49584958
) -> Result<(), LocalHTLCFailureReason> {
4959-
let outgoing_scid = match next_packet_details.outgoing_connector {
4959+
let forward_info = next_packet_details
4960+
.forward_info
4961+
.as_ref()
4962+
.ok_or(LocalHTLCFailureReason::InvalidOnionPayload)?;
4963+
4964+
let outgoing_scid = match forward_info.outgoing_connector {
49604965
HopConnector::ShortChannelId(scid) => scid,
49614966
HopConnector::Trampoline(_) => {
49624967
return Err(LocalHTLCFailureReason::InvalidTrampolineForward);
49634968
}
49644969
};
4970+
49654971
match self.do_funded_channel_callback(outgoing_scid, |chan: &mut FundedChannel<SP>| {
4966-
self.can_forward_htlc_to_outgoing_channel(chan, msg, next_packet_details)
4972+
self.can_forward_htlc_to_outgoing_channel(chan, msg, forward_info)
49674973
}) {
49684974
Some(Ok(())) => {},
49694975
Some(Err(e)) => return Err(e),
@@ -4980,7 +4986,7 @@ where
49804986
}
49814987

49824988
let cur_height = self.best_block.read().unwrap().height + 1;
4983-
check_incoming_htlc_cltv(cur_height, next_packet_details.outgoing_cltv_value, msg.cltv_expiry)?;
4989+
check_incoming_htlc_cltv(cur_height, forward_info.outgoing_cltv_value, msg.cltv_expiry)?;
49844990

49854991
Ok(())
49864992
}
@@ -6918,11 +6924,12 @@ where
69186924
};
69196925

69206926
let is_intro_node_blinded_forward = next_hop.is_intro_node_blinded_forward();
6921-
let outgoing_scid_opt =
6922-
next_packet_details_opt.as_ref().and_then(|d| match d.outgoing_connector {
6927+
let outgoing_scid_opt = next_packet_details_opt.as_ref().and_then(|d| {
6928+
d.forward_info.as_ref().and_then(|f| match f.outgoing_connector {
69236929
HopConnector::ShortChannelId(scid) => Some(scid),
69246930
HopConnector::Trampoline(_) => None,
6925-
});
6931+
})
6932+
});
69266933
let shared_secret = next_hop.shared_secret().secret_bytes();
69276934

69286935
// Nodes shouldn't expect us to hold HTLCs for them if we don't advertise htlc_hold feature

lightning/src/ln/onion_payment.rs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -469,16 +469,19 @@ where
469469
Ok(match hop {
470470
onion_utils::Hop::Forward { shared_secret, .. } |
471471
onion_utils::Hop::BlindedForward { shared_secret, .. } => {
472-
let NextPacketDetails {
473-
next_packet_pubkey, outgoing_amt_msat: _, outgoing_connector: _, outgoing_cltv_value
474-
} = match next_packet_details_opt {
475-
Some(next_packet_details) => next_packet_details,
472+
let (next_packet_pubkey, outgoing_cltv_value) = match next_packet_details_opt {
473+
Some(NextPacketDetails {
474+
next_packet_pubkey,
475+
forward_info: Some(ForwardInfo { outgoing_cltv_value, .. }),
476+
}) => (next_packet_pubkey, outgoing_cltv_value),
476477
// Forward should always include the next hop details
477-
None => return Err(InboundHTLCErr {
478-
msg: "Failed to decode update add htlc onion",
479-
reason: LocalHTLCFailureReason::InvalidOnionPayload,
480-
err_data: Vec::new(),
481-
}),
478+
_ => {
479+
return Err(InboundHTLCErr {
480+
msg: "Failed to decode update add htlc onion",
481+
reason: LocalHTLCFailureReason::InvalidOnionPayload,
482+
err_data: Vec::new(),
483+
});
484+
}
482485
};
483486

484487
if let Err(reason) = check_incoming_htlc_cltv(
@@ -515,6 +518,10 @@ pub(super) enum HopConnector {
515518

516519
pub(super) struct NextPacketDetails {
517520
pub(super) next_packet_pubkey: Result<PublicKey, secp256k1::Error>,
521+
pub(super) forward_info: Option<ForwardInfo>,
522+
}
523+
524+
pub(super) struct ForwardInfo {
518525
pub(super) outgoing_connector: HopConnector,
519526
pub(super) outgoing_amt_msat: u64,
520527
pub(super) outgoing_cltv_value: u32,
@@ -591,8 +598,12 @@ where
591598
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
592599
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
593600
Some(NextPacketDetails {
594-
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
595-
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
601+
next_packet_pubkey,
602+
forward_info: Some(ForwardInfo {
603+
outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
604+
outgoing_amt_msat: amt_to_forward,
605+
outgoing_cltv_value,
606+
}),
596607
})
597608
}
598609
onion_utils::Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload { short_channel_id, ref payment_relay, ref payment_constraints, ref features, .. }, shared_secret, .. } => {
@@ -608,19 +619,31 @@ where
608619
let next_packet_pubkey = onion_utils::next_hop_pubkey(&secp_ctx,
609620
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
610621
Some(NextPacketDetails {
611-
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id), outgoing_amt_msat: amt_to_forward,
612-
outgoing_cltv_value
622+
next_packet_pubkey,
623+
forward_info: Some(ForwardInfo {
624+
outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
625+
outgoing_amt_msat: amt_to_forward,
626+
outgoing_cltv_value,
627+
}),
613628
})
614629
}
615630
onion_utils::Hop::TrampolineForward { next_trampoline_hop_data: msgs::InboundTrampolineForwardPayload { amt_to_forward, outgoing_cltv_value, next_trampoline }, trampoline_shared_secret, incoming_trampoline_public_key, .. } => {
616631
let next_trampoline_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
617632
incoming_trampoline_public_key, &trampoline_shared_secret.secret_bytes());
618633
Some(NextPacketDetails {
619634
next_packet_pubkey: next_trampoline_packet_pubkey,
620-
outgoing_connector: HopConnector::Trampoline(next_trampoline),
621-
outgoing_amt_msat: amt_to_forward,
622-
outgoing_cltv_value,
635+
forward_info: Some(ForwardInfo {
636+
outgoing_connector: HopConnector::Trampoline(next_trampoline),
637+
outgoing_amt_msat: amt_to_forward,
638+
outgoing_cltv_value,
639+
}),
623640
})
641+
},
642+
onion_utils::Hop::Dummy { shared_secret, .. } => {
643+
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
644+
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
645+
646+
Some(NextPacketDetails { next_packet_pubkey, forward_info: None })
624647
}
625648
_ => None
626649
};

0 commit comments

Comments
 (0)