Skip to content

Commit 51730b4

Browse files
committed
Implement ResponseInstruction Usage in OnionMessage Handling
This commit integrates the newly introduced ResponseInstruction structs and enums into the codebase for handling OnionMessage responses.
1 parent e241b8a commit 51730b4

File tree

7 files changed

+95
-55
lines changed

7 files changed

+95
-55
lines changed

fuzz/src/onion_message.rs

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

9898
impl OffersMessageHandler for TestOffersMessageHandler {
99-
fn handle_message(&self, _message: OffersMessage) -> Option<OffersMessage> {
100-
None
99+
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder<OffersMessage>>) -> ResponseInstruction<OffersMessage> {
100+
ResponseInstruction::NoResponse
101101
}
102102
}
103103

@@ -123,8 +123,10 @@ struct TestCustomMessageHandler {}
123123

124124
impl CustomOnionMessageHandler for TestCustomMessageHandler {
125125
type CustomMessage = TestCustomMessage;
126-
fn handle_custom_message(&self, _msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
127-
Some(TestCustomMessage {})
126+
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder<Self::CustomMessage>>) -> ResponseInstruction<Self::CustomMessage> {
127+
if let Some(responder) = responder {
128+
responder.respond(TestCustomMessage {})
129+
}
128130
}
129131
fn read_custom_message<R: io::Read>(&self, _message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
130132
let mut buf = Vec::new();

lightning/src/ln/channelmanager.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use crate::offers::merkle::SignError;
6565
use crate::offers::offer::{Offer, OfferBuilder};
6666
use crate::offers::parse::Bolt12SemanticError;
6767
use crate::offers::refund::{Refund, RefundBuilder};
68-
use crate::onion_message::messenger::{Destination, MessageRouter, PendingOnionMessage, new_pending_onion_message};
68+
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction};
6969
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
7070
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
7171
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
@@ -76,6 +76,7 @@ use crate::util::string::UntrustedString;
7676
use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
7777
use crate::util::logger::{Level, Logger, WithContext};
7878
use crate::util::errors::APIError;
79+
7980
#[cfg(not(c_bindings))]
8081
use {
8182
crate::offers::offer::DerivedMetadata,
@@ -9450,24 +9451,34 @@ where
94509451
R::Target: Router,
94519452
L::Target: Logger,
94529453
{
9453-
fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage> {
9454+
fn handle_message(&self, message: OffersMessage, responder: Option<Responder<OffersMessage>>) -> ResponseInstruction<OffersMessage>
9455+
{
94549456
let secp_ctx = &self.secp_ctx;
94559457
let expanded_key = &self.inbound_payment_key;
94569458

9457-
match message {
9459+
let respond = |response| {
9460+
match responder {
9461+
Some(responder) => responder.respond(response),
9462+
None => ResponseInstruction::NoResponse,
9463+
}
9464+
};
9465+
9466+
let response_opt = match &message {
94589467
OffersMessage::InvoiceRequest(invoice_request) => {
94599468
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
94609469
&invoice_request
94619470
) {
94629471
Ok(amount_msats) => amount_msats,
9463-
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
9472+
Err(error) => {
9473+
return respond(OffersMessage::InvoiceError(error.into()));
9474+
}
94649475
};
9465-
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
9476+
let invoice_request = match invoice_request.clone().verify(expanded_key, secp_ctx) {
94669477
Ok(invoice_request) => invoice_request,
94679478
Err(()) => {
94689479
let error = Bolt12SemanticError::InvalidMetadata;
9469-
return Some(OffersMessage::InvoiceError(error.into()));
9470-
},
9480+
return respond(OffersMessage::InvoiceError(error.into()));
9481+
}
94719482
};
94729483

94739484
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
@@ -9477,8 +9488,8 @@ where
94779488
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
94789489
Err(()) => {
94799490
let error = Bolt12SemanticError::InvalidAmount;
9480-
return Some(OffersMessage::InvoiceError(error.into()));
9481-
},
9491+
return respond(OffersMessage::InvoiceError(error.into()));
9492+
}
94829493
};
94839494

94849495
let payment_paths = match self.create_blinded_payment_paths(
@@ -9487,8 +9498,8 @@ where
94879498
Ok(payment_paths) => payment_paths,
94889499
Err(()) => {
94899500
let error = Bolt12SemanticError::MissingPaths;
9490-
return Some(OffersMessage::InvoiceError(error.into()));
9491-
},
9501+
return respond(OffersMessage::InvoiceError(error.into()));
9502+
}
94929503
};
94939504

94949505
#[cfg(not(feature = "std"))]
@@ -9565,6 +9576,11 @@ where
95659576
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
95669577
None
95679578
},
9579+
};
9580+
9581+
match response_opt {
9582+
Some(response) => respond(response),
9583+
None => ResponseInstruction::NoResponse
95689584
}
95699585
}
95709586

lightning/src/ln/peer_handler.rs

Lines changed: 8 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};
31+
use crate::onion_message::messenger::{CustomOnionMessageHandler, PendingOnionMessage, Responder, ResponseInstruction};
3232
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
3333
use crate::onion_message::packet::OnionMessageContents;
3434
use crate::routing::gossip::{NodeId, NodeAlias};
@@ -120,6 +120,7 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
120120
}
121121
fn processing_queue_high(&self) -> bool { false }
122122
}
123+
123124
impl OnionMessageHandler for IgnoringMessageHandler {
124125
fn handle_onion_message(&self, _their_node_id: &PublicKey, _msg: &msgs::OnionMessage) {}
125126
fn next_onion_message_for_peer(&self, _peer_node_id: PublicKey) -> Option<msgs::OnionMessage> { None }
@@ -131,12 +132,15 @@ impl OnionMessageHandler for IgnoringMessageHandler {
131132
InitFeatures::empty()
132133
}
133134
}
135+
134136
impl OffersMessageHandler for IgnoringMessageHandler {
135-
fn handle_message(&self, _msg: OffersMessage) -> Option<OffersMessage> { None }
137+
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder<OffersMessage>>) -> ResponseInstruction<OffersMessage> {
138+
ResponseInstruction::NoResponse
139+
}
136140
}
137141
impl CustomOnionMessageHandler for IgnoringMessageHandler {
138142
type CustomMessage = Infallible;
139-
fn handle_custom_message(&self, _msg: Infallible) -> Option<Infallible> {
143+
fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option<Responder<Self::CustomMessage>>) -> ResponseInstruction<Self::CustomMessage> {
140144
// Since we always return `None` in the read the handle method should never be called.
141145
unreachable!();
142146
}
@@ -150,6 +154,7 @@ impl CustomOnionMessageHandler for IgnoringMessageHandler {
150154

151155
impl OnionMessageContents for Infallible {
152156
fn tlv_type(&self) -> u64 { unreachable!(); }
157+
fn msg_type(&self) -> &'static str { unreachable!(); }
153158
}
154159

155160
impl Deref for IgnoringMessageHandler {

lightning/src/onion_message/functional_tests.rs

Lines changed: 18 additions & 8 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, SendError};
21+
use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction, SendError};
2222
use super::offers::{OffersMessage, OffersMessageHandler};
2323
use super::packet::{OnionMessageContents, Packet};
2424

@@ -61,8 +61,8 @@ struct MessengerNode {
6161
struct TestOffersMessageHandler {}
6262

6363
impl OffersMessageHandler for TestOffersMessageHandler {
64-
fn handle_message(&self, _message: OffersMessage) -> Option<OffersMessage> {
65-
None
64+
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder<OffersMessage>>) -> ResponseInstruction<OffersMessage> {
65+
ResponseInstruction::NoResponse
6666
}
6767
}
6868

@@ -84,6 +84,9 @@ impl OnionMessageContents for TestCustomMessage {
8484
TestCustomMessage::Response => CUSTOM_RESPONSE_MESSAGE_TYPE,
8585
}
8686
}
87+
fn msg_type(&self) -> &'static str {
88+
&"Custom"
89+
}
8790
}
8891

8992
impl Writeable for TestCustomMessage {
@@ -122,15 +125,19 @@ impl Drop for TestCustomMessageHandler {
122125

123126
impl CustomOnionMessageHandler for TestCustomMessageHandler {
124127
type CustomMessage = TestCustomMessage;
125-
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
128+
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder<Self::CustomMessage>>) -> ResponseInstruction<Self::CustomMessage> {
126129
match self.expected_messages.lock().unwrap().pop_front() {
127-
Some(expected_msg) => assert_eq!(expected_msg, msg),
128-
None => panic!("Unexpected message: {:?}", msg),
130+
Some(expected_msg) => assert_eq!(expected_msg, message),
131+
None => panic!("Unexpected message: {:?}", message),
129132
}
130-
131-
match msg {
133+
let response_option = match message {
132134
TestCustomMessage::Request => Some(TestCustomMessage::Response),
133135
TestCustomMessage::Response => None,
136+
};
137+
if let (Some(response), Some(responder)) = (response_option, responder) {
138+
responder.respond(response)
139+
} else {
140+
ResponseInstruction::NoResponse
134141
}
135142
}
136143
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {
@@ -420,6 +427,9 @@ fn invalid_custom_message_type() {
420427
// Onion message contents must have a TLV >= 64.
421428
63
422429
}
430+
fn msg_type(&self) -> &'static str {
431+
&"Invalid"
432+
}
423433
}
424434

425435
impl Writeable for InvalidCustomMessage {

lightning/src/onion_message/messenger.rs

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
135135
/// # let your_custom_message_type = 42;
136136
/// your_custom_message_type
137137
/// }
138+
/// fn msg_type(&self) -> &'static str { &"YourCustomMessageType" }
138139
/// }
139140
/// // Send a custom onion message to a node id.
140141
/// let destination = Destination::Node(destination_node_id);
@@ -557,7 +558,7 @@ pub trait CustomOnionMessageHandler {
557558
/// Called with the custom message that was received, returning a response to send, if any.
558559
///
559560
/// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
560-
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage>;
561+
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder<Self::CustomMessage>>) -> ResponseInstruction<Self::CustomMessage>;
561562

562563
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
563564
/// message type is unknown.
@@ -893,19 +894,12 @@ where
893894
}
894895

895896
fn handle_onion_message_response<T: OnionMessageContents>(
896-
&self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
897+
&self, response: ResponseInstruction<T>, log_suffix: fmt::Arguments
897898
) {
898-
if let Some(response) = response {
899-
match reply_path {
900-
Some(reply_path) => {
901-
let _ = self.find_path_and_enqueue_onion_message(
902-
response, Destination::BlindedPath(reply_path), None, log_suffix
903-
);
904-
},
905-
None => {
906-
log_trace!(self.logger, "Missing reply path {}", log_suffix);
907-
},
908-
}
899+
if let ResponseInstruction::WithoutReplyPath(response) = response {
900+
let _ = self.find_path_and_enqueue_onion_message(
901+
response.message, Destination::BlindedPath(response.reply_path), None, log_suffix
902+
);
909903
}
910904
}
911905

@@ -985,24 +979,25 @@ where
985979
"Received an onion message with path_id {:02x?} and {} reply_path: {:?}",
986980
path_id, if reply_path.is_some() { "a" } else { "no" }, message);
987981

982+
let message_type = message.msg_type();
988983
match message {
989984
ParsedOnionMessageContents::Offers(msg) => {
990-
let response = self.offers_handler.handle_message(msg);
991-
self.handle_onion_message_response(
992-
response, reply_path, format_args!(
993-
"when responding to Offers onion message with path_id {:02x?}",
994-
path_id
995-
)
996-
);
985+
let responder = reply_path.map(|path| Responder::new(path));
986+
let response_instructions = self.offers_handler.handle_message(msg, responder);
987+
self.handle_onion_message_response(response_instructions, format_args!(
988+
"when responding to {} onion message with path_id {:02x?}",
989+
message_type,
990+
path_id
991+
))
997992
},
998993
ParsedOnionMessageContents::Custom(msg) => {
999-
let response = self.custom_handler.handle_custom_message(msg);
1000-
self.handle_onion_message_response(
1001-
response, reply_path, format_args!(
1002-
"when responding to Custom onion message with path_id {:02x?}",
1003-
path_id
1004-
)
1005-
);
994+
let responder = reply_path.map(|path| Responder::new(path));
995+
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
996+
self.handle_onion_message_response(response_instructions, format_args!(
997+
"when responding to {} onion message with path_id {:02x?}",
998+
message_type,
999+
path_id
1000+
))
10061001
},
10071002
}
10081003
},

lightning/src/onion_message/offers.rs

Lines changed: 5 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;
24+
use crate::onion_message::messenger::{PendingOnionMessage, ResponseInstruction, Responder};
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(&self, message: OffersMessage) -> Option<OffersMessage>;
43+
fn handle_message(&self, message: OffersMessage, responder: Option<Responder<OffersMessage>>) -> ResponseInstruction<OffersMessage>;
4444

4545
/// Releases any [`OffersMessage`]s that need to be sent.
4646
///
@@ -118,6 +118,9 @@ impl OnionMessageContents for OffersMessage {
118118
OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
119119
}
120120
}
121+
fn msg_type(&self) -> &'static str {
122+
&"Offers"
123+
}
121124
}
122125

123126
impl Writeable for OffersMessage {

lightning/src/onion_message/packet.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContent
135135
&ParsedOnionMessageContents::Custom(ref msg) => msg.tlv_type(),
136136
}
137137
}
138+
fn msg_type(&self) -> &'static str {
139+
match self {
140+
&ParsedOnionMessageContents::Offers(ref msg) => msg.msg_type(),
141+
&ParsedOnionMessageContents::Custom(ref msg) => msg.msg_type(),
142+
}
143+
}
138144
}
139145

140146
impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
@@ -150,6 +156,9 @@ impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
150156
pub trait OnionMessageContents: Writeable + core::fmt::Debug {
151157
/// Returns the TLV type identifying the message contents. MUST be >= 64.
152158
fn tlv_type(&self) -> u64;
159+
160+
/// Returns the message type
161+
fn msg_type(&self) -> &'static str;
153162
}
154163

155164
/// Forward control TLVs in their blinded and unblinded form.

0 commit comments

Comments
 (0)