Skip to content

Commit aaf0d45

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 5ff6766 commit aaf0d45

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

lightning/src/ln/channelmanager.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use crate::types::features::Bolt11InvoiceFeatures;
5757
#[cfg(trampoline)]
5858
use crate::routing::gossip::NodeId;
5959
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, Payee, PaymentParameters, RouteParameters, RouteParametersConfig, Router, FixedRouter, Route};
60-
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};
60+
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};
6161
use crate::ln::msgs;
6262
use crate::ln::onion_utils;
6363
use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
@@ -4288,11 +4288,15 @@ where
42884288
// we don't allow forwards outbound over them.
42894289
return Err(("Refusing to forward to a private channel based on our config.", 0x4000 | 10));
42904290
}
4291-
if chan.context.get_channel_type().supports_scid_privacy() && next_packet.outgoing_scid != chan.context.outbound_scid_alias() {
4292-
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
4293-
// "refuse to forward unless the SCID alias was used", so we pretend
4294-
// we don't have the channel here.
4295-
return Err(("Refusing to forward over real channel SCID as our counterparty requested.", 0x4000 | 10));
4291+
if let HopConnector::ShortChannelId(outgoing_scid) = next_packet.outgoing_connector {
4292+
if chan.context.get_channel_type().supports_scid_privacy() && outgoing_scid != chan.context.outbound_scid_alias() {
4293+
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
4294+
// "refuse to forward unless the SCID alias was used", so we pretend
4295+
// we don't have the channel here.
4296+
return Err(("Refusing to forward over real channel SCID as our counterparty requested.", 0x4000 | 10));
4297+
}
4298+
} else {
4299+
return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
42964300
}
42974301

42984302
// Note that we could technically not return an error yet here and just hope
@@ -4344,7 +4348,13 @@ where
43444348
fn can_forward_htlc(
43454349
&self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails
43464350
) -> Result<(), (&'static str, u16)> {
4347-
match self.do_funded_channel_callback(next_packet_details.outgoing_scid, |chan: &mut FundedChannel<SP>| {
4351+
let outgoing_scid = match next_packet_details.outgoing_connector {
4352+
HopConnector::ShortChannelId(scid) => scid,
4353+
HopConnector::Trampoline(_) => {
4354+
return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
4355+
}
4356+
};
4357+
match self.do_funded_channel_callback(outgoing_scid, |chan: &mut FundedChannel<SP>| {
43484358
self.can_forward_htlc_to_outgoing_channel(chan, msg, next_packet_details)
43494359
}) {
43504360
Some(Ok(())) => {},
@@ -4353,8 +4363,8 @@ where
43534363
// If we couldn't find the channel info for the scid, it may be a phantom or
43544364
// intercept forward.
43554365
if (self.default_configuration.accept_intercept_htlcs &&
4356-
fake_scid::is_valid_intercept(&self.fake_scid_rand_bytes, next_packet_details.outgoing_scid, &self.chain_hash)) ||
4357-
fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, next_packet_details.outgoing_scid, &self.chain_hash)
4366+
fake_scid::is_valid_intercept(&self.fake_scid_rand_bytes, outgoing_scid, &self.chain_hash)) ||
4367+
fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, outgoing_scid, &self.chain_hash)
43584368
{} else {
43594369
return Err(("Don't have available channel for forwarding as requested.", 0x4000 | 10));
43604370
}
@@ -5705,7 +5715,12 @@ where
57055715
};
57065716

57075717
let is_intro_node_blinded_forward = next_hop.is_intro_node_blinded_forward();
5708-
let outgoing_scid_opt = next_packet_details_opt.as_ref().map(|d| d.outgoing_scid);
5718+
let outgoing_scid_opt = next_packet_details_opt.as_ref().and_then(|d| {
5719+
match d.outgoing_connector {
5720+
HopConnector::ShortChannelId(scid) => { Some(scid) }
5721+
HopConnector::Trampoline(_) => { None }
5722+
}
5723+
});
57095724
let shared_secret = next_hop.shared_secret().secret_bytes();
57105725

57115726
// Process the HTLC on the incoming channel.

lightning/src/ln/onion_payment.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ where
300300
onion_utils::Hop::Forward { shared_secret, .. } |
301301
onion_utils::Hop::BlindedForward { shared_secret, .. } => {
302302
let NextPacketDetails {
303-
next_packet_pubkey, outgoing_amt_msat: _, outgoing_scid: _, outgoing_cltv_value
303+
next_packet_pubkey, outgoing_amt_msat: _, outgoing_connector: _, outgoing_cltv_value
304304
} = match next_packet_details_opt {
305305
Some(next_packet_details) => next_packet_details,
306306
// Forward should always include the next hop details
@@ -335,9 +335,17 @@ where
335335
})
336336
}
337337

338+
pub(super) enum HopConnector {
339+
// scid-based routing
340+
ShortChannelId(u64),
341+
// Trampoline-based routing
342+
#[allow(unused)]
343+
Trampoline(PublicKey),
344+
}
345+
338346
pub(super) struct NextPacketDetails {
339347
pub(super) next_packet_pubkey: Result<PublicKey, secp256k1::Error>,
340-
pub(super) outgoing_scid: u64,
348+
pub(super) outgoing_connector: HopConnector,
341349
pub(super) outgoing_amt_msat: u64,
342350
pub(super) outgoing_cltv_value: u32,
343351
}
@@ -414,7 +422,7 @@ where
414422
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
415423
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
416424
Some(NextPacketDetails {
417-
next_packet_pubkey, outgoing_scid: short_channel_id,
425+
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id),
418426
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
419427
})
420428
}
@@ -431,7 +439,7 @@ where
431439
let next_packet_pubkey = onion_utils::next_hop_pubkey(&secp_ctx,
432440
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
433441
Some(NextPacketDetails {
434-
next_packet_pubkey, outgoing_scid: short_channel_id, outgoing_amt_msat: amt_to_forward,
442+
next_packet_pubkey, outgoing_connector: HopConnector::ShortChannelId(short_channel_id), outgoing_amt_msat: amt_to_forward,
435443
outgoing_cltv_value
436444
})
437445
}

0 commit comments

Comments
 (0)