Skip to content

Commit 4ba91a9

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 4ba91a9

File tree

2 files changed

+68
-17
lines changed

2 files changed

+68
-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: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,23 @@ impl Responder {
267267
}
268268
}
269269

270-
/// Creates the appropriate [`ResponseInstruction`] for a given response.
270+
/// Creates a [`ResponseInstruction::WithoutReplyPath`] for a given response.
271271
pub fn respond<T: OnionMessageContents>(self, response: T) -> ResponseInstruction<T> {
272272
ResponseInstruction::WithoutReplyPath(OnionMessageResponse {
273273
message: response,
274274
reply_path: self.reply_path,
275275
path_id: self.path_id,
276276
})
277277
}
278+
279+
/// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
280+
pub fn respond_with_reply_path<T: OnionMessageContents>(self, response: T) -> ResponseInstruction<T> {
281+
ResponseInstruction::WithReplyPath(OnionMessageResponse {
282+
message: response,
283+
reply_path: self.reply_path,
284+
path_id: self.path_id,
285+
})
286+
}
278287
}
279288

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

287296
/// `ResponseInstruction` represents instructions for responding to received messages.
288297
pub enum ResponseInstruction<T: OnionMessageContents> {
298+
/// Indicates that a response should be sent including a reply path for
299+
/// the recipient to respond back.
300+
WithReplyPath(OnionMessageResponse<T>),
289301
/// Indicates that a response should be sent without including a reply path
290302
/// for the recipient to respond back.
291303
WithoutReplyPath(OnionMessageResponse<T>),
@@ -971,6 +983,24 @@ where
971983
.map_err(|_| SendError::PathNotFound)
972984
}
973985

986+
fn create_blinded_path(&self) -> Result<BlindedPath, SendError> {
987+
let recipient = self.node_signer
988+
.get_node_id(Recipient::Node)
989+
.map_err(|_| SendError::GetNodeIdFailed)?;
990+
let secp_ctx = &self.secp_ctx;
991+
992+
let peers = self.message_recipients.lock().unwrap()
993+
.iter()
994+
.filter(|(_, peer)| matches!(peer, OnionMessageRecipient::ConnectedPeer(_)))
995+
.map(|(node_id, _)| *node_id)
996+
.collect();
997+
998+
self.message_router
999+
.create_blinded_paths(recipient, peers, secp_ctx)
1000+
.and_then(|paths| paths.into_iter().next().ok_or(()))
1001+
.map_err(|_| SendError::PathNotFound)
1002+
}
1003+
9741004
fn enqueue_onion_message<T: OnionMessageContents>(
9751005
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
9761006
log_suffix: fmt::Arguments
@@ -1047,18 +1077,35 @@ where
10471077
/// enqueueing any response for sending.
10481078
pub fn handle_onion_message_response<T: OnionMessageContents>(
10491079
&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-
}
1080+
) -> Result<Option<SendSuccess>, SendError> {
1081+
let (response, create_reply_path) = match response {
1082+
ResponseInstruction::WithReplyPath(response) => (response, true),
1083+
ResponseInstruction::WithoutReplyPath(response) => (response, false),
1084+
ResponseInstruction::NoResponse => return Ok(None),
1085+
};
1086+
let logger = WithContext::from(&self.logger, None, None, None);
1087+
let message_type = response.message.msg_type();
1088+
let log_suffix = format!(
1089+
"when responding with {} to an onion message with path_id {:02x?}",
1090+
message_type,
1091+
response.path_id
1092+
);
1093+
1094+
let reply_path = if create_reply_path {
1095+
let reply_path = self.create_blinded_path();
1096+
match reply_path.as_ref() {
1097+
Err(SendError::PathNotFound) => log_trace!(
1098+
logger, "Failed to create blinded_path {}", format_args!("{}", log_suffix)
1099+
),
1100+
_ => (),
1101+
}
1102+
Some(reply_path?)
1103+
} else { None };
1104+
1105+
self.find_path_and_enqueue_onion_message(
1106+
response.message, Destination::BlindedPath(response.reply_path), reply_path,
1107+
format_args!("{}", log_suffix)
1108+
).map(|result| Some(result))
10621109
}
10631110

10641111
#[cfg(test)]
@@ -1164,14 +1211,14 @@ where
11641211
|reply_path| Responder::new(reply_path, path_id)
11651212
);
11661213
let response_instructions = self.offers_handler.handle_message(msg, responder);
1167-
self.handle_onion_message_response(response_instructions);
1214+
let _ = self.handle_onion_message_response(response_instructions);
11681215
},
11691216
ParsedOnionMessageContents::Custom(msg) => {
11701217
let responder = reply_path.map(
11711218
|reply_path| Responder::new(reply_path, path_id)
11721219
);
11731220
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
1174-
self.handle_onion_message_response(response_instructions);
1221+
let _ = self.handle_onion_message_response(response_instructions);
11751222
},
11761223
}
11771224
},

0 commit comments

Comments
 (0)