Skip to content

Commit 57bca64

Browse files
committed
Introduce ResponseInstruction::WithReplyPath variant.
And expand handle_onion_message_response return Type 1. Introduce a new function in OnionMessenger to create blinded paths. 2. Use it in handle_onion_message_response to create a reply_path for the right variant and use it in onion_message. 3. Expand the return type of handle_onion_message_response to handle three cases: 1. Ok(None) in case of no response to be sent. 2. Ok(Some(SendSuccess) and Err(SendError) in case of successful and unsuccessful queueing up of response messages respectively. This allows the user to get access to the Success/Failure status of the sending of response and handle it accordingly.
1 parent f73f8af commit 57bca64

File tree

2 files changed

+73
-17
lines changed

2 files changed

+73
-17
lines changed

lightning/src/onion_message/functional_tests.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::routing::test_utils::{add_channel, add_or_update_node};
1818
use crate::sign::{NodeSigner, Recipient};
1919
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
2020
use crate::util::test_utils;
21-
use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction, SendError};
21+
use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction, SendError, SendSuccess};
2222
use super::offers::{OffersMessage, OffersMessageHandler};
2323
use super::packet::{OnionMessageContents, Packet};
2424

@@ -391,7 +391,11 @@ fn async_response_over_one_blinded_hop() {
391391
let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, responder);
392392

393393
// 6. Simulate Alice asynchronously responding back to Bob with a response.
394-
nodes[0].messenger.handle_onion_message_response(response_instruction);
394+
assert_eq!(
395+
nodes[0].messenger.handle_onion_message_response(response_instruction),
396+
Ok(Some(SendSuccess::Buffered)),
397+
);
398+
395399
bob.custom_message_handler.expect_message(TestCustomMessage::Response);
396400

397401
pass_along_path(&nodes);

lightning/src/onion_message/messenger.rs

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,27 @@ impl Responder {
267267
}
268268
}
269269

270-
/// Creates the appropriate [`ResponseInstruction`] for a given response.
270+
/// Creates a [`ResponseInstruction::WithoutReplyPath`] for a given response.
271+
///
272+
/// Use when the recipient doesn't need to send back a reply to us.
271273
pub fn respond<T: OnionMessageContents>(self, response: T) -> ResponseInstruction<T> {
272274
ResponseInstruction::WithoutReplyPath(OnionMessageResponse {
273275
message: response,
274276
reply_path: self.reply_path,
275277
path_id: self.path_id,
276278
})
277279
}
280+
281+
/// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
282+
///
283+
/// Use when the recipient need to send back a reply to us.
284+
pub fn respond_with_reply_path<T: OnionMessageContents>(self, response: T) -> ResponseInstruction<T> {
285+
ResponseInstruction::WithReplyPath(OnionMessageResponse {
286+
message: response,
287+
reply_path: self.reply_path,
288+
path_id: self.path_id,
289+
})
290+
}
278291
}
279292

280293
/// This struct contains the information needed to reply to a received message.
@@ -286,6 +299,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
286299

287300
/// `ResponseInstruction` represents instructions for responding to received messages.
288301
pub enum ResponseInstruction<T: OnionMessageContents> {
302+
/// Indicates that a response should be sent including a reply path for
303+
/// the recipient to respond back.
304+
WithReplyPath(OnionMessageResponse<T>),
289305
/// Indicates that a response should be sent without including a reply path
290306
/// for the recipient to respond back.
291307
WithoutReplyPath(OnionMessageResponse<T>),
@@ -971,6 +987,24 @@ where
971987
.map_err(|_| SendError::PathNotFound)
972988
}
973989

990+
fn create_blinded_path(&self) -> Result<BlindedPath, SendError> {
991+
let recipient = self.node_signer
992+
.get_node_id(Recipient::Node)
993+
.map_err(|_| SendError::GetNodeIdFailed)?;
994+
let secp_ctx = &self.secp_ctx;
995+
996+
let peers = self.message_recipients.lock().unwrap()
997+
.iter()
998+
.filter(|(_, peer)| matches!(peer, OnionMessageRecipient::ConnectedPeer(_)))
999+
.map(|(node_id, _)| *node_id)
1000+
.collect();
1001+
1002+
self.message_router
1003+
.create_blinded_paths(recipient, peers, secp_ctx)
1004+
.and_then(|paths| paths.into_iter().next().ok_or(()))
1005+
.map_err(|_| SendError::PathNotFound)
1006+
}
1007+
9741008
fn enqueue_onion_message<T: OnionMessageContents>(
9751009
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
9761010
log_suffix: fmt::Arguments
@@ -1047,18 +1081,36 @@ where
10471081
/// enqueueing any response for sending.
10481082
pub fn handle_onion_message_response<T: OnionMessageContents>(
10491083
&self, response: ResponseInstruction<T>
1050-
) {
1051-
if let ResponseInstruction::WithoutReplyPath(response) = response {
1052-
let message_type = response.message.msg_type();
1053-
let _ = self.find_path_and_enqueue_onion_message(
1054-
response.message, Destination::BlindedPath(response.reply_path), None,
1055-
format_args!(
1056-
"when responding with {} to an onion message with path_id {:02x?}",
1057-
message_type,
1058-
response.path_id
1059-
)
1060-
);
1061-
}
1084+
) -> Result<Option<SendSuccess>, SendError> {
1085+
let (response, create_reply_path) = match response {
1086+
ResponseInstruction::WithReplyPath(response) => (response, true),
1087+
ResponseInstruction::WithoutReplyPath(response) => (response, false),
1088+
ResponseInstruction::NoResponse => return Ok(None),
1089+
};
1090+
1091+
let message_type = response.message.msg_type();
1092+
let log_suffix = format!(
1093+
"when responding with {} to an onion message with path_id {:02x?}",
1094+
message_type,
1095+
response.path_id
1096+
);
1097+
1098+
let reply_path = if create_reply_path {
1099+
match self.create_blinded_path() {
1100+
Ok(reply_path) => Some(reply_path),
1101+
Err(e) => {
1102+
log_trace!(
1103+
self.logger, "Failed to create reply_path {}: {:?}", log_suffix, e
1104+
);
1105+
return Err(e);
1106+
}
1107+
}
1108+
} else { None };
1109+
1110+
self.find_path_and_enqueue_onion_message(
1111+
response.message, Destination::BlindedPath(response.reply_path), reply_path,
1112+
format_args!("{}", log_suffix)
1113+
).map(|result| Some(result))
10621114
}
10631115

10641116
#[cfg(test)]
@@ -1164,14 +1216,14 @@ where
11641216
|reply_path| Responder::new(reply_path, path_id)
11651217
);
11661218
let response_instructions = self.offers_handler.handle_message(msg, responder);
1167-
self.handle_onion_message_response(response_instructions);
1219+
let _ = self.handle_onion_message_response(response_instructions);
11681220
},
11691221
ParsedOnionMessageContents::Custom(msg) => {
11701222
let responder = reply_path.map(
11711223
|reply_path| Responder::new(reply_path, path_id)
11721224
);
11731225
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
1174-
self.handle_onion_message_response(response_instructions);
1226+
let _ = self.handle_onion_message_response(response_instructions);
11751227
},
11761228
}
11771229
},

0 commit comments

Comments
 (0)