@@ -58,6 +58,17 @@ struct MessengerNode {
58
58
> >
59
59
}
60
60
61
+ impl Drop for MessengerNode {
62
+ fn drop ( & mut self ) {
63
+ #[ cfg( feature = "std" ) ] {
64
+ if std:: thread:: panicking ( ) {
65
+ return ;
66
+ }
67
+ }
68
+ assert ! ( release_events( self ) . is_empty( ) ) ;
69
+ }
70
+ }
71
+
61
72
struct TestOffersMessageHandler { }
62
73
63
74
impl OffersMessageHandler for TestOffersMessageHandler {
@@ -163,15 +174,20 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
163
174
164
175
struct MessengerCfg {
165
176
secret_override : Option < SecretKey > ,
177
+ intercept_offline_peer_oms : bool ,
166
178
}
167
179
impl MessengerCfg {
168
180
fn new ( ) -> Self {
169
- Self { secret_override : None }
181
+ Self { secret_override : None , intercept_offline_peer_oms : false }
170
182
}
171
183
fn with_node_secret ( mut self , secret : SecretKey ) -> Self {
172
184
self . secret_override = Some ( secret) ;
173
185
self
174
186
}
187
+ fn with_offline_peer_interception ( mut self ) -> Self {
188
+ self . intercept_offline_peer_oms = true ;
189
+ self
190
+ }
175
191
}
176
192
177
193
fn create_nodes_using_cfgs ( cfgs : Vec < MessengerCfg > ) -> Vec < MessengerNode > {
@@ -194,14 +210,22 @@ fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
194
210
) ;
195
211
let offers_message_handler = Arc :: new ( TestOffersMessageHandler { } ) ;
196
212
let custom_message_handler = Arc :: new ( TestCustomMessageHandler :: new ( ) ) ;
213
+ let messenger = if cfg. intercept_offline_peer_oms {
214
+ OnionMessenger :: new_with_offline_peer_interception (
215
+ entropy_source. clone ( ) , node_signer. clone ( ) , logger. clone ( ) , message_router,
216
+ offers_message_handler, custom_message_handler. clone ( )
217
+ )
218
+ } else {
219
+ OnionMessenger :: new (
220
+ entropy_source. clone ( ) , node_signer. clone ( ) , logger. clone ( ) , message_router,
221
+ offers_message_handler, custom_message_handler. clone ( )
222
+ )
223
+ } ;
197
224
nodes. push ( MessengerNode {
198
225
privkey : secret_key,
199
226
node_id : node_signer. get_node_id ( Recipient :: Node ) . unwrap ( ) ,
200
- entropy_source : entropy_source. clone ( ) ,
201
- messenger : OnionMessenger :: new (
202
- entropy_source, node_signer, logger. clone ( ) , message_router,
203
- offers_message_handler, custom_message_handler. clone ( )
204
- ) ,
227
+ entropy_source,
228
+ messenger,
205
229
custom_message_handler,
206
230
gossip_sync : gossip_sync. clone ( ) ,
207
231
} ) ;
@@ -550,6 +574,70 @@ fn drops_buffered_messages_waiting_for_peer_connection() {
550
574
assert ! ( nodes[ 0 ] . messenger. next_onion_message_for_peer( nodes[ 1 ] . node_id) . is_none( ) ) ;
551
575
}
552
576
577
+ #[ test]
578
+ fn intercept_offline_peer_oms ( ) {
579
+ // Ensure that if OnionMessenger is initialized with
580
+ // new_with_offline_peer_interception, we will intercept OMs for offline
581
+ // peers, generate the right events, and forward OMs when they are re-injected
582
+ // by the user.
583
+ let node_cfgs = vec ! [ MessengerCfg :: new( ) , MessengerCfg :: new( ) . with_offline_peer_interception( ) , MessengerCfg :: new( ) ] ;
584
+ let mut nodes = create_nodes_using_cfgs ( node_cfgs) ;
585
+
586
+ let peer_conn_evs = release_events ( & nodes[ 1 ] ) ;
587
+ assert_eq ! ( peer_conn_evs. len( ) , 2 ) ;
588
+ for ( i, ev) in peer_conn_evs. iter ( ) . enumerate ( ) {
589
+ match ev {
590
+ Event :: OnionMessagePeerConnected { peer_node_id } => {
591
+ let node_idx = if i == 0 { 0 } else { 2 } ;
592
+ assert_eq ! ( peer_node_id, & nodes[ node_idx] . node_id) ;
593
+ } ,
594
+ _ => panic ! ( )
595
+ }
596
+ }
597
+
598
+ let message = TestCustomMessage :: Response ;
599
+ let secp_ctx = Secp256k1 :: new ( ) ;
600
+ let blinded_path = BlindedPath :: new_for_message (
601
+ & [ nodes[ 1 ] . node_id , nodes[ 2 ] . node_id ] , & * nodes[ 2 ] . entropy_source , & secp_ctx
602
+ ) . unwrap ( ) ;
603
+ let destination = Destination :: BlindedPath ( blinded_path) ;
604
+
605
+ // Disconnect the peers to ensure we intercept the OM.
606
+ disconnect_peers ( & nodes[ 1 ] , & nodes[ 2 ] ) ;
607
+ nodes[ 0 ] . messenger . send_onion_message ( message, destination, None ) . unwrap ( ) ;
608
+ let mut final_node_vec = nodes. split_off ( 2 ) ;
609
+ pass_along_path ( & nodes) ;
610
+
611
+ let mut events = release_events ( & nodes[ 1 ] ) ;
612
+ assert_eq ! ( events. len( ) , 1 ) ;
613
+ let onion_message = match events. remove ( 0 ) {
614
+ Event :: OnionMessageForOfflinePeer { peer_node_id, message } => {
615
+ assert_eq ! ( peer_node_id, final_node_vec[ 0 ] . node_id) ;
616
+ message
617
+ } ,
618
+ _ => panic ! ( )
619
+ } ;
620
+
621
+ // Ensure that we'll refuse to forward the re-injected OM until after the
622
+ // outbound peer comes back online.
623
+ let err = nodes[ 1 ] . messenger . forward_onion_message ( onion_message. clone ( ) , & final_node_vec[ 0 ] . node_id ) . unwrap_err ( ) ;
624
+ assert_eq ! ( err, SendError :: InvalidFirstHop ( final_node_vec[ 0 ] . node_id) ) ;
625
+
626
+ connect_peers ( & nodes[ 1 ] , & final_node_vec[ 0 ] ) ;
627
+ let peer_conn_ev = release_events ( & nodes[ 1 ] ) ;
628
+ assert_eq ! ( peer_conn_ev. len( ) , 1 ) ;
629
+ match peer_conn_ev[ 0 ] {
630
+ Event :: OnionMessagePeerConnected { peer_node_id } => {
631
+ assert_eq ! ( peer_node_id, final_node_vec[ 0 ] . node_id) ;
632
+ } ,
633
+ _ => panic ! ( )
634
+ }
635
+
636
+ nodes[ 1 ] . messenger . forward_onion_message ( onion_message, & final_node_vec[ 0 ] . node_id ) . unwrap ( ) ;
637
+ final_node_vec[ 0 ] . custom_message_handler . expect_message ( TestCustomMessage :: Response ) ;
638
+ pass_along_path ( & vec ! [ nodes. remove( 1 ) , final_node_vec. remove( 0 ) ] ) ;
639
+ }
640
+
553
641
#[ test]
554
642
fn spec_test_vector ( ) {
555
643
let node_cfgs = [
0 commit comments