Skip to content

Commit c17c2ae

Browse files
committed
Support onion message replies in OnionMessenger
Modify onion message handlers to return an optional response message for OnionMessenger to reply with.
1 parent a71000f commit c17c2ae

File tree

5 files changed

+81
-13
lines changed

5 files changed

+81
-13
lines changed

fuzz/src/onion_message.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ impl MessageRouter for TestMessageRouter {
6868
struct TestOffersMessageHandler {}
6969

7070
impl OffersMessageHandler for TestOffersMessageHandler {
71-
fn handle_message(&self, _message: OffersMessage) {}
71+
fn handle_message(&self, _message: OffersMessage) -> Option<OffersMessage> {
72+
None
73+
}
7274
}
7375

7476
struct TestCustomMessage {}
@@ -92,7 +94,9 @@ struct TestCustomMessageHandler {}
9294

9395
impl CustomOnionMessageHandler for TestCustomMessageHandler {
9496
type CustomMessage = TestCustomMessage;
95-
fn handle_custom_message(&self, _msg: Self::CustomMessage) {}
97+
fn handle_custom_message(&self, _msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
98+
None
99+
}
96100
fn read_custom_message<R: io::Read>(&self, _message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
97101
let mut buf = Vec::new();
98102
buffer.read_to_end(&mut buf)?;

lightning/src/ln/peer_handler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ impl OnionMessageHandler for IgnoringMessageHandler {
119119
}
120120
}
121121
impl OffersMessageHandler for IgnoringMessageHandler {
122-
fn handle_message(&self, _msg: OffersMessage) {}
122+
fn handle_message(&self, _msg: OffersMessage) -> Option<OffersMessage> { None }
123123
}
124124
impl CustomOnionMessageHandler for IgnoringMessageHandler {
125125
type CustomMessage = Infallible;
126-
fn handle_custom_message(&self, _msg: Infallible) {
126+
fn handle_custom_message(&self, _msg: Infallible) -> Option<Infallible> {
127127
// Since we always return `None` in the read the handle method should never be called.
128128
unreachable!();
129129
}

lightning/src/onion_message/functional_tests.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ impl MessageRouter for TestMessageRouter {
5858
struct TestOffersMessageHandler {}
5959

6060
impl OffersMessageHandler for TestOffersMessageHandler {
61-
fn handle_message(&self, _message: OffersMessage) {
62-
todo!()
61+
fn handle_message(&self, _message: OffersMessage) -> Option<OffersMessage> {
62+
None
6363
}
6464
}
6565

@@ -104,8 +104,9 @@ impl Drop for TestCustomMessageHandler {
104104

105105
impl CustomOnionMessageHandler for TestCustomMessageHandler {
106106
type CustomMessage = TestCustomMessage;
107-
fn handle_custom_message(&self, _msg: Self::CustomMessage) {
107+
fn handle_custom_message(&self, _msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
108108
self.num_messages_expected.fetch_sub(1, Ordering::SeqCst);
109+
None
109110
}
110111
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {
111112
if message_type == CUSTOM_MESSAGE_TYPE {

lightning/src/onion_message/messenger.rs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,10 @@ pub trait CustomOnionMessageHandler {
224224
/// The message known to the handler. To support multiple message types, you may want to make this
225225
/// an enum with a variant for each supported message.
226226
type CustomMessage: CustomOnionMessageContents;
227-
/// Called with the custom message that was received.
228-
fn handle_custom_message(&self, msg: Self::CustomMessage);
227+
228+
/// Called with the custom message that was received, returning a response to send, if any.
229+
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage>;
230+
229231
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
230232
/// message type is unknown.
231233
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
@@ -320,6 +322,56 @@ where
320322
}
321323
}
322324

325+
fn respond_with_onion_message<T: CustomOnionMessageContents>(
326+
&self, response: OnionMessageContents<T>, path_id: Option<[u8; 32]>,
327+
reply_path: Option<BlindedPath>
328+
) {
329+
let sender = match self.node_signer.get_node_id(Recipient::Node) {
330+
Ok(node_id) => node_id,
331+
Err(_) => {
332+
log_warn!(
333+
self.logger, "Unable to retrieve node id when responding to onion message with \
334+
path_id {:02x?}", path_id
335+
);
336+
return;
337+
}
338+
};
339+
340+
let peers = self.pending_messages.lock().unwrap().keys().copied().collect();
341+
342+
let destination = match reply_path {
343+
Some(reply_path) => Destination::BlindedPath(reply_path),
344+
None => {
345+
log_trace!(
346+
self.logger, "Missing reply path when responding to onion message with path_id \
347+
{:02x?}", path_id
348+
);
349+
return;
350+
},
351+
};
352+
353+
let path = match self.message_router.find_path(sender, peers, destination) {
354+
Ok(path) => path,
355+
Err(()) => {
356+
log_trace!(
357+
self.logger, "Failed to find path when responding to onion message with \
358+
path_id {:02x?}", path_id
359+
);
360+
return;
361+
},
362+
};
363+
364+
log_trace!(self.logger, "Responding to onion message with path_id {:02x?}", path_id);
365+
366+
if let Err(e) = self.send_onion_message(path, response, None) {
367+
log_trace!(
368+
self.logger, "Failed responding to onion message with path_id {:02x?}: {:?}",
369+
path_id, e
370+
);
371+
return;
372+
}
373+
}
374+
323375
#[cfg(test)]
324376
pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, VecDeque<msgs::OnionMessage>> {
325377
let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -403,9 +455,20 @@ where
403455
log_info!(self.logger,
404456
"Received an onion message with path_id {:02x?} and {} reply_path",
405457
path_id, if reply_path.is_some() { "a" } else { "no" });
406-
match message {
407-
OnionMessageContents::Offers(msg) => self.offers_handler.handle_message(msg),
408-
OnionMessageContents::Custom(msg) => self.custom_handler.handle_custom_message(msg),
458+
459+
let response = match message {
460+
OnionMessageContents::Offers(msg) => {
461+
self.offers_handler.handle_message(msg)
462+
.map(|msg| OnionMessageContents::Offers(msg))
463+
},
464+
OnionMessageContents::Custom(msg) => {
465+
self.custom_handler.handle_custom_message(msg)
466+
.map(|msg| OnionMessageContents::Custom(msg))
467+
},
468+
};
469+
470+
if let Some(response) = response {
471+
self.respond_with_onion_message(response, path_id, reply_path);
409472
}
410473
},
411474
Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {

lightning/src/onion_message/offers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const INVOICE_ERROR_TLV_TYPE: u64 = 68;
3232
pub trait OffersMessageHandler {
3333
/// Handles the given message by either responding with an [`Invoice`], sending a payment, or
3434
/// replying with an error.
35-
fn handle_message(&self, message: OffersMessage);
35+
fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage>;
3636
}
3737

3838
/// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`].

0 commit comments

Comments
 (0)