Skip to content

Commit ef40c7e

Browse files
Move BlindedPayInfo into BlindedPaymentPath.
Also removes the implementation of Writeable for BlindedPaymentPath, to ensure callsites are explicit about what they're writing.
1 parent bad5e32 commit ef40c7e

20 files changed

+272
-259
lines changed

fuzz/src/chanmon_consistency.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use lightning::ln::msgs::{
5656
};
5757
use lightning::ln::script::ShutdownScript;
5858
use lightning::ln::types::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};
59-
use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice};
59+
use lightning::offers::invoice::UnsignedBolt12Invoice;
6060
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
6161
use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
6262
use lightning::routing::router::{InFlightHtlcs, Path, Route, RouteHop, RouteParameters, Router};
@@ -126,7 +126,7 @@ impl Router for FuzzRouter {
126126
fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
127127
&self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
128128
_amount_msats: u64, _secp_ctx: &Secp256k1<T>,
129-
) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
129+
) -> Result<Vec<BlindedPaymentPath>, ()> {
130130
unreachable!()
131131
}
132132
}

fuzz/src/full_stack.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use lightning::ln::peer_handler::{
4949
};
5050
use lightning::ln::script::ShutdownScript;
5151
use lightning::ln::types::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};
52-
use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice};
52+
use lightning::offers::invoice::UnsignedBolt12Invoice;
5353
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
5454
use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
5555
use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
@@ -163,7 +163,7 @@ impl Router for FuzzRouter {
163163
fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
164164
&self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
165165
_amount_msats: u64, _secp_ctx: &Secp256k1<T>,
166-
) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
166+
) -> Result<Vec<BlindedPaymentPath>, ()> {
167167
unreachable!()
168168
}
169169
}

fuzz/src/router.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
381381
let mut last_hops_unblinded = Vec::new();
382382
last_hops!(last_hops_unblinded);
383383
let dummy_pk = PublicKey::from_slice(&[2; 33]).unwrap();
384-
let last_hops: Vec<(BlindedPayInfo, BlindedPaymentPath)> = last_hops_unblinded
384+
let last_hops: Vec<BlindedPaymentPath> = last_hops_unblinded
385385
.into_iter()
386386
.map(|hint| {
387387
let hop = &hint.0[0];
@@ -401,10 +401,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
401401
encrypted_payload: Vec::new(),
402402
});
403403
}
404-
(
405-
payinfo,
406-
BlindedPaymentPath::from_raw(hop.src_node_id, dummy_pk, blinded_hops),
407-
)
404+
BlindedPaymentPath::from_raw(hop.src_node_id, dummy_pk, blinded_hops, payinfo)
408405
})
409406
.collect();
410407
let mut features = Bolt12InvoiceFeatures::empty();

lightning/src/blinded_path/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::prelude::*;
2626
/// Onion messages and payments can be sent and received to blinded paths, which serve to hide the
2727
/// identity of the recipient.
2828
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
29-
struct BlindedPath {
29+
pub(crate) struct BlindedPath {
3030
/// To send to a blinded path, the sender first finds a route to the unblinded
3131
/// `introduction_node`, which can unblind its [`encrypted_payload`] to find out the onion
3232
/// message or payment's next hop and forward it along.

lightning/src/blinded_path/payment.rs

+45-38
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,18 @@ use crate::prelude::*;
3737
/// A blinded path to be used for sending or receiving a payment, hiding the identity of the
3838
/// recipient.
3939
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
40-
pub struct BlindedPaymentPath(pub(super) BlindedPath);
41-
42-
impl Writeable for BlindedPaymentPath {
43-
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
44-
self.0.write(w)
45-
}
46-
}
47-
48-
impl Readable for BlindedPaymentPath {
49-
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
50-
Ok(Self(BlindedPath::read(r)?))
51-
}
40+
pub struct BlindedPaymentPath {
41+
pub(super) inner_path: BlindedPath,
42+
/// The [`BlindedPayInfo`] used to pay this blinded path.
43+
pub payinfo: BlindedPayInfo,
5244
}
5345

5446
impl BlindedPaymentPath {
5547
/// Create a one-hop blinded path for a payment.
5648
pub fn one_hop<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
5749
payee_node_id: PublicKey, payee_tlvs: ReceiveTlvs, min_final_cltv_expiry_delta: u16,
5850
entropy_source: ES, secp_ctx: &Secp256k1<T>
59-
) -> Result<(BlindedPayInfo, Self), ()> where ES::Target: EntropySource {
51+
) -> Result<Self, ()> where ES::Target: EntropySource {
6052
// This value is not considered in pathfinding for 1-hop blinded paths, because it's intended to
6153
// be in relation to a specific channel.
6254
let htlc_maximum_msat = u64::max_value();
@@ -77,7 +69,7 @@ impl BlindedPaymentPath {
7769
intermediate_nodes: &[ForwardNode], payee_node_id: PublicKey, payee_tlvs: ReceiveTlvs,
7870
htlc_maximum_msat: u64, min_final_cltv_expiry_delta: u16, entropy_source: ES,
7971
secp_ctx: &Secp256k1<T>
80-
) -> Result<(BlindedPayInfo, Self), ()> where ES::Target: EntropySource {
72+
) -> Result<Self, ()> where ES::Target: EntropySource {
8173
let introduction_node = IntroductionNode::NodeId(
8274
intermediate_nodes.first().map_or(payee_node_id, |n| n.node_id)
8375
);
@@ -87,38 +79,41 @@ impl BlindedPaymentPath {
8779
let blinded_payinfo = compute_payinfo(
8880
intermediate_nodes, &payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta
8981
)?;
90-
Ok((blinded_payinfo, Self(BlindedPath {
91-
introduction_node,
92-
blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
93-
blinded_hops: blinded_hops(
94-
secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, &blinding_secret
95-
).map_err(|_| ())?,
96-
})))
82+
Ok(Self {
83+
inner_path: BlindedPath {
84+
introduction_node,
85+
blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
86+
blinded_hops: blinded_hops(
87+
secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, &blinding_secret
88+
).map_err(|_| ())?,
89+
},
90+
payinfo: blinded_payinfo
91+
})
9792
}
9893

9994
/// Returns the introduction [`NodeId`] of the blinded path, if it is publicly reachable (i.e.,
10095
/// it is found in the network graph).
10196
pub fn public_introduction_node_id<'a>(
10297
&self, network_graph: &'a ReadOnlyNetworkGraph
10398
) -> Option<&'a NodeId> {
104-
self.0.public_introduction_node_id(network_graph)
99+
self.inner_path.public_introduction_node_id(network_graph)
105100
}
106101

107102
/// The [`IntroductionNode`] of the blinded path.
108103
pub fn introduction_node(&self) -> &IntroductionNode {
109-
&self.0.introduction_node
104+
&self.inner_path.introduction_node
110105
}
111106

112107
/// Used by the [`IntroductionNode`] to decrypt its [`encrypted_payload`] to forward the payment.
113108
///
114109
/// [`encrypted_payload`]: BlindedHop::encrypted_payload
115110
pub fn blinding_point(&self) -> PublicKey {
116-
self.0.blinding_point
111+
self.inner_path.blinding_point
117112
}
118113

119114
/// The [`BlindedHop`]s within the blinded path.
120115
pub fn blinded_hops(&self) -> &[BlindedHop] {
121-
&self.0.blinded_hops
116+
&self.inner_path.blinded_hops
122117
}
123118

124119
/// Advance the blinded onion payment path by one hop, making the second hop into the new
@@ -133,9 +128,9 @@ impl BlindedPaymentPath {
133128
NL::Target: NodeIdLookUp,
134129
T: secp256k1::Signing + secp256k1::Verification,
135130
{
136-
let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &self.0.blinding_point, None)?;
131+
let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &self.inner_path.blinding_point, None)?;
137132
let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());
138-
let encrypted_control_tlvs = &self.0.blinded_hops.get(0).ok_or(())?.encrypted_payload;
133+
let encrypted_control_tlvs = &self.inner_path.blinded_hops.get(0).ok_or(())?.encrypted_payload;
139134
let mut s = Cursor::new(encrypted_control_tlvs);
140135
let mut reader = FixedLengthReader::new(&mut s, encrypted_control_tlvs.len() as u64);
141136
match ChaChaPolyReadAdapter::read(&mut reader, rho) {
@@ -147,31 +142,43 @@ impl BlindedPaymentPath {
147142
None => return Err(()),
148143
};
149144
let mut new_blinding_point = onion_utils::next_hop_pubkey(
150-
secp_ctx, self.0.blinding_point, control_tlvs_ss.as_ref()
145+
secp_ctx, self.inner_path.blinding_point, control_tlvs_ss.as_ref()
151146
).map_err(|_| ())?;
152-
mem::swap(&mut self.0.blinding_point, &mut new_blinding_point);
153-
self.0.introduction_node = IntroductionNode::NodeId(next_node_id);
154-
self.0.blinded_hops.remove(0);
147+
mem::swap(&mut self.inner_path.blinding_point, &mut new_blinding_point);
148+
self.inner_path.introduction_node = IntroductionNode::NodeId(next_node_id);
149+
self.inner_path.blinded_hops.remove(0);
155150
Ok(())
156151
},
157152
_ => Err(())
158153
}
159154
}
160155

156+
pub(crate) fn inner_blinded_path(&self) -> &BlindedPath {
157+
&self.inner_path
158+
}
159+
160+
pub(crate) fn from_parts(inner_path: BlindedPath, payinfo: BlindedPayInfo) -> Self {
161+
Self { inner_path, payinfo }
162+
}
163+
161164
#[cfg(any(test, fuzzing))]
162165
pub fn from_raw(
163-
introduction_node_id: PublicKey, blinding_point: PublicKey, blinded_hops: Vec<BlindedHop>
166+
introduction_node_id: PublicKey, blinding_point: PublicKey, blinded_hops: Vec<BlindedHop>,
167+
payinfo: BlindedPayInfo
164168
) -> Self {
165-
Self(BlindedPath {
166-
introduction_node: IntroductionNode::NodeId(introduction_node_id),
167-
blinding_point,
168-
blinded_hops,
169-
})
169+
Self {
170+
inner_path: BlindedPath {
171+
introduction_node: IntroductionNode::NodeId(introduction_node_id),
172+
blinding_point,
173+
blinded_hops,
174+
},
175+
payinfo
176+
}
170177
}
171178

172179
#[cfg(test)]
173180
pub fn clear_blinded_hops(&mut self) {
174-
self.0.blinded_hops.clear()
181+
self.inner_path.blinded_hops.clear()
175182
}
176183
}
177184

lightning/src/ln/blinded_payment_tests.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use crate::ln::msgs::ChannelMessageHandler;
2020
use crate::ln::onion_utils;
2121
use crate::ln::onion_utils::INVALID_ONION_BLINDING;
2222
use crate::ln::outbound_payment::{Retry, IDEMPOTENCY_TIMEOUT_TICKS};
23-
use crate::offers::invoice::BlindedPayInfo;
2423
use crate::prelude::*;
2524
use crate::routing::router::{Payee, PaymentParameters, RouteParameters};
2625
use crate::util::config::UserConfig;
@@ -30,7 +29,7 @@ fn blinded_payment_path(
3029
payment_secret: PaymentSecret, intro_node_min_htlc: u64, intro_node_max_htlc: u64,
3130
node_ids: Vec<PublicKey>, channel_upds: &[&msgs::UnsignedChannelUpdate],
3231
keys_manager: &test_utils::TestKeysInterface
33-
) -> (BlindedPayInfo, BlindedPaymentPath) {
32+
) -> BlindedPaymentPath {
3433
let mut intermediate_nodes = Vec::new();
3534
let mut intro_node_min_htlc_opt = Some(intro_node_min_htlc);
3635
let mut intro_node_max_htlc_opt = Some(intro_node_max_htlc);
@@ -829,11 +828,12 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
829828
nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(), &[&high_htlc_minimum_upd],
830829
&chanmon_cfgs[2].keys_manager);
831830
if let Payee::Blinded { route_hints, .. } = high_htlc_min_params.payment_params.payee {
832-
route_hints[0].1.clone()
831+
route_hints[0].clone()
833832
} else { panic!() }
834833
};
835834
if let Payee::Blinded { ref mut route_hints, .. } = route_params.payment_params.payee {
836-
route_hints[0].1 = high_htlc_min_bp;
835+
route_hints[0] = high_htlc_min_bp;
836+
route_hints[0].payinfo.htlc_minimum_msat = amt_msat;
837837
} else { panic!() }
838838
find_route(&nodes[0], &route_params).unwrap()
839839
} else {
@@ -1111,7 +1111,7 @@ fn min_htlc() {
11111111
nodes[2].node.get_our_node_id(), nodes[3].node.get_our_node_id()],
11121112
&[&chan_1_2.0.contents, &chan_2_3.0.contents], &chanmon_cfgs[3].keys_manager);
11131113
assert_eq!(min_htlc_msat,
1114-
route_params.payment_params.payee.blinded_route_hints()[0].0.htlc_minimum_msat);
1114+
route_params.payment_params.payee.blinded_route_hints()[0].payinfo.htlc_minimum_msat);
11151115

11161116
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0), route_params.clone(), Retry::Attempts(0)).unwrap();
11171117
check_added_monitors(&nodes[0], 1);
@@ -1123,7 +1123,7 @@ fn min_htlc() {
11231123
nodes[0].node.timer_tick_occurred();
11241124
}
11251125
if let Payee::Blinded { ref mut route_hints, .. } = route_params.payment_params.payee {
1126-
route_hints[0].0.htlc_minimum_msat -= 1;
1126+
route_hints[0].payinfo.htlc_minimum_msat -= 1;
11271127
} else { panic!() }
11281128
route_params.final_value_msat -= 1;
11291129
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
6262
use crate::ln::outbound_payment;
6363
use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs, StaleExpiration};
6464
use crate::ln::wire::Encode;
65-
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
65+
use crate::offers::invoice::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
6666
use crate::offers::invoice_error::InvoiceError;
6767
use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
6868
use crate::offers::nonce::Nonce;
@@ -9367,7 +9367,7 @@ where
93679367
/// [`Router::create_blinded_payment_paths`].
93689368
fn create_blinded_payment_paths(
93699369
&self, amount_msats: u64, payment_secret: PaymentSecret, payment_context: PaymentContext
9370-
) -> Result<Vec<(BlindedPayInfo, BlindedPaymentPath)>, ()> {
9370+
) -> Result<Vec<BlindedPaymentPath>, ()> {
93719371
let secp_ctx = &self.secp_ctx;
93729372

93739373
let first_hops = self.list_usable_channels();

lightning/src/ln/max_payment_path_len_tests.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ fn one_hop_blinded_path_with_custom_tlv() {
182182
sender_intended_htlc_amt_msat: MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
183183
total_msat: MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
184184
cltv_expiry_height: nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
185-
encrypted_tlvs: &blinded_path.1.blinded_hops()[0].encrypted_payload,
186-
intro_node_blinding_point: Some(blinded_path.1.blinding_point()),
185+
encrypted_tlvs: &blinded_path.blinded_hops()[0].encrypted_payload,
186+
intro_node_blinding_point: Some(blinded_path.blinding_point()),
187187
keysend_preimage: None,
188188
custom_tlvs: &Vec::new()
189189
}.serialized_length();
@@ -354,15 +354,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
354354
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
355355
create_announced_chan_between_nodes(&nodes, 0, 1);
356356

357-
nodes[1].router.expect_blinded_payment_paths(vec![(
358-
BlindedPayInfo {
359-
fee_base_msat: 42,
360-
fee_proportional_millionths: 42,
361-
cltv_expiry_delta: 42,
362-
htlc_minimum_msat: 42,
363-
htlc_maximum_msat: 42_000_000,
364-
features: BlindedHopFeatures::empty(),
365-
},
357+
nodes[1].router.expect_blinded_payment_paths(vec![
366358
BlindedPaymentPath::from_raw(
367359
PublicKey::from_slice(&[2; 33]).unwrap(), PublicKey::from_slice(&[2; 33]).unwrap(),
368360
vec![
@@ -374,9 +366,17 @@ fn bolt12_invoice_too_large_blinded_paths() {
374366
blinded_node_id: PublicKey::from_slice(&[2; 33]).unwrap(),
375367
encrypted_payload: vec![42; 1300],
376368
},
377-
]
369+
],
370+
BlindedPayInfo {
371+
fee_base_msat: 42,
372+
fee_proportional_millionths: 42,
373+
cltv_expiry_delta: 42,
374+
htlc_minimum_msat: 42,
375+
htlc_maximum_msat: 42_000_000,
376+
features: BlindedHopFeatures::empty(),
377+
}
378378
)
379-
)]);
379+
]);
380380

381381
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
382382
let payment_id = PaymentId([1; 32]);

0 commit comments

Comments
 (0)