Skip to content

Commit 3425345

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 e32f883 commit 3425345

File tree

3 files changed

+70
-34
lines changed

3 files changed

+70
-34
lines changed

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,8 +1675,9 @@ fn route_blinding_spec_test_vector() {
16751675
hop_data: carol_packet_bytes,
16761676
hmac: carol_hmac,
16771677
};
1678+
let carol_forward_info = carol_packet_details.next_hop_forward_info.unwrap();
16781679
let carol_update_add = update_add_msg(
1679-
carol_packet_details.outgoing_amt_msat, carol_packet_details.outgoing_cltv_value,
1680+
carol_forward_info.outgoing_amt_msat, carol_forward_info.outgoing_cltv_value,
16801681
Some(pubkey_from_hex("034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0")),
16811682
carol_onion
16821683
);
@@ -1709,8 +1710,9 @@ fn route_blinding_spec_test_vector() {
17091710
hop_data: dave_packet_bytes,
17101711
hmac: dave_hmac,
17111712
};
1713+
let dave_forward_info = dave_packet_details.next_hop_forward_info.unwrap();
17121714
let dave_update_add = update_add_msg(
1713-
dave_packet_details.outgoing_amt_msat, dave_packet_details.outgoing_cltv_value,
1715+
dave_forward_info.outgoing_amt_msat, dave_forward_info.outgoing_cltv_value,
17141716
Some(pubkey_from_hex("031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f")),
17151717
dave_onion
17161718
);
@@ -1743,8 +1745,9 @@ fn route_blinding_spec_test_vector() {
17431745
hop_data: eve_packet_bytes,
17441746
hmac: eve_hmac,
17451747
};
1748+
let eve_forward_info = eve_packet_details.next_hop_forward_info.unwrap();
17461749
let eve_update_add = update_add_msg(
1747-
eve_packet_details.outgoing_amt_msat, eve_packet_details.outgoing_cltv_value,
1750+
eve_forward_info.outgoing_amt_msat, eve_forward_info.outgoing_cltv_value,
17481751
Some(pubkey_from_hex("03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a")),
17491752
eve_onion
17501753
);
@@ -1977,7 +1980,8 @@ fn test_trampoline_inbound_payment_decoding() {
19771980
hop_data: carol_packet_bytes,
19781981
hmac: carol_hmac,
19791982
};
1980-
let carol_update_add = update_add_msg(carol_packet_details.outgoing_amt_msat, carol_packet_details.outgoing_cltv_value, None, carol_onion);
1983+
let carol_forward_info = carol_packet_details.next_hop_forward_info.unwrap();
1984+
let carol_update_add = update_add_msg(carol_forward_info.outgoing_amt_msat, carol_forward_info.outgoing_cltv_value, None, carol_onion);
19811985

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

lightning/src/ln/channelmanager.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use crate::ln::msgs::{
7474
use crate::ln::onion_payment::{
7575
check_incoming_htlc_cltv, create_fwd_pending_htlc_info, create_recv_pending_htlc_info,
7676
decode_incoming_update_add_htlc_onion, invalid_payment_err_data, HopConnector, InboundHTLCErr,
77-
NextPacketDetails,
77+
NextHopForwardInfo, NextPacketDetails,
7878
};
7979
use crate::ln::onion_utils::{self};
8080
use crate::ln::onion_utils::{
@@ -4904,7 +4904,7 @@ where
49044904

49054905
#[rustfmt::skip]
49064906
fn can_forward_htlc_to_outgoing_channel(
4907-
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, next_packet: &NextPacketDetails
4907+
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, forward_info: &NextHopForwardInfo
49084908
) -> Result<(), LocalHTLCFailureReason> {
49094909
if !chan.context.should_announce()
49104910
&& !self.config.read().unwrap().accept_forwards_to_priv_channels
@@ -4914,7 +4914,7 @@ where
49144914
// we don't allow forwards outbound over them.
49154915
return Err(LocalHTLCFailureReason::PrivateChannelForward);
49164916
}
4917-
if let HopConnector::ShortChannelId(outgoing_scid) = next_packet.outgoing_connector {
4917+
if let HopConnector::ShortChannelId(outgoing_scid) = forward_info.outgoing_connector {
49184918
if chan.funding.get_channel_type().supports_scid_privacy() && outgoing_scid != chan.context.outbound_scid_alias() {
49194919
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
49204920
// "refuse to forward unless the SCID alias was used", so we pretend
@@ -4937,10 +4937,10 @@ where
49374937
return Err(LocalHTLCFailureReason::ChannelNotReady);
49384938
}
49394939
}
4940-
if next_packet.outgoing_amt_msat < chan.context.get_counterparty_htlc_minimum_msat() {
4940+
if forward_info.outgoing_amt_msat < chan.context.get_counterparty_htlc_minimum_msat() {
49414941
return Err(LocalHTLCFailureReason::AmountBelowMinimum);
49424942
}
4943-
chan.htlc_satisfies_config(msg, next_packet.outgoing_amt_msat, next_packet.outgoing_cltv_value)?;
4943+
chan.htlc_satisfies_config(msg, forward_info.outgoing_amt_msat, forward_info.outgoing_cltv_value)?;
49444944

49454945
Ok(())
49464946
}
@@ -4972,14 +4972,20 @@ where
49724972
fn can_forward_htlc(
49734973
&self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails
49744974
) -> Result<(), LocalHTLCFailureReason> {
4975-
let outgoing_scid = match next_packet_details.outgoing_connector {
4975+
let next_hop_forward_info = next_packet_details
4976+
.next_hop_forward_info
4977+
.as_ref()
4978+
.ok_or(LocalHTLCFailureReason::InvalidOnionPayload)?;
4979+
4980+
let outgoing_scid = match next_hop_forward_info.outgoing_connector {
49764981
HopConnector::ShortChannelId(scid) => scid,
49774982
HopConnector::Trampoline(_) => {
49784983
return Err(LocalHTLCFailureReason::InvalidTrampolineForward);
49794984
}
49804985
};
4986+
49814987
match self.do_funded_channel_callback(outgoing_scid, |chan: &mut FundedChannel<SP>| {
4982-
self.can_forward_htlc_to_outgoing_channel(chan, msg, next_packet_details)
4988+
self.can_forward_htlc_to_outgoing_channel(chan, msg, next_hop_forward_info)
49834989
}) {
49844990
Some(Ok(())) => {},
49854991
Some(Err(e)) => return Err(e),
@@ -4996,7 +5002,7 @@ where
49965002
}
49975003

49985004
let cur_height = self.best_block.read().unwrap().height + 1;
4999-
check_incoming_htlc_cltv(cur_height, next_packet_details.outgoing_cltv_value, msg.cltv_expiry)?;
5005+
check_incoming_htlc_cltv(cur_height, next_hop_forward_info.outgoing_cltv_value, msg.cltv_expiry)?;
50005006

50015007
Ok(())
50025008
}
@@ -6951,11 +6957,12 @@ where
69516957
};
69526958

69536959
let is_intro_node_blinded_forward = next_hop.is_intro_node_blinded_forward();
6954-
let outgoing_scid_opt =
6955-
next_packet_details_opt.as_ref().and_then(|d| match d.outgoing_connector {
6960+
let outgoing_scid_opt = next_packet_details_opt.as_ref().and_then(|d| {
6961+
d.next_hop_forward_info.as_ref().and_then(|f| match f.outgoing_connector {
69566962
HopConnector::ShortChannelId(scid) => Some(scid),
69576963
HopConnector::Trampoline(_) => None,
6958-
});
6964+
})
6965+
});
69596966
let shared_secret = next_hop.shared_secret().secret_bytes();
69606967

69616968
// 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: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -506,16 +506,19 @@ where
506506
Ok(match hop {
507507
onion_utils::Hop::Forward { shared_secret, .. } |
508508
onion_utils::Hop::BlindedForward { shared_secret, .. } => {
509-
let NextPacketDetails {
510-
next_packet_pubkey, outgoing_amt_msat: _, outgoing_connector: _, outgoing_cltv_value
511-
} = match next_packet_details_opt {
512-
Some(next_packet_details) => next_packet_details,
509+
let (next_packet_pubkey, outgoing_cltv_value) = match next_packet_details_opt {
510+
Some(NextPacketDetails {
511+
next_packet_pubkey,
512+
next_hop_forward_info: Some(NextHopForwardInfo { outgoing_cltv_value, .. }),
513+
}) => (next_packet_pubkey, outgoing_cltv_value),
513514
// Forward should always include the next hop details
514-
None => return Err(InboundHTLCErr {
515-
msg: "Failed to decode update add htlc onion",
516-
reason: LocalHTLCFailureReason::InvalidOnionPayload,
517-
err_data: Vec::new(),
518-
}),
515+
_ => {
516+
return Err(InboundHTLCErr {
517+
msg: "Failed to decode update add htlc onion",
518+
reason: LocalHTLCFailureReason::InvalidOnionPayload,
519+
err_data: Vec::new(),
520+
});
521+
}
519522
};
520523

521524
if let Err(reason) = check_incoming_htlc_cltv(
@@ -552,6 +555,10 @@ pub(super) enum HopConnector {
552555

553556
pub(super) struct NextPacketDetails {
554557
pub(super) next_packet_pubkey: Result<PublicKey, secp256k1::Error>,
558+
pub(super) next_hop_forward_info: Option<NextHopForwardInfo>,
559+
}
560+
561+
pub(super) struct NextHopForwardInfo {
555562
pub(super) outgoing_connector: HopConnector,
556563
pub(super) outgoing_amt_msat: u64,
557564
pub(super) outgoing_cltv_value: u32,
@@ -628,8 +635,12 @@ where
628635
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
629636
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
630637
Some(NextPacketDetails {
631-
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
632-
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
638+
next_packet_pubkey,
639+
next_hop_forward_info: Some(NextHopForwardInfo {
640+
outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
641+
outgoing_amt_msat: amt_to_forward,
642+
outgoing_cltv_value,
643+
}),
633644
})
634645
}
635646
onion_utils::Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload { short_channel_id, ref payment_relay, ref payment_constraints, ref features, .. }, shared_secret, .. } => {
@@ -645,19 +656,31 @@ where
645656
let next_packet_pubkey = onion_utils::next_hop_pubkey(&secp_ctx,
646657
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
647658
Some(NextPacketDetails {
648-
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id), outgoing_amt_msat: amt_to_forward,
649-
outgoing_cltv_value
659+
next_packet_pubkey,
660+
next_hop_forward_info: Some(NextHopForwardInfo {
661+
outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
662+
outgoing_amt_msat: amt_to_forward,
663+
outgoing_cltv_value,
664+
}),
650665
})
651666
}
652667
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, .. } => {
653668
let next_trampoline_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
654669
incoming_trampoline_public_key, &trampoline_shared_secret.secret_bytes());
655670
Some(NextPacketDetails {
656671
next_packet_pubkey: next_trampoline_packet_pubkey,
657-
outgoing_connector: HopConnector::Trampoline(next_trampoline),
658-
outgoing_amt_msat: amt_to_forward,
659-
outgoing_cltv_value,
672+
next_hop_forward_info: Some(NextHopForwardInfo {
673+
outgoing_connector: HopConnector::Trampoline(next_trampoline),
674+
outgoing_amt_msat: amt_to_forward,
675+
outgoing_cltv_value,
676+
}),
660677
})
678+
},
679+
onion_utils::Hop::Dummy { shared_secret, .. } => {
680+
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
681+
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
682+
683+
Some(NextPacketDetails { next_packet_pubkey, next_hop_forward_info: None })
661684
}
662685
onion_utils::Hop::TrampolineBlindedForward { next_trampoline_hop_data: msgs::InboundTrampolineBlindedForwardPayload { next_trampoline, ref payment_relay, ref payment_constraints, ref features, .. }, outer_shared_secret, trampoline_shared_secret, incoming_trampoline_public_key, .. } => {
663686
let (amt_to_forward, outgoing_cltv_value) = match check_blinded_forward(
@@ -673,9 +696,11 @@ where
673696
incoming_trampoline_public_key, &trampoline_shared_secret.secret_bytes());
674697
Some(NextPacketDetails {
675698
next_packet_pubkey: next_trampoline_packet_pubkey,
676-
outgoing_connector: HopConnector::Trampoline(next_trampoline),
677-
outgoing_amt_msat: amt_to_forward,
678-
outgoing_cltv_value,
699+
next_hop_forward_info: Some(NextHopForwardInfo {
700+
outgoing_connector: HopConnector::Trampoline(next_trampoline),
701+
outgoing_amt_msat: amt_to_forward,
702+
outgoing_cltv_value
703+
}),
679704
})
680705
}
681706
_ => None

0 commit comments

Comments
 (0)