Skip to content

Commit 23ad1f1

Browse files
Add SendError enum for onion messages and error on too-big packets
1 parent 6c2f45c commit 23ad1f1

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

lightning/src/onion_message.rs

+38-4
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,18 @@ impl Destination {
358358
}
359359
}
360360

361+
/// Errors that may occur when [sending an onion message].
362+
///
363+
/// [sending an onion message]: OnionMessenger::send_onion_message
364+
#[derive(Debug, PartialEq)]
365+
pub enum SendError {
366+
/// Errored computing onion message packet keys.
367+
Secp256k1(secp256k1::Error),
368+
/// Because implementations such as Eclair will drop onion messages where the message packet
369+
/// exceeds 32834 bytes, we refuse to send messages where the packet exceeds this size.
370+
TooBigPacket,
371+
}
372+
361373
/// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
362374
/// used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending
363375
/// and
@@ -444,7 +456,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
444456
}
445457

446458
/// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
447-
pub fn send_onion_message(&self, intermediate_nodes: Vec<PublicKey>, destination: Destination) -> Result<(), secp256k1::Error> {
459+
pub fn send_onion_message(&self, intermediate_nodes: Vec<PublicKey>, destination: Destination) -> Result<(), SendError> {
448460
let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes();
449461
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
450462
let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
@@ -457,9 +469,17 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
457469
}
458470
};
459471
let (encrypted_data_keys, onion_packet_keys) = construct_sending_keys(
460-
&self.secp_ctx, &intermediate_nodes, &destination, &blinding_secret)?;
472+
&self.secp_ctx, &intermediate_nodes, &destination, &blinding_secret)
473+
.map_err(|e| SendError::Secp256k1(e))?;
461474
let payloads = build_payloads(intermediate_nodes, destination, encrypted_data_keys);
462475

476+
// Check whether the onion message is too big to send.
477+
let payloads_serialized_len = payloads.iter()
478+
.fold(0, |total, next_payload| total + next_payload.serialized_length() + 32 /* HMAC */ );
479+
if payloads_serialized_len > BIG_PACKET_HOP_DATA_LEN {
480+
return Err(SendError::TooBigPacket)
481+
}
482+
463483
let prng_seed = self.keys_manager.get_secure_random_bytes();
464484
let onion_packet = onion_utils::construct_onion_message_packet(payloads, onion_packet_keys, prng_seed);
465485

@@ -778,13 +798,13 @@ pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<InMemorySigner, &'a
778798
mod tests {
779799
use chain::keysinterface::{KeysInterface, Recipient};
780800
use ln::msgs::OnionMessageHandler;
781-
use onion_message::{BlindedRoute, Destination, OnionMessenger};
801+
use onion_message::{BlindedRoute, Destination, OnionMessenger, SendError};
782802
use util::enforcing_trait_impls::EnforcingSigner;
783803
use util::events::{MessageSendEvent, MessageSendEventsProvider};
784804
use util::test_utils;
785805

786806
use bitcoin::network::constants::Network;
787-
use bitcoin::secp256k1::{PublicKey, Secp256k1};
807+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
788808

789809
use sync::Arc;
790810

@@ -877,4 +897,18 @@ mod tests {
877897
node1.messenger.send_onion_message(vec![], Destination::BlindedRoute(blinded_route)).unwrap();
878898
pass_along_path(vec![&node1, &node2, &node3, &node4], None);
879899
}
900+
901+
#[test]
902+
fn too_big_packet_error() {
903+
// Make sure we error as expected if a packet is too big to send.
904+
let nodes = create_nodes(1);
905+
906+
let hop_secret = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
907+
let secp_ctx = Secp256k1::new();
908+
let hop_node_id = PublicKey::from_secret_key(&secp_ctx, &hop_secret);
909+
910+
let hops = vec![hop_node_id.clone(); 400];
911+
let err = nodes[0].messenger.send_onion_message(hops, Destination::Node(hop_node_id)).unwrap_err();
912+
assert_eq!(err, SendError::TooBigPacket);
913+
}
880914
}

0 commit comments

Comments
 (0)