+#[test]
+fn intercept_offline_peer_oms() {
+ // Ensure that if OnionMessenger is initialized with
+ // new_with_offline_peer_interception, we will intercept OMs for offline
+ // peers, generate the right events, and forward OMs when they are re-injected
+ // by the user.
+ let node_cfgs = vec![MessengerCfg::new(), MessengerCfg::new().with_offline_peer_interception(), MessengerCfg::new()];
+ let mut nodes = create_nodes_using_cfgs(node_cfgs);
+
+ let peer_conn_evs = release_events(&nodes[1]);
+ assert_eq!(peer_conn_evs.len(), 2);
+ for (i, ev) in peer_conn_evs.iter().enumerate() {
+ match ev {
+ Event::OnionMessagePeerConnected { peer_node_id } => {
+ let node_idx = if i == 0 { 0 } else { 2 };
+ assert_eq!(peer_node_id, &nodes[node_idx].node_id);
+ },
+ _ => panic!()
+ }
+ }
+
+ let message = TestCustomMessage::Response;
+ let secp_ctx = Secp256k1::new();
+ let intermediate_nodes = [ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }];
+ let blinded_path = BlindedPath::new_for_message(
+ &intermediate_nodes, nodes[2].node_id, &*nodes[2].entropy_source, &secp_ctx
+ ).unwrap();
+ let destination = Destination::BlindedPath(blinded_path);
+
+ // Disconnect the peers to ensure we intercept the OM.
+ disconnect_peers(&nodes[1], &nodes[2]);
+ nodes[0].messenger.send_onion_message(message, destination, None).unwrap();
+ let mut final_node_vec = nodes.split_off(2);
+ pass_along_path(&nodes);
+
+ let mut events = release_events(&nodes[1]);
+ assert_eq!(events.len(), 1);
+ let onion_message = match events.remove(0) {
+ Event::OnionMessageIntercepted { peer_node_id, message } => {
+ assert_eq!(peer_node_id, final_node_vec[0].node_id);
+ message
+ },
+ _ => panic!()
+ };
+
+ // Ensure that we'll refuse to forward the re-injected OM until after the
+ // outbound peer comes back online.
+ let err = nodes[1].messenger.forward_onion_message(onion_message.clone(), &final_node_vec[0].node_id).unwrap_err();
+ assert_eq!(err, SendError::InvalidFirstHop(final_node_vec[0].node_id));
+
+ connect_peers(&nodes[1], &final_node_vec[0]);
+ let peer_conn_ev = release_events(&nodes[1]);
+ assert_eq!(peer_conn_ev.len(), 1);
+ match peer_conn_ev[0] {
+ Event::OnionMessagePeerConnected { peer_node_id } => {
+ assert_eq!(peer_node_id, final_node_vec[0].node_id);
+ },
+ _ => panic!()
+ }
+
+ nodes[1].messenger.forward_onion_message(onion_message, &final_node_vec[0].node_id).unwrap();
+ final_node_vec[0].custom_message_handler.expect_message(TestCustomMessage::Response);
+ pass_along_path(&vec![nodes.remove(1), final_node_vec.remove(0)]);
+}
+