Skip to content

Commit 8412e83

Browse files
committed
Destination in OnionMessenger::send_onion_message
OnionMessenger::send_onion_message takes an OnionMessagePath. This isn't very useful as it requires finding a path manually. Instead, have the method take a Destination and use OnionMessenger's MessageRouter to construct the path. Later, this will allow for buffering messages where the first node in the path isn't a direct connection.
1 parent 79f212b commit 8412e83

File tree

3 files changed

+108
-65
lines changed

3 files changed

+108
-65
lines changed

fuzz/src/onion_message.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ mod tests {
269269
"Received an onion message with path_id None and a reply_path: Custom(TestCustomMessage)"
270270
.to_string())), Some(&1));
271271
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
272-
"Sending onion message when responding to Custom onion message with path_id None: TestCustomMessage".to_string())), Some(&1));
272+
"Constructing onion message when responding to Custom onion message with path_id None: TestCustomMessage".to_string())), Some(&1));
273+
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
274+
"Buffered onion message when responding to Custom onion message with path_id None".to_string())), Some(&1));
273275
}
274276

275277
let two_unblinded_hops_om = "\

lightning/src/onion_message/functional_tests.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ fn one_unblinded_hop() {
206206
intermediate_nodes: vec![],
207207
destination: Destination::Node(nodes[1].get_node_pk()),
208208
};
209-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
209+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
210210
nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response);
211211
pass_along_path(&nodes);
212212
}
@@ -220,7 +220,7 @@ fn two_unblinded_hops() {
220220
intermediate_nodes: vec![nodes[1].get_node_pk()],
221221
destination: Destination::Node(nodes[2].get_node_pk()),
222222
};
223-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
223+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
224224
nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response);
225225
pass_along_path(&nodes);
226226
}
@@ -236,7 +236,7 @@ fn one_blinded_hop() {
236236
intermediate_nodes: vec![],
237237
destination: Destination::BlindedPath(blinded_path),
238238
};
239-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
239+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
240240
nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response);
241241
pass_along_path(&nodes);
242242
}
@@ -253,7 +253,7 @@ fn two_unblinded_two_blinded() {
253253
destination: Destination::BlindedPath(blinded_path),
254254
};
255255

256-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
256+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
257257
nodes[4].custom_message_handler.expect_message(TestCustomMessage::Response);
258258
pass_along_path(&nodes);
259259
}
@@ -270,7 +270,7 @@ fn three_blinded_hops() {
270270
destination: Destination::BlindedPath(blinded_path),
271271
};
272272

273-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
273+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
274274
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Response);
275275
pass_along_path(&nodes);
276276
}
@@ -287,7 +287,7 @@ fn too_big_packet_error() {
287287
intermediate_nodes: hops,
288288
destination: Destination::Node(hop_node_id),
289289
};
290-
let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
290+
let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err();
291291
assert_eq!(err, SendError::TooBigPacket);
292292
}
293293

@@ -305,7 +305,7 @@ fn we_are_intro_node() {
305305
destination: Destination::BlindedPath(blinded_path),
306306
};
307307

308-
nodes[0].messenger.send_onion_message(path, test_msg.clone(), None).unwrap();
308+
nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), None).unwrap();
309309
nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response);
310310
pass_along_path(&nodes);
311311

@@ -315,7 +315,7 @@ fn we_are_intro_node() {
315315
intermediate_nodes: vec![],
316316
destination: Destination::BlindedPath(blinded_path),
317317
};
318-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
318+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
319319
nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response);
320320
nodes.remove(2);
321321
pass_along_path(&nodes);
@@ -335,7 +335,7 @@ fn invalid_blinded_path_error() {
335335
intermediate_nodes: vec![],
336336
destination: Destination::BlindedPath(blinded_path),
337337
};
338-
let err = nodes[0].messenger.send_onion_message(path, test_msg.clone(), None).unwrap_err();
338+
let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), None).unwrap_err();
339339
assert_eq!(err, SendError::TooFewBlindedHops);
340340
}
341341

@@ -351,7 +351,7 @@ fn reply_path() {
351351
destination: Destination::Node(nodes[3].get_node_pk()),
352352
};
353353
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();
354-
nodes[0].messenger.send_onion_message(path, test_msg.clone(), Some(reply_path)).unwrap();
354+
nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), Some(reply_path)).unwrap();
355355
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
356356
pass_along_path(&nodes);
357357
// Make sure the last node successfully decoded the reply path.
@@ -367,7 +367,7 @@ fn reply_path() {
367367
};
368368
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();
369369

370-
nodes[0].messenger.send_onion_message(path, test_msg, Some(reply_path)).unwrap();
370+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, Some(reply_path)).unwrap();
371371
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
372372
pass_along_path(&nodes);
373373

@@ -399,7 +399,7 @@ fn invalid_custom_message_type() {
399399
intermediate_nodes: vec![],
400400
destination: Destination::Node(nodes[1].get_node_pk()),
401401
};
402-
let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
402+
let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err();
403403
assert_eq!(err, SendError::InvalidMessage);
404404
}
405405

@@ -412,9 +412,9 @@ fn peer_buffer_full() {
412412
destination: Destination::Node(nodes[1].get_node_pk()),
413413
};
414414
for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
415-
nodes[0].messenger.send_onion_message(path.clone(), test_msg.clone(), None).unwrap();
415+
nodes[0].messenger.send_onion_message_using_path(path.clone(), test_msg.clone(), None).unwrap();
416416
}
417-
let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
417+
let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err();
418418
assert_eq!(err, SendError::BufferFull);
419419
}
420420

@@ -435,7 +435,7 @@ fn many_hops() {
435435
intermediate_nodes,
436436
destination: Destination::Node(nodes[num_nodes-1].get_node_pk()),
437437
};
438-
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
438+
nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap();
439439
nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Response);
440440
pass_along_path(&nodes);
441441
}

lightning/src/onion_message/messenger.rs

Lines changed: 90 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@ use crate::prelude::*;
7676
/// # struct FakeMessageRouter {}
7777
/// # impl MessageRouter for FakeMessageRouter {
7878
/// # fn find_path(&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination) -> Result<OnionMessagePath, ()> {
79-
/// # unimplemented!()
79+
/// # let secp_ctx = Secp256k1::new();
80+
/// # let node_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
81+
/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
82+
/// # let hop_node_id2 = hop_node_id1;
83+
/// # Ok(OnionMessagePath {
84+
/// # intermediate_nodes: vec![hop_node_id1, hop_node_id2],
85+
/// # destination,
86+
/// # })
8087
/// # }
8188
/// # }
8289
/// # let seed = [42u8; 32];
@@ -86,7 +93,7 @@ use crate::prelude::*;
8693
/// # let node_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
8794
/// # let secp_ctx = Secp256k1::new();
8895
/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
89-
/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
96+
/// # let (hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1);
9097
/// # let destination_node_id = hop_node_id1;
9198
/// # let message_router = Arc::new(FakeMessageRouter {});
9299
/// # let custom_message_handler = IgnoringMessageHandler {};
@@ -113,27 +120,21 @@ use crate::prelude::*;
113120
/// }
114121
/// }
115122
/// // Send a custom onion message to a node id.
116-
/// let path = OnionMessagePath {
117-
/// intermediate_nodes: vec![hop_node_id1, hop_node_id2],
118-
/// destination: Destination::Node(destination_node_id),
119-
/// };
123+
/// let destination = Destination::Node(destination_node_id);
120124
/// let reply_path = None;
121125
/// # let message = YourCustomMessage {};
122-
/// onion_messenger.send_onion_message(path, message, reply_path);
126+
/// onion_messenger.send_onion_message(message, destination, reply_path);
123127
///
124128
/// // Create a blinded path to yourself, for someone to send an onion message to.
125129
/// # let your_node_id = hop_node_id1;
126130
/// let hops = [hop_node_id3, hop_node_id4, your_node_id];
127131
/// let blinded_path = BlindedPath::new_for_message(&hops, &keys_manager, &secp_ctx).unwrap();
128132
///
129133
/// // Send a custom onion message to a blinded path.
130-
/// let path = OnionMessagePath {
131-
/// intermediate_nodes: vec![hop_node_id1, hop_node_id2],
132-
/// destination: Destination::BlindedPath(blinded_path),
133-
/// };
134+
/// let destination = Destination::BlindedPath(blinded_path);
134135
/// let reply_path = None;
135136
/// # let message = YourCustomMessage {};
136-
/// onion_messenger.send_onion_message(path, message, reply_path);
137+
/// onion_messenger.send_onion_message(message, destination, reply_path);
137138
/// ```
138139
///
139140
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
@@ -304,6 +305,16 @@ impl Destination {
304305
}
305306
}
306307

308+
/// Result of successfully [sending an onion message].
309+
///
310+
/// [sending an onion message]: OnionMessenger::send_onion_message
311+
#[derive(Debug, PartialEq, Eq)]
312+
pub enum SendSuccess {
313+
/// The message was buffered and will be sent once it is processed by
314+
/// [`OnionMessageHandler::next_onion_message_for_peer`].
315+
Buffered,
316+
}
317+
307318
/// Errors that may occur when [sending an onion message].
308319
///
309320
/// [sending an onion message]: OnionMessenger::send_onion_message
@@ -319,6 +330,8 @@ pub enum SendError {
319330
TooFewBlindedHops,
320331
/// Our next-hop peer was offline or does not support onion message forwarding.
321332
InvalidFirstHop,
333+
/// A path from the sender to the destination could not be found by the [`MessageRouter`].
334+
PathNotFound,
322335
/// Onion message contents must have a TLV type >= 64.
323336
InvalidMessage,
324337
/// Our next-hop peer's buffer was full or our total outbound buffer was full.
@@ -568,14 +581,63 @@ where
568581
}
569582
}
570583

571-
/// Sends an [`OnionMessage`] with the given `contents` for sending to the destination of
572-
/// `path`.
584+
/// Sends an [`OnionMessage`] with the given `contents` to `destination`.
573585
///
574586
/// See [`OnionMessenger`] for example usage.
575587
pub fn send_onion_message<T: OnionMessageContents>(
576-
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>
577-
) -> Result<(), SendError> {
578-
log_trace!(self.logger, "Sending onion message: {:?}", contents);
588+
&self, contents: T, destination: Destination, reply_path: Option<BlindedPath>
589+
) -> Result<SendSuccess, SendError> {
590+
self.find_path_and_enqueue_onion_message(
591+
contents, destination, reply_path, format_args!("")
592+
)
593+
}
594+
595+
fn find_path_and_enqueue_onion_message<T: OnionMessageContents>(
596+
&self, contents: T, destination: Destination, reply_path: Option<BlindedPath>,
597+
log_suffix: fmt::Arguments
598+
) -> Result<SendSuccess, SendError> {
599+
let result = self.find_path(destination)
600+
.and_then(|path| self.enqueue_onion_message(path, contents, reply_path, log_suffix));
601+
602+
match result.as_ref() {
603+
Err(SendError::GetNodeIdFailed) => {
604+
log_warn!(self.logger, "Unable to retrieve node id {}", log_suffix);
605+
},
606+
Err(SendError::PathNotFound) => {
607+
log_trace!(self.logger, "Failed to find path {}", log_suffix);
608+
},
609+
Err(e) => {
610+
log_trace!(self.logger, "Failed sending onion message {}: {:?}", log_suffix, e);
611+
},
612+
Ok(SendSuccess::Buffered) => {
613+
log_trace!(self.logger, "Buffered onion message {}", log_suffix);
614+
},
615+
}
616+
617+
result
618+
}
619+
620+
fn find_path(&self, destination: Destination) -> Result<OnionMessagePath, SendError> {
621+
let sender = self.node_signer
622+
.get_node_id(Recipient::Node)
623+
.map_err(|_| SendError::GetNodeIdFailed)?;
624+
625+
let peers = self.message_buffers.lock().unwrap()
626+
.iter()
627+
.filter(|(_, buffer)| matches!(buffer, OnionMessageBuffer::ConnectedPeer(_)))
628+
.map(|(node_id, _)| *node_id)
629+
.collect();
630+
631+
self.message_router
632+
.find_path(sender, peers, destination)
633+
.map_err(|_| SendError::PathNotFound)
634+
}
635+
636+
fn enqueue_onion_message<T: OnionMessageContents>(
637+
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
638+
log_suffix: fmt::Arguments
639+
) -> Result<SendSuccess, SendError> {
640+
log_trace!(self.logger, "Constructing onion message {}: {:?}", log_suffix, contents);
579641

580642
let (first_node_id, onion_message) = create_onion_message(
581643
&self.entropy_source, &self.node_signer, &self.secp_ctx, path, contents, reply_path
@@ -590,18 +652,25 @@ where
590652
hash_map::Entry::Vacant(_) => Err(SendError::InvalidFirstHop),
591653
hash_map::Entry::Occupied(mut e) => {
592654
e.get_mut().enqueue_message(onion_message);
593-
Ok(())
655+
Ok(SendSuccess::Buffered)
594656
},
595657
}
596658
}
597659

660+
#[cfg(test)]
661+
pub(super) fn send_onion_message_using_path<T: OnionMessageContents>(
662+
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>
663+
) -> Result<SendSuccess, SendError> {
664+
self.enqueue_onion_message(path, contents, reply_path, format_args!(""))
665+
}
666+
598667
fn handle_onion_message_response<T: OnionMessageContents>(
599668
&self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
600669
) {
601670
if let Some(response) = response {
602671
match reply_path {
603672
Some(reply_path) => {
604-
self.find_path_and_enqueue_onion_message(
673+
let _ = self.find_path_and_enqueue_onion_message(
605674
response, Destination::BlindedPath(reply_path), None, log_suffix
606675
);
607676
},
@@ -612,34 +681,6 @@ where
612681
}
613682
}
614683

615-
fn find_path_and_enqueue_onion_message<T: OnionMessageContents>(
616-
&self, contents: T, destination: Destination, reply_path: Option<BlindedPath>,
617-
log_suffix: fmt::Arguments
618-
) {
619-
let sender = match self.node_signer.get_node_id(Recipient::Node) {
620-
Ok(node_id) => node_id,
621-
Err(_) => {
622-
log_warn!(self.logger, "Unable to retrieve node id {}", log_suffix);
623-
return;
624-
}
625-
};
626-
627-
let peers = self.message_buffers.lock().unwrap().keys().copied().collect();
628-
let path = match self.message_router.find_path(sender, peers, destination) {
629-
Ok(path) => path,
630-
Err(()) => {
631-
log_trace!(self.logger, "Failed to find path {}", log_suffix);
632-
return;
633-
},
634-
};
635-
636-
log_trace!(self.logger, "Sending onion message {}: {:?}", log_suffix, contents);
637-
638-
if let Err(e) = self.send_onion_message(path, contents, reply_path) {
639-
log_trace!(self.logger, "Failed sending onion message {}: {:?}", log_suffix, e);
640-
}
641-
}
642-
643684
#[cfg(test)]
644685
pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, VecDeque<OnionMessage>> {
645686
let mut message_buffers = self.message_buffers.lock().unwrap();
@@ -790,7 +831,7 @@ where
790831
let PendingOnionMessage { contents, destination, reply_path } = message;
791832
#[cfg(c_bindings)]
792833
let (contents, destination, reply_path) = message;
793-
self.find_path_and_enqueue_onion_message(
834+
let _ = self.find_path_and_enqueue_onion_message(
794835
contents, destination, reply_path, format_args!("when sending OffersMessage")
795836
);
796837
}
@@ -801,7 +842,7 @@ where
801842
let PendingOnionMessage { contents, destination, reply_path } = message;
802843
#[cfg(c_bindings)]
803844
let (contents, destination, reply_path) = message;
804-
self.find_path_and_enqueue_onion_message(
845+
let _ = self.find_path_and_enqueue_onion_message(
805846
contents, destination, reply_path, format_args!("when sending CustomMessage")
806847
);
807848
}

0 commit comments

Comments
 (0)