Skip to content

Commit f262608

Browse files
committed
Introduce HopConnector enum
When parsing inbound HTLCs, we need to provide supplemental information about potential outgoing hops, which hitherto always required the next SCID. However, Trampoline uproots the approach because the sender did not specify the SCID; rather, they rely on us to do the intermediate routing. Thus we now need to distinguish between SCID-based and node- ID-based outgoing routing.
1 parent eec4bd9 commit f262608

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

lightning/src/ln/channelmanager.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::types::features::Bolt11InvoiceFeatures;
5858
#[cfg(trampoline)]
5959
use crate::routing::gossip::NodeId;
6060
use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, RouteParametersConfig, Router};
61-
use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, InboundHTLCErr, NextPacketDetails};
61+
use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, HopConnector, InboundHTLCErr, NextPacketDetails};
6262
use crate::ln::msgs;
6363
use crate::ln::onion_utils;
6464
use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
@@ -4290,11 +4290,15 @@ where
42904290
// we don't allow forwards outbound over them.
42914291
return Err(("Refusing to forward to a private channel based on our config.", 0x4000 | 10));
42924292
}
4293-
if chan.context.get_channel_type().supports_scid_privacy() && next_packet.outgoing_scid != chan.context.outbound_scid_alias() {
4294-
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
4295-
// "refuse to forward unless the SCID alias was used", so we pretend
4296-
// we don't have the channel here.
4297-
return Err(("Refusing to forward over real channel SCID as our counterparty requested.", 0x4000 | 10));
4293+
if let HopConnector::ShortChannelId(outgoing_scid) = next_packet.outgoing_connector {
4294+
if chan.context.get_channel_type().supports_scid_privacy() && outgoing_scid != chan.context.outbound_scid_alias() {
4295+
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
4296+
// "refuse to forward unless the SCID alias was used", so we pretend
4297+
// we don't have the channel here.
4298+
return Err(("Refusing to forward over real channel SCID as our counterparty requested.", 0x4000 | 10));
4299+
}
4300+
} else {
4301+
return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
42984302
}
42994303

43004304
// Note that we could technically not return an error yet here and just hope
@@ -4346,7 +4350,13 @@ where
43464350
fn can_forward_htlc(
43474351
&self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails
43484352
) -> Result<(), (&'static str, u16)> {
4349-
match self.do_funded_channel_callback(next_packet_details.outgoing_scid, |chan: &mut FundedChannel<SP>| {
4353+
let outgoing_scid = match next_packet_details.outgoing_connector {
4354+
HopConnector::ShortChannelId(scid) => scid,
4355+
HopConnector::Trampoline(_) => {
4356+
return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
4357+
}
4358+
};
4359+
match self.do_funded_channel_callback(outgoing_scid, |chan: &mut FundedChannel<SP>| {
43504360
self.can_forward_htlc_to_outgoing_channel(chan, msg, next_packet_details)
43514361
}) {
43524362
Some(Ok(())) => {},
@@ -4355,8 +4365,8 @@ where
43554365
// If we couldn't find the channel info for the scid, it may be a phantom or
43564366
// intercept forward.
43574367
if (self.default_configuration.accept_intercept_htlcs &&
4358-
fake_scid::is_valid_intercept(&self.fake_scid_rand_bytes, next_packet_details.outgoing_scid, &self.chain_hash)) ||
4359-
fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, next_packet_details.outgoing_scid, &self.chain_hash)
4368+
fake_scid::is_valid_intercept(&self.fake_scid_rand_bytes, outgoing_scid, &self.chain_hash)) ||
4369+
fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, outgoing_scid, &self.chain_hash)
43604370
{} else {
43614371
return Err(("Don't have available channel for forwarding as requested.", 0x4000 | 10));
43624372
}
@@ -5708,7 +5718,12 @@ where
57085718
};
57095719

57105720
let is_intro_node_blinded_forward = next_hop.is_intro_node_blinded_forward();
5711-
let outgoing_scid_opt = next_packet_details_opt.as_ref().map(|d| d.outgoing_scid);
5721+
let outgoing_scid_opt = next_packet_details_opt.as_ref().and_then(|d| {
5722+
match d.outgoing_connector {
5723+
HopConnector::ShortChannelId(scid) => { Some(scid) }
5724+
HopConnector::Trampoline(_) => { None }
5725+
}
5726+
});
57125727
let shared_secret = next_hop.shared_secret().secret_bytes();
57135728

57145729
// Process the HTLC on the incoming channel.

lightning/src/ln/onion_payment.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::types::features::BlindedHopFeatures;
1616
use crate::ln::msgs;
1717
use crate::ln::onion_utils;
1818
use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
19+
use crate::routing::gossip::NodeId;
1920
use crate::sign::{NodeSigner, Recipient};
2021
use crate::util::logger::Logger;
2122

@@ -298,7 +299,7 @@ where
298299
onion_utils::Hop::Forward { shared_secret, next_hop_hmac, new_packet_bytes, .. } |
299300
onion_utils::Hop::BlindedForward { shared_secret, next_hop_hmac, new_packet_bytes, .. } => {
300301
let NextPacketDetails {
301-
next_packet_pubkey, outgoing_amt_msat: _, outgoing_scid: _, outgoing_cltv_value
302+
next_packet_pubkey, outgoing_amt_msat: _, outgoing_connector: _, outgoing_cltv_value
302303
} = match next_packet_details_opt {
303304
Some(next_packet_details) => next_packet_details,
304305
// Forward should always include the next hop details
@@ -336,9 +337,17 @@ where
336337
})
337338
}
338339

340+
pub(super) enum HopConnector {
341+
// scid-based routing
342+
ShortChannelId(u64),
343+
// Trampoline-based routing
344+
#[allow(unused)]
345+
Trampoline(NodeId),
346+
}
347+
339348
pub(super) struct NextPacketDetails {
340349
pub(super) next_packet_pubkey: Result<PublicKey, secp256k1::Error>,
341-
pub(super) outgoing_scid: u64,
350+
pub(super) outgoing_connector: HopConnector,
342351
pub(super) outgoing_amt_msat: u64,
343352
pub(super) outgoing_cltv_value: u32,
344353
}
@@ -415,7 +424,7 @@ where
415424
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
416425
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
417426
Some(NextPacketDetails {
418-
next_packet_pubkey, outgoing_scid: short_channel_id,
427+
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
419428
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
420429
})
421430
}
@@ -432,7 +441,7 @@ where
432441
let next_packet_pubkey = onion_utils::next_hop_pubkey(&secp_ctx,
433442
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
434443
Some(NextPacketDetails {
435-
next_packet_pubkey, outgoing_scid: short_channel_id, outgoing_amt_msat: amt_to_forward,
444+
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id), outgoing_amt_msat: amt_to_forward,
436445
outgoing_cltv_value
437446
})
438447
}

0 commit comments

Comments
 (0)