Skip to content

Commit

Permalink
Fuzz test blinded payment pathfinding
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinewallace committed Jul 25, 2023
1 parent 9bf4b6e commit a35b92c
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
45 changes: 44 additions & 1 deletion fuzz/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ use bitcoin::blockdata::script::Builder;
use bitcoin::blockdata::transaction::TxOut;
use bitcoin::hash_types::BlockHash;

use lightning::blinded_path::{BlindedHop, BlindedPath};
use lightning::chain::transaction::OutPoint;
use lightning::ln::channelmanager::{self, ChannelDetails, ChannelCounterparty};
use lightning::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
use lightning::ln::msgs;
use lightning::offers::invoice::BlindedPayInfo;
use lightning::routing::gossip::{NetworkGraph, RoutingFees};
use lightning::routing::utxo::{UtxoFuture, UtxoLookup, UtxoLookupError, UtxoResult};
use lightning::routing::router::{find_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters};
Expand Down Expand Up @@ -315,7 +318,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
net_graph.channel_failed_permanent(short_channel_id);
},
_ if node_pks.is_empty() => {},
_ => {
x if x < 250 => {
let mut first_hops_vec = Vec::new();
// Use macros here and in the blinded match arm to ensure values are fetched from the fuzz
// input in the same order, for better coverage.
Expand All @@ -330,6 +333,46 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
}
});
},
x => {
let mut first_hops_vec = Vec::new();
let first_hops = first_hops!(first_hops_vec);
let mut last_hops_unblinded = Vec::new();
last_hops!(last_hops_unblinded);
let dummy_pk = PublicKey::from_slice(&[2; 33]).unwrap();
let last_hops: Vec<(BlindedPayInfo, BlindedPath)> = last_hops_unblinded.into_iter().map(|hint| {
let hop = &hint.0[0];
let payinfo = BlindedPayInfo {
fee_base_msat: hop.fees.base_msat,
fee_proportional_millionths: hop.fees.proportional_millionths,
htlc_minimum_msat: hop.htlc_minimum_msat.unwrap(),
htlc_maximum_msat: hop.htlc_minimum_msat.unwrap().saturating_mul(100),
cltv_expiry_delta: hop.cltv_expiry_delta,
features: BlindedHopFeatures::empty(),
};
let num_blinded_hops = x % 250;
let mut blinded_hops = Vec::new();
for _ in 0..num_blinded_hops {
blinded_hops.push(BlindedHop {
blinded_node_id: dummy_pk,
encrypted_payload: Vec::new()
});
}
(payinfo, BlindedPath {
introduction_node_id: hop.src_node_id,
blinding_point: dummy_pk,
blinded_hops,
})
}).collect();
let mut features = Bolt12InvoiceFeatures::empty();
features.set_basic_mpp_optional();
find_routes!(first_hops, vec![dummy_pk].iter(), |final_amt, _, _| {
RouteParameters {
payment_params: PaymentParameters::blinded(last_hops.clone())
.with_bolt12_features(features.clone()).unwrap(),
final_value_msat: final_amt,
}
});
}
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions lightning/src/blinded_path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,26 @@ pub struct BlindedPath {
/// message or payment's next hop and forward it along.
///
/// [`encrypted_payload`]: BlindedHop::encrypted_payload
pub(crate) introduction_node_id: PublicKey,
pub introduction_node_id: PublicKey,
/// Used by the introduction node to decrypt its [`encrypted_payload`] to forward the onion
/// message or payment.
///
/// [`encrypted_payload`]: BlindedHop::encrypted_payload
pub(crate) blinding_point: PublicKey,
pub blinding_point: PublicKey,
/// The hops composing the blinded path.
pub(crate) blinded_hops: Vec<BlindedHop>,
pub blinded_hops: Vec<BlindedHop>,
}

/// Used to construct the blinded hops portion of a blinded path. These hops cannot be identified
/// by outside observers and thus can be used to hide the identity of the recipient.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BlindedHop {
/// The blinded node id of this hop in a blinded path.
pub(crate) blinded_node_id: PublicKey,
pub blinded_node_id: PublicKey,
/// The encrypted payload intended for this hop in a blinded path.
// The node sending to this blinded path will later encode this payload into the onion packet for
// this hop.
pub(crate) encrypted_payload: Vec<u8>,
pub encrypted_payload: Vec<u8>,
}

impl BlindedPath {
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/routing/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,8 @@ impl PaymentParameters {
.with_expiry_time(invoice.created_at().as_secs().saturating_add(invoice.relative_expiry().as_secs()))
}

fn blinded(blinded_route_hints: Vec<(BlindedPayInfo, BlindedPath)>) -> Self {
/// Creates parameters for paying to a blinded payee from the provided blinded route hints.
pub fn blinded(blinded_route_hints: Vec<(BlindedPayInfo, BlindedPath)>) -> Self {
Self {
payee: Payee::Blinded { route_hints: blinded_route_hints, features: None },
expiry_time: None,
Expand Down

0 comments on commit a35b92c

Please sign in to comment.