Skip to content

Commit 3dd0fc0

Browse files
shaavanjkczyz
andcommitted
Approach Revamp: Introducing ResponseInstruction.
1. Since usage of closure could have lead to circular referencing, a new approach is introduced here. 2. This commit introduce a new struct called ResponseInstruction. The job of this struct is to contain the following information: 1. The knowledge of whether to have a response to the message, 2. the response of the message itself, and 3. The other variable needed to forward this response (that is, reply_path, for now). 3. This struct will be used by OnionMessageHandler for doing proper response handling 4. In this commit this struct is used in handle_onion_message_response to appropriately queue the response of responding. Co-authored-by: Jeffrey Czyz <jkczyz@gmail.com>
1 parent 9699624 commit 3dd0fc0

File tree

6 files changed

+68
-68
lines changed

6 files changed

+68
-68
lines changed

fuzz/src/onion_message.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ impl MessageRouter for TestMessageRouter {
9696
struct TestOffersMessageHandler {}
9797

9898
impl OffersMessageHandler for TestOffersMessageHandler {
99-
fn handle_message<R: RespondFunction<OffersMessage>>(&self, _message: ReceivedOnionMessage<R, OffersMessage>) {}
99+
fn handle_message(&self, _message: ReceivedOnionMessage<OffersMessage>) -> ResponseInstruction<OffersMessage> {
100+
ResponseInstruction::NoResponse
101+
}
100102
}
101103

102104
#[derive(Debug)]
@@ -121,7 +123,7 @@ struct TestCustomMessageHandler {}
121123

122124
impl CustomOnionMessageHandler for TestCustomMessageHandler {
123125
type CustomMessage = TestCustomMessage;
124-
fn handle_custom_message<R: RespondFunction<Self::CustomMessage>>(&self, message: ReceivedOnionMessage<R, Self::CustomMessage>) {
126+
fn handle_custom_message(&self, message: ReceivedOnionMessage<Self::CustomMessage>) -> ResponseInstruction<Self::CustomMessage> {
125127
if let ReceivedOnionMessage::WithReplyPath({_, responder}) = message {
126128
responder.respond(TestCustomMessage {})
127129
}

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use crate::offers::merkle::SignError;
6464
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
6565
use crate::offers::parse::Bolt12SemanticError;
6666
use crate::offers::refund::{Refund, RefundBuilder};
67-
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, ReceivedOnionMessage, RespondFunction};
67+
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, ReceivedOnionMessage, ResponseInstruction};
6868
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
6969
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
7070
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
@@ -9274,7 +9274,7 @@ where
92749274
R::Target: Router,
92759275
L::Target: Logger,
92769276
{
9277-
fn handle_message<RF: RespondFunction<OffersMessage>>(&self, message: ReceivedOnionMessage<RF, OffersMessage>)
9277+
fn handle_message(&self, message: ReceivedOnionMessage<OffersMessage>) -> ResponseInstruction<OffersMessage>
92789278
{
92799279
let secp_ctx = &self.secp_ctx;
92809280
let expanded_key = &self.inbound_payment_key;
@@ -9385,8 +9385,12 @@ where
93859385
};
93869386

93879387
if let Some(response) = response_option {
9388-
responder.respond(response);
9388+
responder.respond(response)
9389+
} else {
9390+
ResponseInstruction::NoResponse
93899391
}
9392+
} else {
9393+
ResponseInstruction::NoResponse
93909394
}
93919395
}
93929396

lightning/src/ln/peer_handler.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
2828
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor, NextNoiseStep, MessageBuf, MSG_BUF_ALLOC_SIZE};
2929
use crate::ln::wire;
3030
use crate::ln::wire::{Encode, Type};
31-
use crate::onion_message::messenger::{CustomOnionMessageHandler, PendingOnionMessage, ReceivedOnionMessage, RespondFunction};
31+
use crate::onion_message::messenger::{CustomOnionMessageHandler, PendingOnionMessage, ReceivedOnionMessage, ResponseInstruction};
3232
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
3333
use crate::onion_message::packet::OnionMessageContents;
3434
use crate::routing::gossip::{NodeId, NodeAlias};
@@ -134,11 +134,13 @@ impl OnionMessageHandler for IgnoringMessageHandler {
134134
}
135135

136136
impl OffersMessageHandler for IgnoringMessageHandler {
137-
fn handle_message<R: RespondFunction<OffersMessage>>(&self, _message: ReceivedOnionMessage<R, OffersMessage>) {}
137+
fn handle_message(&self, _message: ReceivedOnionMessage<OffersMessage>) -> ResponseInstruction<OffersMessage> {
138+
ResponseInstruction::NoResponse
139+
}
138140
}
139141
impl CustomOnionMessageHandler for IgnoringMessageHandler {
140142
type CustomMessage = Infallible;
141-
fn handle_custom_message<R: RespondFunction<Self::CustomMessage>>(&self, _message: ReceivedOnionMessage<R, Self::CustomMessage>) {
143+
fn handle_custom_message(&self, _message: ReceivedOnionMessage<Self::CustomMessage>) -> ResponseInstruction<Self::CustomMessage> {
142144
// Since we always return `None` in the read the handle method should never be called.
143145
unreachable!();
144146
}

lightning/src/onion_message/functional_tests.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress};
1616
use crate::sign::{NodeSigner, Recipient};
1717
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
1818
use crate::util::test_utils;
19-
use super::messenger::{CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, PendingOnionMessage, ReceivedOnionMessage, RespondFunction, SendError};
19+
use super::messenger::{CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, PendingOnionMessage, ReceivedOnionMessage, ResponseInstruction, SendError};
2020
use super::offers::{OffersMessage, OffersMessageHandler};
2121
use super::packet::{OnionMessageContents, Packet};
2222

@@ -70,7 +70,9 @@ impl MessageRouter for TestMessageRouter {
7070
struct TestOffersMessageHandler {}
7171

7272
impl OffersMessageHandler for TestOffersMessageHandler {
73-
fn handle_message<R: RespondFunction<OffersMessage>>(&self, _message: ReceivedOnionMessage<R, OffersMessage>) {}
73+
fn handle_message(&self, _message: ReceivedOnionMessage<OffersMessage>) -> ResponseInstruction<OffersMessage> {
74+
ResponseInstruction::NoResponse
75+
}
7476
}
7577

7678
#[derive(Clone, Debug, PartialEq)]
@@ -132,7 +134,7 @@ impl Drop for TestCustomMessageHandler {
132134

133135
impl CustomOnionMessageHandler for TestCustomMessageHandler {
134136
type CustomMessage = TestCustomMessage;
135-
fn handle_custom_message<R: RespondFunction<Self::CustomMessage>>(&self, message: ReceivedOnionMessage<R, Self::CustomMessage>) {
137+
fn handle_custom_message(&self, message: ReceivedOnionMessage<Self::CustomMessage>) -> ResponseInstruction<Self::CustomMessage> {
136138
if let ReceivedOnionMessage::WithReplyPath{responder, message, path_id: _} = message {
137139
match self.expected_messages.lock().unwrap().pop_front() {
138140
Some(expected_msg) => assert_eq!(expected_msg, message),
@@ -146,7 +148,11 @@ impl CustomOnionMessageHandler for TestCustomMessageHandler {
146148

147149
if let Some(response) = response_option {
148150
responder.respond(response)
151+
} else {
152+
ResponseInstruction::NoResponse
149153
}
154+
} else {
155+
ResponseInstruction::NoResponse
150156
}
151157
}
152158
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {

lightning/src/onion_message/messenger.rs

Lines changed: 41 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -245,31 +245,28 @@ impl OnionMessageRecipient {
245245
}
246246

247247
/// A enum to handle received [`OnionMessage`]
248-
pub enum ReceivedOnionMessage<R, T>
248+
pub enum ReceivedOnionMessage<T>
249249
where
250-
R: RespondFunction<T>,
251250
T: OnionMessageContents
252251
{
253252
WithReplyPath {
254253
message: T,
255254
path_id: Option<[u8; 32]>,
256-
responder: Responder<R, T>,
255+
responder: Responder<T>,
257256
},
258257
WithoutReplyPath {
259258
message: T,
260259
path_id: Option<[u8; 32]>,
261260
},
262261
}
263262

264-
impl<R, T> ReceivedOnionMessage<R, T>
263+
impl<T> ReceivedOnionMessage<T>
265264
where
266-
R: RespondFunction<T>,
267265
T: OnionMessageContents
268266
{
269-
fn new(messenger_function: R, message: T, reply_path_opt: Option<BlindedPath>, path_id: Option<[u8; 32]> ) -> Self {
267+
fn new( message: T, reply_path_opt: Option<BlindedPath>, path_id: Option<[u8; 32]> ) -> Self {
270268
if let Some(reply_path) = reply_path_opt {
271269
let responder = Responder {
272-
messenger_function,
273270
reply_path,
274271
_phantom: PhantomData
275272
};
@@ -287,43 +284,38 @@ where
287284
}
288285
}
289286

290-
pub trait RespondFunction<T: OnionMessageContents>{
291-
fn respond(self, response: T, reply_path: BlindedPath);
292-
}
293-
294-
impl<F, T> RespondFunction<T> for F
295-
where
296-
F: Fn(T, BlindedPath),
297-
T: OnionMessageContents
298-
{
299-
fn respond(self, response: T, reply_path: BlindedPath) {
300-
self(response, reply_path)
301-
}
302-
}
303-
304287
/// A struct handling response to an [`OnionMessage`]
305-
pub struct Responder<R, T>
288+
pub struct Responder<T>
306289
where
307-
R: RespondFunction<T>,
308290
T: OnionMessageContents
309291
{
310-
messenger_function: R,
311292
reply_path: BlindedPath,
293+
312294
// This phantom Data is used to ensure that we use T in the struct definition
313295
// This allow us to ensure at compile time that the received message type and response type will be same
314296
_phantom: PhantomData<T>
315297
}
316298

317-
impl<R, T> Responder<R, T>
299+
impl<T> Responder<T>
318300
where
319-
R: RespondFunction<T>,
320301
T: OnionMessageContents
321302
{
322-
pub fn respond(self, response: T) {
323-
self.messenger_function.respond(response, self.reply_path)
303+
pub fn respond(self, response: T) -> ResponseInstruction<T>{
304+
ResponseInstruction::HaveResponse {
305+
response,
306+
reply_path: self.reply_path,
307+
}
324308
}
325309
}
326310

311+
pub enum ResponseInstruction<T: OnionMessageContents> {
312+
HaveResponse {
313+
response: T,
314+
reply_path: BlindedPath,
315+
},
316+
NoResponse
317+
}
318+
327319
/// An [`OnionMessage`] for [`OnionMessenger`] to send.
328320
///
329321
/// These are obtained when released from [`OnionMessenger`]'s handlers after which they are
@@ -581,7 +573,7 @@ pub trait CustomOnionMessageHandler {
581573
/// Called with the custom message that was received, returning a response to send, if any.
582574
///
583575
/// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
584-
fn handle_custom_message<R: RespondFunction<Self::CustomMessage>>(&self, message: ReceivedOnionMessage<R, Self::CustomMessage>);
576+
fn handle_custom_message(&self, message: ReceivedOnionMessage<Self::CustomMessage>) -> ResponseInstruction<Self::CustomMessage>;
585577

586578
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
587579
/// message type is unknown.
@@ -910,11 +902,13 @@ where
910902
}
911903

912904
fn handle_onion_message_response<T: OnionMessageContents>(
913-
&self, response: T, reply_path: BlindedPath, log_suffix: fmt::Arguments
905+
&self, response: ResponseInstruction<T>, log_suffix: fmt::Arguments
914906
) {
915-
let _ = self.find_path_and_enqueue_onion_message(
916-
response, Destination::BlindedPath(reply_path), None, log_suffix
917-
);
907+
if let ResponseInstruction::HaveResponse { response, reply_path } = response {
908+
let _ = self.find_path_and_enqueue_onion_message(
909+
response, Destination::BlindedPath(reply_path), None, log_suffix
910+
);
911+
}
918912
}
919913

920914
#[cfg(test)]
@@ -995,30 +989,22 @@ where
995989
let message_type = message.msg_type();
996990
match message {
997991
ParsedOnionMessageContents::Offers(msg) => {
998-
let closure = |response, reply_path: BlindedPath| {
999-
self.handle_onion_message_response(
1000-
response, reply_path, format_args!(
1001-
"when responding to {} onion message with path_id {:02x?}",
1002-
message_type,
1003-
path_id
1004-
)
1005-
);
1006-
};
1007-
let message = ReceivedOnionMessage::new(closure, msg, reply_path, path_id);
1008-
self.offers_handler.handle_message(message);
992+
let received_message = ReceivedOnionMessage::new(msg, reply_path, path_id);
993+
let response_instructions = self.offers_handler.handle_message(received_message);
994+
self.handle_onion_message_response(response_instructions, format_args!(
995+
"when responding to {} onion message with path_id {:02x?}",
996+
message_type,
997+
path_id
998+
))
1009999
},
10101000
ParsedOnionMessageContents::Custom(msg) => {
1011-
let closure = |response, reply_path: BlindedPath| {
1012-
self.handle_onion_message_response(
1013-
response, reply_path, format_args!(
1014-
"when responding to {} onion message with path_id {:02x?}",
1015-
message_type,
1016-
path_id
1017-
)
1018-
);
1019-
};
1020-
let message = ReceivedOnionMessage::new(closure, msg, reply_path, path_id);
1021-
self.custom_handler.handle_custom_message(message);
1001+
let message = ReceivedOnionMessage::new(msg, reply_path, path_id);
1002+
let response_instructions = self.custom_handler.handle_custom_message(message);
1003+
self.handle_onion_message_response(response_instructions, format_args!(
1004+
"when responding to {} onion message with path_id {:02x?}",
1005+
message_type,
1006+
path_id
1007+
))
10221008
},
10231009
}
10241010
},

lightning/src/onion_message/offers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::onion_message::packet::OnionMessageContents;
2121
use crate::util::logger::Logger;
2222
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
2323
#[cfg(not(c_bindings))]
24-
use crate::onion_message::messenger::{PendingOnionMessage, ReceivedOnionMessage, RespondFunction};
24+
use crate::onion_message::messenger::{PendingOnionMessage, ReceivedOnionMessage, ResponseInstruction};
2525

2626
use crate::prelude::*;
2727

@@ -40,7 +40,7 @@ pub trait OffersMessageHandler {
4040
/// The returned [`OffersMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
4141
///
4242
/// [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger
43-
fn handle_message<R: RespondFunction<OffersMessage>>(&self, message: ReceivedOnionMessage<R, OffersMessage>);
43+
fn handle_message(&self, message: ReceivedOnionMessage<OffersMessage>) -> ResponseInstruction<OffersMessage>;
4444

4545
/// Releases any [`OffersMessage`]s that need to be sent.
4646
///

0 commit comments

Comments
 (0)