@@ -136,6 +136,18 @@ impl Destination {
136
136
}
137
137
}
138
138
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
+
139
151
impl < Signer : Sign , K : Deref , L : Deref > OnionMessenger < Signer , K , L >
140
152
where K :: Target : KeysInterface < Signer = Signer > ,
141
153
L :: Target : Logger ,
@@ -154,7 +166,7 @@ where K::Target: KeysInterface<Signer = Signer>,
154
166
}
155
167
156
168
/// 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 > {
158
170
let blinding_secret_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
159
171
let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
160
172
let ( introduction_node_id, blinding_point) = if intermediate_nodes. len ( ) != 0 {
@@ -167,9 +179,17 @@ where K::Target: KeysInterface<Signer = Signer>,
167
179
}
168
180
} ;
169
181
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) ) ?;
171
184
let payloads = utils:: build_payloads ( intermediate_nodes, destination, encrypted_data_keys) ;
172
185
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
+
173
193
let prng_seed = self . keys_manager . get_secure_random_bytes ( ) ;
174
194
let onion_packet = onion_utils:: construct_onion_message_packet ( payloads, onion_packet_keys, prng_seed) ;
175
195
@@ -453,13 +473,13 @@ pub(crate) enum EncryptedTlvs {
453
473
mod tests {
454
474
use chain:: keysinterface:: { KeysInterface , Recipient } ;
455
475
use ln:: msgs:: OnionMessageHandler ;
456
- use onion_message:: { BlindedRoute , Destination , OnionMessenger } ;
476
+ use onion_message:: { BlindedRoute , Destination , OnionMessenger , SendError } ;
457
477
use util:: enforcing_trait_impls:: EnforcingSigner ;
458
478
use util:: events:: { MessageSendEvent , MessageSendEventsProvider } ;
459
479
use util:: test_utils;
460
480
461
481
use bitcoin:: network:: constants:: Network ;
462
- use bitcoin:: secp256k1:: { PublicKey , Secp256k1 } ;
482
+ use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
463
483
464
484
use sync:: Arc ;
465
485
@@ -552,4 +572,18 @@ mod tests {
552
572
node1. messenger . send_onion_message ( vec ! [ ] , Destination :: BlindedRoute ( blinded_route) ) . unwrap ( ) ;
553
573
pass_along_path ( vec ! [ & node1, & node2, & node3, & node4] , None ) ;
554
574
}
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
+ }
555
589
}
0 commit comments