Skip to content

Commit 220b3d9

Browse files
Add SendError enum for onion messages and error on too-big packets
1 parent 9ff0e82 commit 220b3d9

File tree

1 file changed

+38
-4
lines changed
  • lightning/src/onion_message

1 file changed

+38
-4
lines changed

lightning/src/onion_message/mod.rs

+38-4
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ impl Destination {
136136
}
137137
}
138138

139+
/// Errors that may occur when [sending an onion message].
140+
///
141+
/// [sending an onion message]: OnionMessenger::send_onion_message
142+
#[derive(Debug, PartialEq)]
143+
pub enum SendError {
144+
/// Errored computing onion message packet keys.
145+
Secp256k1(secp256k1::Error),
146+
/// Because implementations such as Eclair will drop onion messages where the message packet
147+
/// exceeds 32834 bytes, we refuse to send messages where the packet exceeds this size.
148+
TooBigPacket,
149+
}
150+
139151
impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
140152
where K::Target: KeysInterface<Signer = Signer>,
141153
L::Target: Logger,
@@ -154,7 +166,7 @@ where K::Target: KeysInterface<Signer = Signer>,
154166
}
155167

156168
/// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
157-
pub fn send_onion_message(&self, intermediate_nodes: Vec<PublicKey>, destination: Destination) -> Result<(), secp256k1::Error> {
169+
pub fn send_onion_message(&self, intermediate_nodes: Vec<PublicKey>, destination: Destination) -> Result<(), SendError> {
158170
let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes();
159171
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
160172
let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
@@ -167,9 +179,17 @@ where K::Target: KeysInterface<Signer = Signer>,
167179
}
168180
};
169181
let (encrypted_data_keys, onion_packet_keys) = utils::construct_sending_keys(
170-
&self.secp_ctx, &intermediate_nodes, &destination, &blinding_secret)?;
182+
&self.secp_ctx, &intermediate_nodes, &destination, &blinding_secret)
183+
.map_err(|e| SendError::Secp256k1(e))?;
171184
let payloads = utils::build_payloads(intermediate_nodes, destination, encrypted_data_keys);
172185

186+
// Check whether the onion message is too big to send.
187+
let payloads_serialized_len = payloads.iter()
188+
.fold(0, |total, next_payload| total + next_payload.serialized_length() + 32 /* HMAC */ );
189+
if payloads_serialized_len > BIG_PACKET_HOP_DATA_LEN {
190+
return Err(SendError::TooBigPacket)
191+
}
192+
173193
let prng_seed = self.keys_manager.get_secure_random_bytes();
174194
let onion_packet = onion_utils::construct_onion_message_packet(payloads, onion_packet_keys, prng_seed);
175195

@@ -453,13 +473,13 @@ pub(crate) enum EncryptedTlvs {
453473
mod tests {
454474
use chain::keysinterface::{KeysInterface, Recipient};
455475
use ln::msgs::OnionMessageHandler;
456-
use onion_message::{BlindedRoute, Destination, OnionMessenger};
476+
use onion_message::{BlindedRoute, Destination, OnionMessenger, SendError};
457477
use util::enforcing_trait_impls::EnforcingSigner;
458478
use util::events::{MessageSendEvent, MessageSendEventsProvider};
459479
use util::test_utils;
460480

461481
use bitcoin::network::constants::Network;
462-
use bitcoin::secp256k1::{PublicKey, Secp256k1};
482+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
463483

464484
use sync::Arc;
465485

@@ -552,4 +572,18 @@ mod tests {
552572
node1.messenger.send_onion_message(vec![], Destination::BlindedRoute(blinded_route)).unwrap();
553573
pass_along_path(vec![&node1, &node2, &node3, &node4], None);
554574
}
575+
576+
#[test]
577+
fn too_big_packet_error() {
578+
// Make sure we error as expected if a packet is too big to send.
579+
let nodes = create_nodes(1);
580+
581+
let hop_secret = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
582+
let secp_ctx = Secp256k1::new();
583+
let hop_node_id = PublicKey::from_secret_key(&secp_ctx, &hop_secret);
584+
585+
let hops = vec![hop_node_id.clone(); 400];
586+
let err = nodes[0].messenger.send_onion_message(hops, Destination::Node(hop_node_id)).unwrap_err();
587+
assert_eq!(err, SendError::TooBigPacket);
588+
}
555589
}

0 commit comments

Comments
 (0)