Skip to content

Commit

Permalink
f - add one more hop to blinded payment paths
Browse files Browse the repository at this point in the history
  • Loading branch information
jkczyz committed Dec 12, 2023
1 parent 9dc55eb commit bcfff55
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 24 deletions.
2 changes: 1 addition & 1 deletion lightning/src/routing/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ impl<'a> DirectedChannelInfo<'a> {

/// Returns information for the direction.
#[inline]
pub(super) fn direction(&self) -> &'a ChannelUpdateInfo { self.direction }
pub(crate) fn direction(&self) -> &'a ChannelUpdateInfo { self.direction }

/// Returns the `node_id` of the source hop.
///
Expand Down
93 changes: 70 additions & 23 deletions lightning/src/routing/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
&self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
amount_msats: u64, entropy_source: &ES, secp_ctx: &Secp256k1<T>
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
let recipient_node_id = NodeId::from_pubkey(&recipient);

// Limit the number of blinded paths that are computed.
const MAX_PAYMENT_PATHS: usize = 3;

Expand All @@ -98,37 +100,82 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
const MIN_PEER_CHANNELS: usize = 3;
let network_graph = self.network_graph.deref().read_only();

first_hops.into_iter()
.filter(|details| details.is_public)
first_hops.iter()
.filter(|details| details.counterparty.features.supports_route_blinding())
.filter(|details| amount_msats <= details.inbound_capacity_msat)
.filter(|details| amount_msats >= details.inbound_htlc_minimum_msat.unwrap_or(0))
.filter(|details| amount_msats <= details.inbound_htlc_maximum_msat.unwrap_or(0))
.filter(|details| network_graph
.node(&NodeId::from_pubkey(&details.counterparty.node_id))
.map(|node_info| node_info.channels.len() >= MIN_PEER_CHANNELS)
.unwrap_or(false)
.map(|details| (details, NodeId::from_pubkey(&details.counterparty.node_id)))
// Limit to counterparties with announced channels
.filter_map(|(details, counterparty_node_id)|
network_graph
.node(&counterparty_node_id)
.map(|info| &info.channels[..])
.and_then(|channels| (channels.len() >= MIN_PEER_CHANNELS).then(|| channels))
.map(|channels| (details, counterparty_node_id, channels))
)
// Pair counterparties with their other channels
.flat_map(|(details, counterparty_node_id, counterparty_channels)|
counterparty_channels
.iter()
.filter_map(|scid| network_graph.channels().get_key_value(scid))
.filter_map(move |(scid, info)| info
.as_directed_to(&counterparty_node_id)
.map(|(info, source)| (source, *scid, info))
)
.filter(|(source, _, _)| **source != recipient_node_id)
.filter(|(_, _, info)| amount_msats >= info.direction().htlc_minimum_msat)
.filter(|(_, _, info)| amount_msats <= info.direction().htlc_maximum_msat)
.map(move |(source, scid, info)| (source, scid, info, details))
)
.map(|details| {
let short_channel_id = details.get_inbound_payment_scid().unwrap();
let payment_relay: PaymentRelay = details.counterparty.forwarding_info.unwrap().into();
let payment_constraints = PaymentConstraints {
max_cltv_expiry: tlvs.payment_constraints.max_cltv_expiry
+ payment_relay.cltv_expiry_delta as u32,
htlc_minimum_msat: details.inbound_htlc_minimum_msat.unwrap_or(0),
// Construct blinded paths where the counterparty's counterparty is the introduction
// node:
//
// source --- info ---> counterparty --- details ---> recipient
.map(|(introduction_node_id, scid, info, details)| {
let counterparty_forward_node = {
let short_channel_id = details.get_inbound_payment_scid().unwrap();
let payment_relay: PaymentRelay =
details.counterparty.forwarding_info.clone().unwrap().into();
let payment_constraints = PaymentConstraints {
max_cltv_expiry: payment_relay.cltv_expiry_delta as u32
+ tlvs.payment_constraints.max_cltv_expiry,
htlc_minimum_msat: details.inbound_htlc_minimum_msat.unwrap_or(0),
};
ForwardNode {
tlvs: ForwardTlvs {
short_channel_id,
payment_relay,
payment_constraints,
features: BlindedHopFeatures::empty(),
},
node_id: details.counterparty.node_id,
htlc_maximum_msat: details.inbound_htlc_maximum_msat.unwrap_or(0),
}
};
let forward_node = ForwardNode {
tlvs: ForwardTlvs {
short_channel_id,
payment_relay,
payment_constraints,
features: BlindedHopFeatures::empty(),
},
node_id: details.counterparty.node_id,
htlc_maximum_msat: details.inbound_htlc_maximum_msat.unwrap_or(0),
let introduction_forward_node = {
let htlc_minimum_msat = info.direction().htlc_minimum_msat;
let htlc_maximum_msat = info.direction().htlc_maximum_msat;
let payment_relay: PaymentRelay = info.into();
let payment_constraints = PaymentConstraints {
max_cltv_expiry: payment_relay.cltv_expiry_delta as u32
+ counterparty_forward_node.tlvs.payment_constraints.max_cltv_expiry,
htlc_minimum_msat,
};
ForwardNode {
tlvs: ForwardTlvs {
short_channel_id: scid,
payment_relay,
payment_constraints,
features: BlindedHopFeatures::empty(),
},
node_id: introduction_node_id.as_pubkey().unwrap(),
htlc_maximum_msat,
}
};
BlindedPath::new_for_payment(
&[forward_node], recipient, tlvs.clone(), u64::MAX, entropy_source, secp_ctx
&[introduction_forward_node, counterparty_forward_node], recipient,
tlvs.clone(), u64::MAX, entropy_source, secp_ctx
)
})
.take(MAX_PAYMENT_PATHS)
Expand Down

0 comments on commit bcfff55

Please sign in to comment.