Skip to content

Commit 408001c

Browse files
Make BlindedMessagePath creation infallible
The LDK codebase in general is comfortable panicking if the entropy source provided to it is dysfunctional. Up until now we made an exception for blinded path creation, where we would handle an error that could occur on mul_tweak that could only occur if the session_priv provided was not actually random. In comparable cases in onion_utils, we would panic instead. In upcoming commits, we will be including blinded paths in outbound revoke_and_ack messages as part of implementing async payments, where it is difficult to handle failing back an HTLC if blinded path creation fails. Thus we now have an incentive to make the blinded path creation methods infallible, so do so here.
1 parent b3f8ccf commit 408001c

File tree

7 files changed

+58
-94
lines changed

7 files changed

+58
-94
lines changed

lightning-dns-resolver/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,7 @@ mod test {
239239
context,
240240
&keys,
241241
secp_ctx,
242-
)
243-
.unwrap()])
242+
)])
244243
}
245244
}
246245
impl Deref for DirectlyConnectedRouter {
@@ -349,8 +348,7 @@ mod test {
349348
query_context,
350349
&*payer_keys,
351350
&secp_ctx,
352-
)
353-
.unwrap();
351+
);
354352
payer.pending_messages.lock().unwrap().push((
355353
DNSResolverMessage::DNSSECQuery(msg),
356354
MessageSendInstructions::WithSpecifiedReplyPath {

lightning/src/blinded_path/message.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,19 @@ impl BlindedMessagePath {
5757
pub fn one_hop<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
5858
recipient_node_id: PublicKey, local_node_receive_key: ReceiveAuthKey,
5959
context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>,
60-
) -> Result<Self, ()>
60+
) -> Self
6161
where
6262
ES::Target: EntropySource,
6363
{
6464
Self::new(&[], recipient_node_id, local_node_receive_key, context, entropy_source, secp_ctx)
6565
}
6666

67-
/// Create a path for an onion message, to be forwarded along `node_pks`. The last node
68-
/// pubkey in `node_pks` will be the destination node.
69-
///
70-
/// Errors if no hops are provided or if `node_pk`(s) are invalid.
71-
// TODO: make all payloads the same size with padding + add dummy hops
67+
/// Create a path for an onion message, to be forwarded along `node_pks`.
7268
pub fn new<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
7369
intermediate_nodes: &[MessageForwardNode], recipient_node_id: PublicKey,
7470
local_node_receive_key: ReceiveAuthKey, context: MessageContext, entropy_source: ES,
7571
secp_ctx: &Secp256k1<T>,
76-
) -> Result<Self, ()>
72+
) -> Self
7773
where
7874
ES::Target: EntropySource,
7975
{
@@ -96,7 +92,7 @@ impl BlindedMessagePath {
9692
intermediate_nodes: &[MessageForwardNode], recipient_node_id: PublicKey,
9793
dummy_hop_count: usize, local_node_receive_key: ReceiveAuthKey, context: MessageContext,
9894
entropy_source: ES, secp_ctx: &Secp256k1<T>,
99-
) -> Result<Self, ()>
95+
) -> Self
10096
where
10197
ES::Target: EntropySource,
10298
{
@@ -107,7 +103,7 @@ impl BlindedMessagePath {
107103
let blinding_secret =
108104
SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
109105

110-
Ok(Self(BlindedPath {
106+
Self(BlindedPath {
111107
introduction_node,
112108
blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
113109
blinded_hops: blinded_hops(
@@ -118,9 +114,8 @@ impl BlindedMessagePath {
118114
context,
119115
&blinding_secret,
120116
local_node_receive_key,
121-
)
122-
.map_err(|_| ())?,
123-
}))
117+
),
118+
})
124119
}
125120

126121
/// Attempts to a use a compact representation for the [`IntroductionNode`] by using a directed
@@ -669,7 +664,7 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
669664
secp_ctx: &Secp256k1<T>, intermediate_nodes: &[MessageForwardNode],
670665
recipient_node_id: PublicKey, dummy_hop_count: usize, context: MessageContext,
671666
session_priv: &SecretKey, local_node_receive_key: ReceiveAuthKey,
672-
) -> Result<Vec<BlindedHop>, secp256k1::Error> {
667+
) -> Vec<BlindedHop> {
673668
let dummy_count = cmp::min(dummy_hop_count, MAX_DUMMY_HOPS_COUNT);
674669
let pks = intermediate_nodes
675670
.iter()

lightning/src/blinded_path/payment.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ impl BlindedPaymentPath {
116116
/// Create a blinded path for a payment, to be forwarded along `intermediate_nodes`.
117117
///
118118
/// Errors if:
119-
/// * a provided node id is invalid
120119
/// * [`BlindedPayInfo`] calculation results in an integer overflow
121120
/// * any unknown features are required in the provided [`ForwardTlvs`]
122121
// TODO: make all payloads the same size with padding + add dummy hops
@@ -151,8 +150,7 @@ impl BlindedPaymentPath {
151150
payee_node_id,
152151
payee_tlvs,
153152
&blinding_secret,
154-
)
155-
.map_err(|_| ())?,
153+
),
156154
},
157155
payinfo: blinded_payinfo,
158156
})
@@ -663,7 +661,7 @@ pub(crate) const PAYMENT_PADDING_ROUND_OFF: usize = 30;
663661
pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
664662
secp_ctx: &Secp256k1<T>, intermediate_nodes: &[PaymentForwardNode], payee_node_id: PublicKey,
665663
payee_tlvs: ReceiveTlvs, session_priv: &SecretKey,
666-
) -> Result<Vec<BlindedHop>, secp256k1::Error> {
664+
) -> Vec<BlindedHop> {
667665
let pks = intermediate_nodes
668666
.iter()
669667
.map(|node| (node.node_id, None))

lightning/src/blinded_path/utils.rs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,8 @@ macro_rules! build_keys_helper {
5151
hmac.input(encrypted_data_ss.as_ref());
5252
Hmac::from_engine(hmac).to_byte_array()
5353
};
54-
pk.mul_tweak(
55-
$secp_ctx,
56-
&Scalar::from_be_bytes(hop_pk_blinding_factor).unwrap(),
57-
)?
54+
pk.mul_tweak($secp_ctx, &Scalar::from_be_bytes(hop_pk_blinding_factor).unwrap())
55+
.expect("RNG is busted")
5856
};
5957
let onion_packet_ss = SharedSecret::new(&blinded_hop_pk, &onion_packet_pubkey_priv);
6058

@@ -84,9 +82,9 @@ macro_rules! build_keys_helper {
8482
Sha256::from_engine(sha).to_byte_array()
8583
};
8684

87-
msg_blinding_point_priv = msg_blinding_point_priv.mul_tweak(
88-
&Scalar::from_be_bytes(msg_blinding_point_blinding_factor).unwrap(),
89-
)?;
85+
msg_blinding_point_priv = msg_blinding_point_priv
86+
.mul_tweak(&Scalar::from_be_bytes(msg_blinding_point_blinding_factor).unwrap())
87+
.expect("RNG is busted");
9088
msg_blinding_point =
9189
PublicKey::from_secret_key($secp_ctx, &msg_blinding_point_priv);
9290

@@ -96,9 +94,9 @@ macro_rules! build_keys_helper {
9694
sha.input(onion_packet_ss.as_ref());
9795
Sha256::from_engine(sha).to_byte_array()
9896
};
99-
onion_packet_pubkey_priv = onion_packet_pubkey_priv.mul_tweak(
100-
&Scalar::from_be_bytes(onion_packet_pubkey_blinding_factor).unwrap(),
101-
)?;
97+
onion_packet_pubkey_priv = onion_packet_pubkey_priv
98+
.mul_tweak(&Scalar::from_be_bytes(onion_packet_pubkey_blinding_factor).unwrap())
99+
.expect("RNG is busted");
102100
onion_packet_pubkey =
103101
PublicKey::from_secret_key($secp_ctx, &onion_packet_pubkey_priv);
104102
};
@@ -109,8 +107,7 @@ macro_rules! build_keys_helper {
109107
pub(crate) fn construct_keys_for_onion_message<'a, T, I, F>(
110108
secp_ctx: &Secp256k1<T>, unblinded_path: I, destination: Destination, session_priv: &SecretKey,
111109
mut callback: F,
112-
) -> Result<(), secp256k1::Error>
113-
where
110+
) where
114111
T: secp256k1::Signing + secp256k1::Verification,
115112
I: Iterator<Item = PublicKey>,
116113
F: FnMut(SharedSecret, PublicKey, [u8; 32], Option<PublicKey>, Option<Vec<u8>>),
@@ -134,13 +131,11 @@ where
134131
}
135132
},
136133
}
137-
Ok(())
138134
}
139135

140136
fn construct_keys_for_blinded_path<'a, T, I, F, H>(
141137
secp_ctx: &Secp256k1<T>, unblinded_path: I, session_priv: &SecretKey, mut callback: F,
142-
) -> Result<(), secp256k1::Error>
143-
where
138+
) where
144139
T: secp256k1::Signing + secp256k1::Verification,
145140
H: Borrow<PublicKey>,
146141
I: Iterator<Item = H>,
@@ -151,7 +146,6 @@ where
151146
for pk in unblinded_path {
152147
build_keys_in_loop!(pk, false, None);
153148
}
154-
Ok(())
155149
}
156150

157151
struct PublicKeyWithTlvs<W: Writeable> {
@@ -168,7 +162,7 @@ impl<W: Writeable> Borrow<PublicKey> for PublicKeyWithTlvs<W> {
168162

169163
pub(crate) fn construct_blinded_hops<'a, T, I, W>(
170164
secp_ctx: &Secp256k1<T>, unblinded_path: I, session_priv: &SecretKey,
171-
) -> Result<Vec<BlindedHop>, secp256k1::Error>
165+
) -> Vec<BlindedHop>
172166
where
173167
T: secp256k1::Signing + secp256k1::Verification,
174168
I: Iterator<Item = ((PublicKey, Option<ReceiveAuthKey>), W)>,
@@ -194,8 +188,8 @@ where
194188
),
195189
});
196190
},
197-
)?;
198-
Ok(blinded_hops)
191+
);
192+
blinded_hops
199193
}
200194

201195
/// Encrypt TLV payload to be used as a [`crate::blinded_path::BlindedHop::encrypted_payload`].

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ fn route_blinding_spec_test_vector() {
15521552
];
15531553
let mut dave_eve_blinded_hops = blinded_path::utils::construct_blinded_hops(
15541554
&secp_ctx, path.into_iter(), &dave_eve_session_priv,
1555-
).unwrap();
1555+
);
15561556

15571557
// Concatenate an additional Bob -> Carol blinded path to the Eve -> Dave blinded path.
15581558
let bob_carol_session_priv = secret_from_hex("0202020202020202020202020202020202020202020202020202020202020202");
@@ -1563,7 +1563,7 @@ fn route_blinding_spec_test_vector() {
15631563
];
15641564
let bob_carol_blinded_hops = blinded_path::utils::construct_blinded_hops(
15651565
&secp_ctx, path.into_iter(), &bob_carol_session_priv,
1566-
).unwrap();
1566+
);
15671567

15681568
let mut blinded_hops = bob_carol_blinded_hops;
15691569
blinded_hops.append(&mut dave_eve_blinded_hops);
@@ -2030,7 +2030,7 @@ fn do_test_trampoline_single_hop_receive(success: bool) {
20302030
let path = [((carol_node_id, None), WithoutLength(&carol_unblinded_tlvs))];
20312031
blinded_path::utils::construct_blinded_hops(
20322032
&secp_ctx, path.into_iter(), &carol_alice_trampoline_session_priv,
2033-
).unwrap()
2033+
)
20342034
} else {
20352035
let payee_tlvs = blinded_path::payment::TrampolineForwardTlvs {
20362036
next_trampoline: alice_node_id,
@@ -2051,7 +2051,7 @@ fn do_test_trampoline_single_hop_receive(success: bool) {
20512051
let path = [((carol_node_id, None), WithoutLength(&carol_unblinded_tlvs))];
20522052
blinded_path::utils::construct_blinded_hops(
20532053
&secp_ctx, path.into_iter(), &carol_alice_trampoline_session_priv,
2054-
).unwrap()
2054+
)
20552055
};
20562056

20572057
let route = Route {
@@ -2255,7 +2255,7 @@ fn test_trampoline_unblinded_receive() {
22552255
let carol_blinding_point = PublicKey::from_secret_key(&secp_ctx, &carol_alice_trampoline_session_priv);
22562256
let carol_blinded_hops = blinded_path::utils::construct_blinded_hops(
22572257
&secp_ctx, path.into_iter(), &carol_alice_trampoline_session_priv,
2258-
).unwrap();
2258+
);
22592259

22602260
let route = Route {
22612261
paths: vec![Path {

0 commit comments

Comments
 (0)