Skip to content

Commit

Permalink
WIP: Include blinded paths
Browse files Browse the repository at this point in the history
  • Loading branch information
jkczyz committed Aug 17, 2023
1 parent 213ee79 commit acb28b9
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
6 changes: 3 additions & 3 deletions lightning/src/blinded_path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ impl BlindedPath {
///
/// Errors if less than two hops are provided or if `node_pk`(s) are invalid.
// TODO: make all payloads the same size with padding + add dummy hops
pub fn new_for_message<ES: EntropySource, T: secp256k1::Signing + secp256k1::Verification>
(node_pks: &[PublicKey], entropy_source: &ES, secp_ctx: &Secp256k1<T>) -> Result<Self, ()>
{
pub fn new_for_message<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
node_pks: &[PublicKey], entropy_source: ES, secp_ctx: &Secp256k1<T>
) -> Result<Self, ()> where ES::Target: EntropySource {
if node_pks.len() < 2 { return Err(()) }
let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
Expand Down
42 changes: 39 additions & 3 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use bitcoin::secp256k1::{SecretKey,PublicKey};
use bitcoin::secp256k1::Secp256k1;
use bitcoin::{LockTime, secp256k1, Sequence};

use crate::blinded_path::BlindedPath;
use crate::chain;
use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
Expand Down Expand Up @@ -6353,6 +6354,10 @@ where
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
/// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer.
///
/// Uses [`Router::find_partial_paths`] to construct a [`BlindedPath`] for the offer. If one is
/// found, also uses a derived signing pubkey for recipient privacy. Otherwise, uses the node id
/// as the signing pubkey.
///
/// [`Offer`]: crate::offers::offer::Offer
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
pub fn create_offer_builder(
Expand All @@ -6362,16 +6367,26 @@ where
let expanded_key = &self.inbound_payment_key;
let entropy = &*self.entropy_source;
let secp_ctx = &self.secp_ctx;
let builder = OfferBuilder::deriving_signing_pubkey(
description, node_id, expanded_key, entropy, secp_ctx
);

// TODO: Set blinded paths
OfferBuilder::deriving_signing_pubkey(description, node_id, expanded_key, entropy, secp_ctx)
match self.create_blinded_paths(1) {
Ok(paths) if !paths.is_empty() => builder.path(paths.into_iter().next().unwrap()),
// TODO: check if node is public?
Ok(_) | Err(_) => builder,
}
}

/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
/// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
///
/// The provided `payment_id` is used to ensure that only one invoice is paid for the refund.
///
/// Uses [`Router::find_partial_paths`] to construct a [`BlindedPath`] for the refund. If one is
/// found, also uses a derived payer id for sender privacy. Otherwise, uses the node id as the
/// payer id.
///
/// [`Refund`]: crate::offers::refund::Refund
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
pub fn create_refund_builder(
Expand All @@ -6382,10 +6397,14 @@ where
let entropy = &*self.entropy_source;
let secp_ctx = &self.secp_ctx;

// TODO: Set blinded paths
let builder = RefundBuilder::deriving_payer_id(
description, node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
)?;
let builder = match self.create_blinded_paths(1) {
Ok(paths) if !paths.is_empty() => builder.path(paths.into_iter().next().unwrap()),
// TODO: check if node is public?
Ok(_) | Err(_) => builder,
};
self.pending_outbound_payments
.add_new_awaiting_invoice(payment_id)
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
Expand Down Expand Up @@ -6518,6 +6537,23 @@ where
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
}

///
fn create_blinded_paths(&self, count: usize) -> Result<Vec<BlindedPath>, ()> {
let last_hops = self.per_peer_state.read().unwrap().iter()
.filter(|(_, peer)| peer.lock().unwrap().latest_features.supports_route_blinding())
.map(|(node_id, _)| *node_id)
.collect::<Vec<_>>();
let entropy_source = self.entropy_source.deref();
let secp_ctx = &self.secp_ctx;

self.router
.find_partial_paths(self.get_our_node_id(), last_hops.as_slice())?
.into_iter()
.map(|node_pks| BlindedPath::new_for_message(&node_pks[..], entropy_source, secp_ctx))
.take(count)
.collect()
}

/// Gets a fake short channel id for use in receiving [phantom node payments]. These fake scids
/// are used when constructing the phantom invoice's route hints.
///
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/routing/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub trait Router {
&self, payer: &PublicKey, route_params: &RouteParameters,
first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs
) -> Result<Route, LightningError>;

/// Finds a [`Route`] for a payment between the given `payer` and a payee.
///
/// The `payee` and the payment's value are given in [`RouteParameters::payment_params`]
Expand All @@ -104,6 +105,17 @@ pub trait Router {
) -> Result<Route, LightningError> {
self.find_route(payer, route_params, first_hops, inflight_htlcs)
}

/// Finds partial paths to the `recipient` node for creating `BlindedPath`s. The nodes in
/// `peers` are assumed to be direct peers with the `recipient`.
///
/// The default implementation returns two-node paths for each node in `peers` with the
/// `recipient` node.
fn find_partial_paths(
&self, recipient: PublicKey, peers: &[PublicKey]
) -> Result<Vec<Vec<PublicKey>>, ()> {
Ok(peers.iter().map(|hop| vec![*hop, recipient]).collect())
}
}

/// [`Score`] implementation that factors in in-flight HTLC liquidity.
Expand Down

0 comments on commit acb28b9

Please sign in to comment.