- nodes[3].logger.assert_log_contains(
- "lightning::onion_message::messenger".to_string(),
- format!("Received an onion message with path_id: None and reply_path").to_string(), 1);
-
- // Destination::BlindedRoute
- let blinded_route = BlindedRoute::new::<EnforcingSigner, _, _>(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap();
- let reply_path = BlindedRoute::new::<EnforcingSigner, _, _>(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap();
-
- nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), Some(reply_path)).unwrap();
- pass_along_path(&nodes, None);
- nodes[3].logger.assert_log_contains(
- "lightning::onion_message::messenger".to_string(),
- format!("Received an onion message with path_id: None and reply_path").to_string(), 2);
+ nodes[0].custom_message_handler.expect_message(TestCustomMessage::Response);
+ nodes.reverse();
+ pass_along_path(&nodes);
+
+ // Destination::BlindedPath
+ let blinded_path = BlindedPath::new_for_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap();
+ let path = OnionMessagePath {
+ intermediate_nodes: vec![],
+ destination: Destination::BlindedPath(blinded_path),
+ };
+ let reply_path = BlindedPath::new_for_message(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap();
+
+ nodes[0].messenger.send_onion_message(path, OnionMessageContents::Custom(test_msg), Some(reply_path)).unwrap();
+ nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
+ pass_along_path(&nodes);
+
+ // Make sure the last node successfully decoded the reply path.
+ nodes[0].custom_message_handler.expect_message(TestCustomMessage::Response);
+ nodes.reverse();
+ pass_along_path(&nodes);
+}
+
+#[test]
+fn invalid_custom_message_type() {
+ let nodes = create_nodes(2);
+
+ struct InvalidCustomMessage{}
+ impl CustomOnionMessageContents for InvalidCustomMessage {
+ fn tlv_type(&self) -> u64 {
+ // Onion message contents must have a TLV >= 64.
+ 63
+ }
+ }
+
+ impl Writeable for InvalidCustomMessage {
+ fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
+ }
+
+ let test_msg = OnionMessageContents::Custom(InvalidCustomMessage {});
+ let path = OnionMessagePath {
+ intermediate_nodes: vec![],
+ destination: Destination::Node(nodes[1].get_node_pk()),
+ };
+ let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
+ assert_eq!(err, SendError::InvalidMessage);
+}
+
+#[test]
+fn peer_buffer_full() {
+ let nodes = create_nodes(2);
+ let test_msg = TestCustomMessage::Request;
+ let path = OnionMessagePath {
+ intermediate_nodes: vec![],
+ destination: Destination::Node(nodes[1].get_node_pk()),
+ };
+ for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
+ nodes[0].messenger.send_onion_message(path.clone(), OnionMessageContents::Custom(test_msg.clone()), None).unwrap();
+ }
+ let err = nodes[0].messenger.send_onion_message(path, OnionMessageContents::Custom(test_msg), None).unwrap_err();
+ assert_eq!(err, SendError::BufferFull);
+}
+
+#[test]
+fn many_hops() {
+ // Check we can send over a route with many hops. This will exercise our logic for onion messages
+ // of size [`crate::onion_message::packet::BIG_PACKET_HOP_DATA_LEN`].
+ let num_nodes: usize = 25;
+ let nodes = create_nodes(num_nodes as u8);
+ let test_msg = TestCustomMessage::Response;
+
+ let mut intermediate_nodes = vec![];
+ for i in 1..(num_nodes-1) {
+ intermediate_nodes.push(nodes[i].get_node_pk());
+ }
+
+ let path = OnionMessagePath {
+ intermediate_nodes,
+ destination: Destination::Node(nodes[num_nodes-1].get_node_pk()),
+ };
+ nodes[0].messenger.send_onion_message(path, OnionMessageContents::Custom(test_msg), None).unwrap();
+ nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Response);
+ pass_along_path(&nodes);