Skip to content

Commit e730884

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 e730884

File tree

2 files changed

+79
-18
lines changed

2 files changed

+79
-18
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: 73 additions & 16 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 needs 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>),
@@ -554,7 +570,11 @@ pub enum SendError {
554570
TooFewBlindedHops,
555571
/// The first hop is not a peer and doesn't have a known [`SocketAddress`].
556572
InvalidFirstHop(PublicKey),
557-
/// A path from the sender to the destination could not be found by the [`MessageRouter`].
573+
/// Indicates that a path could not be found by the [`MessageRouter`].
574+
///
575+
/// This occurs when:
576+
/// 1. No path from sender to destination is found for sending the onion message.
577+
/// 2. No reply path from destination to sender is created when responding to the onion message.
558578
PathNotFound,
559579
/// Onion message contents must have a TLV type >= 64.
560580
InvalidMessage,
@@ -971,6 +991,24 @@ where
971991
.map_err(|_| SendError::PathNotFound)
972992
}
973993

994+
fn create_blinded_path(&self) -> Result<BlindedPath, SendError> {
995+
let recipient = self.node_signer
996+
.get_node_id(Recipient::Node)
997+
.map_err(|_| SendError::GetNodeIdFailed)?;
998+
let secp_ctx = &self.secp_ctx;
999+
1000+
let peers = self.message_recipients.lock().unwrap()
1001+
.iter()
1002+
.filter(|(_, peer)| matches!(peer, OnionMessageRecipient::ConnectedPeer(_)))
1003+
.map(|(node_id, _)| *node_id)
1004+
.collect();
1005+
1006+
self.message_router
1007+
.create_blinded_paths(recipient, peers, secp_ctx)
1008+
.and_then(|paths| paths.into_iter().next().ok_or(()))
1009+
.map_err(|_| SendError::PathNotFound)
1010+
}
1011+
9741012
fn enqueue_onion_message<T: OnionMessageContents>(
9751013
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
9761014
log_suffix: fmt::Arguments
@@ -1047,18 +1085,37 @@ where
10471085
/// enqueueing any response for sending.
10481086
pub fn handle_onion_message_response<T: OnionMessageContents>(
10491087
&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-
}
1088+
) -> Result<Option<SendSuccess>, SendError> {
1089+
let (response, create_reply_path) = match response {
1090+
ResponseInstruction::WithReplyPath(response) => (response, true),
1091+
ResponseInstruction::WithoutReplyPath(response) => (response, false),
1092+
ResponseInstruction::NoResponse => return Ok(None),
1093+
};
1094+
1095+
let message_type = response.message.msg_type();
1096+
let reply_path = if create_reply_path {
1097+
match self.create_blinded_path() {
1098+
Ok(reply_path) => Some(reply_path),
1099+
Err(err) => {
1100+
log_trace!(
1101+
self.logger,
1102+
"Failed to create reply path when responding with {} to an onion message \
1103+
with path_id {:02x?}: {:?}",
1104+
message_type, response.path_id, err
1105+
);
1106+
return Err(err);
1107+
}
1108+
}
1109+
} else { None };
1110+
1111+
self.find_path_and_enqueue_onion_message(
1112+
response.message, Destination::BlindedPath(response.reply_path), reply_path,
1113+
format_args!(
1114+
"when responding with {} to an onion message with path_id {:02x?}",
1115+
message_type,
1116+
response.path_id
1117+
)
1118+
).map(|result| Some(result))
10621119
}
10631120

10641121
#[cfg(test)]
@@ -1164,14 +1221,14 @@ where
11641221
|reply_path| Responder::new(reply_path, path_id)
11651222
);
11661223
let response_instructions = self.offers_handler.handle_message(msg, responder);
1167-
self.handle_onion_message_response(response_instructions);
1224+
let _ = self.handle_onion_message_response(response_instructions);
11681225
},
11691226
ParsedOnionMessageContents::Custom(msg) => {
11701227
let responder = reply_path.map(
11711228
|reply_path| Responder::new(reply_path, path_id)
11721229
);
11731230
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
1174-
self.handle_onion_message_response(response_instructions);
1231+
let _ = self.handle_onion_message_response(response_instructions);
11751232
},
11761233
}
11771234
},

0 commit comments

Comments
 (0)