Skip to content

Commit 78a05ab

Browse files
committed
Buffer onion messages requiring a connection
MessageRouter::find_path returns a path to use when sending an onion message. If the first node on the path is not connected or does not support onion messages, sending will fail with InvalidFirstHop. Instead of failing outright, buffer the message for later sending once the first node is a connected peer.
1 parent 400d5e2 commit 78a05ab

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

lightning/src/onion_message/messenger.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ pub enum SendError {
313313
/// hops.
314314
TooFewBlindedHops,
315315
/// Our next-hop peer was offline or does not support onion message forwarding.
316-
InvalidFirstHop,
316+
InvalidFirstHop(PublicKey, OnionMessage),
317317
/// Onion message contents must have a TLV type >= 64.
318318
InvalidMessage,
319319
/// Our next-hop peer's buffer was full or our total outbound buffer was full.
@@ -580,7 +580,9 @@ where
580580
}
581581

582582
match message_buffers.entry(first_node_id) {
583-
hash_map::Entry::Vacant(_) => Err(SendError::InvalidFirstHop),
583+
hash_map::Entry::Vacant(_) => {
584+
Err(SendError::InvalidFirstHop(first_node_id, onion_message))
585+
},
584586
hash_map::Entry::Occupied(mut e) => {
585587
e.get_mut().enqueue_message(onion_message);
586588
Ok(())
@@ -617,7 +619,11 @@ where
617619
}
618620
};
619621

620-
let peers = self.message_buffers.lock().unwrap().keys().copied().collect();
622+
let peers = self.message_buffers.lock().unwrap()
623+
.iter()
624+
.filter(|(_, buffer)| matches!(buffer, OnionMessageBuffer::ConnectedPeer(_)))
625+
.map(|(node_id, _)| *node_id)
626+
.collect();
621627
let path = match self.message_router.find_path(sender, peers, destination) {
622628
Ok(path) => path,
623629
Err(()) => {
@@ -629,7 +635,19 @@ where
629635
log_trace!(self.logger, "Sending onion message {}", log_suffix);
630636

631637
if let Err(e) = self.send_onion_message(path, contents, reply_path) {
632-
log_trace!(self.logger, "Failed sending onion message {}: {:?}", log_suffix, e);
638+
if let SendError::InvalidFirstHop(first_node_id, onion_message) = e {
639+
// TODO: Check NetworkGraph for node id and onion message support before enqueuing
640+
self.message_buffers.lock().unwrap()
641+
.entry(first_node_id)
642+
.or_insert_with(|| OnionMessageBuffer::PendingConnection(VecDeque::new()))
643+
.enqueue_message(onion_message);
644+
log_trace!(
645+
self.logger, "Buffered onion message waiting on peer connection {}: {:?}",
646+
log_suffix, first_node_id
647+
);
648+
} else {
649+
log_trace!(self.logger, "Failed sending onion message {}: {:?}", log_suffix, e);
650+
}
633651
}
634652
}
635653

0 commit comments

Comments
 (0)