Skip to content

Commit 45c0843

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 67c47b7 commit 45c0843

File tree

7 files changed

+90
-53
lines changed

7 files changed

+90
-53
lines changed

fuzz/src/onion_message.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerP
1616
use lightning::util::test_channel_signer::TestChannelSigner;
1717
use lightning::util::logger::Logger;
1818
use lightning::util::ser::{Readable, Writeable, Writer};
19-
use lightning::onion_message::messenger::{CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, PendingOnionMessage};
19+
use lightning::onion_message::messenger::{CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction};
2020
use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
2121
use lightning::onion_message::packet::OnionMessageContents;
2222

@@ -97,8 +97,8 @@ impl MessageRouter for TestMessageRouter {
9797
struct TestOffersMessageHandler {}
9898

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

@@ -112,6 +112,9 @@ impl OnionMessageContents for TestCustomMessage {
112112
fn tlv_type(&self) -> u64 {
113113
CUSTOM_MESSAGE_TYPE
114114
}
115+
fn msg_type() -> &'static str {
116+
"Custom"
117+
}
115118
}
116119

117120
impl Writeable for TestCustomMessage {
@@ -124,8 +127,11 @@ struct TestCustomMessageHandler {}
124127

125128
impl CustomOnionMessageHandler for TestCustomMessageHandler {
126129
type CustomMessage = TestCustomMessage;
127-
fn handle_custom_message(&self, _msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
128-
Some(TestCustomMessage {})
130+
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
131+
match responder {
132+
Some(responder) => responder.respond(message),
133+
None => ResponseInstruction::NoResponse
134+
}
129135
}
130136
fn read_custom_message<R: io::Read>(&self, _message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
131137
let mut buf = Vec::new();

lightning/src/ln/channelmanager.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
6464
use crate::offers::offer::{Offer, OfferBuilder};
6565
use crate::offers::parse::Bolt12SemanticError;
6666
use crate::offers::refund::{Refund, RefundBuilder};
67-
use crate::onion_message::messenger::{Destination, MessageRouter, PendingOnionMessage, new_pending_onion_message};
67+
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction};
6868
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
6969
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
7070
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
@@ -75,6 +75,7 @@ use crate::util::string::UntrustedString;
7575
use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
7676
use crate::util::logger::{Level, Logger, WithContext};
7777
use crate::util::errors::APIError;
78+
7879
#[cfg(not(c_bindings))]
7980
use {
8081
crate::offers::offer::DerivedMetadata,
@@ -10337,23 +10338,27 @@ where
1033710338
R::Target: Router,
1033810339
L::Target: Logger,
1033910340
{
10340-
fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage> {
10341+
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
1034110342
let secp_ctx = &self.secp_ctx;
1034210343
let expanded_key = &self.inbound_payment_key;
1034310344

1034410345
match message {
1034510346
OffersMessage::InvoiceRequest(invoice_request) => {
10347+
let responder = match responder {
10348+
Some(responder) => responder,
10349+
None => return ResponseInstruction::NoResponse,
10350+
};
1034610351
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
1034710352
&invoice_request
1034810353
) {
1034910354
Ok(amount_msats) => amount_msats,
10350-
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
10355+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
1035110356
};
1035210357
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
1035310358
Ok(invoice_request) => invoice_request,
1035410359
Err(()) => {
1035510360
let error = Bolt12SemanticError::InvalidMetadata;
10356-
return Some(OffersMessage::InvoiceError(error.into()));
10361+
return responder.respond(OffersMessage::InvoiceError(error.into()));
1035710362
},
1035810363
};
1035910364

@@ -10364,7 +10369,7 @@ where
1036410369
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
1036510370
Err(()) => {
1036610371
let error = Bolt12SemanticError::InvalidAmount;
10367-
return Some(OffersMessage::InvoiceError(error.into()));
10372+
return responder.respond(OffersMessage::InvoiceError(error.into()));
1036810373
},
1036910374
};
1037010375

@@ -10378,7 +10383,7 @@ where
1037810383
Ok(payment_paths) => payment_paths,
1037910384
Err(()) => {
1038010385
let error = Bolt12SemanticError::MissingPaths;
10381-
return Some(OffersMessage::InvoiceError(error.into()));
10386+
return responder.respond(OffersMessage::InvoiceError(error.into()));
1038210387
},
1038310388
};
1038410389

@@ -10423,8 +10428,8 @@ where
1042310428
};
1042410429

1042510430
match response {
10426-
Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
10427-
Err(error) => Some(OffersMessage::InvoiceError(error.into())),
10431+
Ok(invoice) => return responder.respond(OffersMessage::Invoice(invoice)),
10432+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
1042810433
}
1042910434
},
1043010435
OffersMessage::Invoice(invoice) => {
@@ -10444,14 +10449,21 @@ where
1044410449
}
1044510450
});
1044610451

10447-
match response {
10448-
Ok(()) => None,
10449-
Err(e) => Some(OffersMessage::InvoiceError(e)),
10452+
match (responder, response) {
10453+
(Some(responder), Err(e)) => responder.respond(OffersMessage::InvoiceError(e)),
10454+
(None, Err(_)) => {
10455+
log_trace!(
10456+
self.logger,
10457+
"A response was generated, but there is no reply_path specified for sending the response."
10458+
);
10459+
return ResponseInstruction::NoResponse;
10460+
}
10461+
_ => return ResponseInstruction::NoResponse,
1045010462
}
1045110463
},
1045210464
OffersMessage::InvoiceError(invoice_error) => {
1045310465
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
10454-
None
10466+
return ResponseInstruction::NoResponse;
1045510467
},
1045610468
}
1045710469
}

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};
@@ -123,6 +123,7 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
123123
}
124124
fn processing_queue_high(&self) -> bool { false }
125125
}
126+
126127
impl OnionMessageHandler for IgnoringMessageHandler {
127128
fn handle_onion_message(&self, _their_node_id: &PublicKey, _msg: &msgs::OnionMessage) {}
128129
fn next_onion_message_for_peer(&self, _peer_node_id: PublicKey) -> Option<msgs::OnionMessage> { None }
@@ -134,12 +135,15 @@ impl OnionMessageHandler for IgnoringMessageHandler {
134135
InitFeatures::empty()
135136
}
136137
}
138+
137139
impl OffersMessageHandler for IgnoringMessageHandler {
138-
fn handle_message(&self, _msg: OffersMessage) -> Option<OffersMessage> { None }
140+
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
141+
ResponseInstruction::NoResponse
142+
}
139143
}
140144
impl CustomOnionMessageHandler for IgnoringMessageHandler {
141145
type CustomMessage = Infallible;
142-
fn handle_custom_message(&self, _msg: Infallible) -> Option<Infallible> {
146+
fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
143147
// Since we always return `None` in the read the handle method should never be called.
144148
unreachable!();
145149
}
@@ -153,6 +157,7 @@ impl CustomOnionMessageHandler for IgnoringMessageHandler {
153157

154158
impl OnionMessageContents for Infallible {
155159
fn tlv_type(&self) -> u64 { unreachable!(); }
160+
fn msg_type() -> &'static str { unreachable!(); }
156161
}
157162

158163
impl Deref for IgnoringMessageHandler {

lightning/src/onion_message/functional_tests.rs

Lines changed: 16 additions & 6 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

@@ -62,8 +62,8 @@ struct MessengerNode {
6262
struct TestOffersMessageHandler {}
6363

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

@@ -85,6 +85,9 @@ impl OnionMessageContents for TestCustomMessage {
8585
TestCustomMessage::Response => CUSTOM_RESPONSE_MESSAGE_TYPE,
8686
}
8787
}
88+
fn msg_type() -> &'static str {
89+
"Custom"
90+
}
8891
}
8992

9093
impl Writeable for TestCustomMessage {
@@ -123,15 +126,19 @@ impl Drop for TestCustomMessageHandler {
123126

124127
impl CustomOnionMessageHandler for TestCustomMessageHandler {
125128
type CustomMessage = TestCustomMessage;
126-
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
129+
fn handle_custom_message(&self, msg: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
127130
match self.expected_messages.lock().unwrap().pop_front() {
128131
Some(expected_msg) => assert_eq!(expected_msg, msg),
129132
None => panic!("Unexpected message: {:?}", msg),
130133
}
131-
132-
match msg {
134+
let response_option = match msg {
133135
TestCustomMessage::Request => Some(TestCustomMessage::Response),
134136
TestCustomMessage::Response => None,
137+
};
138+
if let (Some(response), Some(responder)) = (response_option, responder) {
139+
responder.respond(response)
140+
} else {
141+
ResponseInstruction::NoResponse
135142
}
136143
}
137144
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {
@@ -422,6 +429,9 @@ fn invalid_custom_message_type() {
422429
// Onion message contents must have a TLV >= 64.
423430
63
424431
}
432+
fn msg_type() -> &'static str {
433+
"Invalid"
434+
}
425435
}
426436

427437
impl Writeable for InvalidCustomMessage {

lightning/src/onion_message/messenger.rs

Lines changed: 20 additions & 26 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() -> &'static str { "YourCustomMessageType" }
138139
/// }
139140
/// // Send a custom onion message to a node id.
140141
/// let destination = Destination::Node(destination_node_id);
@@ -275,7 +276,6 @@ impl Responder {
275276
}
276277

277278
/// This struct contains the information needed to reply to a received message.
278-
#[allow(unused)]
279279
pub struct OnionMessageResponse<T: OnionMessageContents> {
280280
message: T,
281281
reply_path: BlindedPath,
@@ -591,7 +591,7 @@ pub trait CustomOnionMessageHandler {
591591
/// Called with the custom message that was received, returning a response to send, if any.
592592
///
593593
/// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
594-
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage>;
594+
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage>;
595595

596596
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
597597
/// message type is unknown.
@@ -978,19 +978,17 @@ where
978978
}
979979

980980
fn handle_onion_message_response<T: OnionMessageContents>(
981-
&self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
981+
&self, response: ResponseInstruction<T>
982982
) {
983-
if let Some(response) = response {
984-
match reply_path {
985-
Some(reply_path) => {
986-
let _ = self.find_path_and_enqueue_onion_message(
987-
response, Destination::BlindedPath(reply_path), None, log_suffix
988-
);
989-
},
990-
None => {
991-
log_trace!(self.logger, "Missing reply path {}", log_suffix);
992-
},
993-
}
983+
if let ResponseInstruction::WithoutReplyPath(response) = response {
984+
let _ = self.find_path_and_enqueue_onion_message(
985+
response.message, Destination::BlindedPath(response.reply_path), None,
986+
format_args!(
987+
"when responding to {} onion message with path_id {:02x?}",
988+
T::msg_type(),
989+
response.path_id
990+
)
991+
);
994992
}
995993
}
996994

@@ -1074,22 +1072,18 @@ where
10741072

10751073
match message {
10761074
ParsedOnionMessageContents::Offers(msg) => {
1077-
let response = self.offers_handler.handle_message(msg);
1078-
self.handle_onion_message_response(
1079-
response, reply_path, format_args!(
1080-
"when responding to Offers onion message with path_id {:02x?}",
1081-
path_id
1082-
)
1075+
let responder = reply_path.map(
1076+
|reply_path| Responder::new(reply_path, path_id)
10831077
);
1078+
let response_instructions = self.offers_handler.handle_message(msg, responder);
1079+
self.handle_onion_message_response(response_instructions);
10841080
},
10851081
ParsedOnionMessageContents::Custom(msg) => {
1086-
let response = self.custom_handler.handle_custom_message(msg);
1087-
self.handle_onion_message_response(
1088-
response, reply_path, format_args!(
1089-
"when responding to Custom onion message with path_id {:02x?}",
1090-
path_id
1091-
)
1082+
let responder = reply_path.map(
1083+
|reply_path| Responder::new(reply_path, path_id)
10921084
);
1085+
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
1086+
self.handle_onion_message_response(response_instructions);
10931087
},
10941088
}
10951089
},

lightning/src/onion_message/offers.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::offers::parse::Bolt12ParseError;
1919
use crate::onion_message::packet::OnionMessageContents;
2020
use crate::util::logger::Logger;
2121
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
22+
use crate::onion_message::messenger::{ResponseInstruction, Responder};
2223
#[cfg(not(c_bindings))]
2324
use crate::onion_message::messenger::PendingOnionMessage;
2425

@@ -39,7 +40,7 @@ pub trait OffersMessageHandler {
3940
/// The returned [`OffersMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
4041
///
4142
/// [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger
42-
fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage>;
43+
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>) -> ResponseInstruction<OffersMessage>;
4344

4445
/// Releases any [`OffersMessage`]s that need to be sent.
4546
///
@@ -117,6 +118,9 @@ impl OnionMessageContents for OffersMessage {
117118
OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
118119
}
119120
}
121+
fn msg_type() -> &'static str {
122+
"Offers"
123+
}
120124
}
121125

122126
impl Writeable for OffersMessage {

lightning/src/onion_message/packet.rs

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

140143
impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
@@ -150,6 +153,9 @@ impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
150153
pub trait OnionMessageContents: Writeable + core::fmt::Debug {
151154
/// Returns the TLV type identifying the message contents. MUST be >= 64.
152155
fn tlv_type(&self) -> u64;
156+
157+
/// Returns the message type
158+
fn msg_type() -> &'static str;
153159
}
154160

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

0 commit comments

Comments
 (0)