@@ -358,6 +358,18 @@ impl Destination {
358
358
}
359
359
}
360
360
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
+
361
373
/// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
362
374
/// used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending
363
375
/// and
@@ -444,7 +456,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
444
456
}
445
457
446
458
/// 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 > {
448
460
let blinding_secret_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
449
461
let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
450
462
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>
457
469
}
458
470
} ;
459
471
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) ) ?;
461
474
let payloads = build_payloads ( intermediate_nodes, destination, encrypted_data_keys) ;
462
475
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
+
463
483
let prng_seed = self . keys_manager . get_secure_random_bytes ( ) ;
464
484
let onion_packet = onion_utils:: construct_onion_message_packet ( payloads, onion_packet_keys, prng_seed) ;
465
485
@@ -778,13 +798,13 @@ pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<InMemorySigner, &'a
778
798
mod tests {
779
799
use chain:: keysinterface:: { KeysInterface , Recipient } ;
780
800
use ln:: msgs:: OnionMessageHandler ;
781
- use onion_message:: { BlindedRoute , Destination , OnionMessenger } ;
801
+ use onion_message:: { BlindedRoute , Destination , OnionMessenger , SendError } ;
782
802
use util:: enforcing_trait_impls:: EnforcingSigner ;
783
803
use util:: events:: { MessageSendEvent , MessageSendEventsProvider } ;
784
804
use util:: test_utils;
785
805
786
806
use bitcoin:: network:: constants:: Network ;
787
- use bitcoin:: secp256k1:: { PublicKey , Secp256k1 } ;
807
+ use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
788
808
789
809
use sync:: Arc ;
790
810
@@ -877,4 +897,18 @@ mod tests {
877
897
node1. messenger . send_onion_message ( vec ! [ ] , Destination :: BlindedRoute ( blinded_route) ) . unwrap ( ) ;
878
898
pass_along_path ( vec ! [ & node1, & node2, & node3, & node4] , None ) ;
879
899
}
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
+ }
880
914
}
0 commit comments