Skip to content

Commit 15d016a

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 e640951 commit 15d016a

File tree

7 files changed

+100
-55
lines changed

7 files changed

+100
-55
lines changed

fuzz/src/onion_message.rs

Lines changed: 13 additions & 7 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(&self) -> &'static str {
116+
"Custom Message"
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();
@@ -280,9 +286,9 @@ mod tests {
280286
"Received an onion message with path_id None and a reply_path: Custom(TestCustomMessage)"
281287
.to_string())), Some(&1));
282288
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
283-
"Constructing onion message when responding to Custom onion message with path_id None: TestCustomMessage".to_string())), Some(&1));
289+
"Constructing onion message when responding with Custom Message to an onion message with path_id None: TestCustomMessage".to_string())), Some(&1));
284290
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
285-
"Buffered onion message when responding to Custom onion message with path_id None".to_string())), Some(&1));
291+
"Buffered onion message when responding with Custom Message to an onion message with path_id None".to_string())), Some(&1));
286292
}
287293

288294
let two_unblinded_hops_om = "\

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,
@@ -10332,23 +10333,27 @@ where
1033210333
R::Target: Router,
1033310334
L::Target: Logger,
1033410335
{
10335-
fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage> {
10336+
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
1033610337
let secp_ctx = &self.secp_ctx;
1033710338
let expanded_key = &self.inbound_payment_key;
1033810339

1033910340
match message {
1034010341
OffersMessage::InvoiceRequest(invoice_request) => {
10342+
let responder = match responder {
10343+
Some(responder) => responder,
10344+
None => return ResponseInstruction::NoResponse,
10345+
};
1034110346
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
1034210347
&invoice_request
1034310348
) {
1034410349
Ok(amount_msats) => amount_msats,
10345-
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
10350+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
1034610351
};
1034710352
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
1034810353
Ok(invoice_request) => invoice_request,
1034910354
Err(()) => {
1035010355
let error = Bolt12SemanticError::InvalidMetadata;
10351-
return Some(OffersMessage::InvoiceError(error.into()));
10356+
return responder.respond(OffersMessage::InvoiceError(error.into()));
1035210357
},
1035310358
};
1035410359

@@ -10359,7 +10364,7 @@ where
1035910364
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
1036010365
Err(()) => {
1036110366
let error = Bolt12SemanticError::InvalidAmount;
10362-
return Some(OffersMessage::InvoiceError(error.into()));
10367+
return responder.respond(OffersMessage::InvoiceError(error.into()));
1036310368
},
1036410369
};
1036510370

@@ -10373,7 +10378,7 @@ where
1037310378
Ok(payment_paths) => payment_paths,
1037410379
Err(()) => {
1037510380
let error = Bolt12SemanticError::MissingPaths;
10376-
return Some(OffersMessage::InvoiceError(error.into()));
10381+
return responder.respond(OffersMessage::InvoiceError(error.into()));
1037710382
},
1037810383
};
1037910384

@@ -10418,8 +10423,8 @@ where
1041810423
};
1041910424

1042010425
match response {
10421-
Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
10422-
Err(error) => Some(OffersMessage::InvoiceError(error.into())),
10426+
Ok(invoice) => return responder.respond(OffersMessage::Invoice(invoice)),
10427+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
1042310428
}
1042410429
},
1042510430
OffersMessage::Invoice(invoice) => {
@@ -10439,14 +10444,21 @@ where
1043910444
}
1044010445
});
1044110446

10442-
match response {
10443-
Ok(()) => None,
10444-
Err(e) => Some(OffersMessage::InvoiceError(e)),
10447+
match (responder, response) {
10448+
(Some(responder), Err(e)) => responder.respond(OffersMessage::InvoiceError(e)),
10449+
(None, Err(_)) => {
10450+
log_trace!(
10451+
self.logger,
10452+
"A response was generated, but there is no reply_path specified for sending the response."
10453+
);
10454+
return ResponseInstruction::NoResponse;
10455+
}
10456+
_ => return ResponseInstruction::NoResponse,
1044510457
}
1044610458
},
1044710459
OffersMessage::InvoiceError(invoice_error) => {
1044810460
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
10449-
None
10461+
return ResponseInstruction::NoResponse;
1045010462
},
1045110463
}
1045210464
}

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(&self) -> &'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(&self) -> &'static str {
89+
"Custom Message"
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(&self) -> &'static str {
433+
"Invalid Message"
434+
}
425435
}
426436

427437
impl Writeable for InvalidCustomMessage {

lightning/src/onion_message/messenger.rs

Lines changed: 21 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(&self) -> &'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,18 @@ 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 message_type = response.message.msg_type();
985+
let _ = self.find_path_and_enqueue_onion_message(
986+
response.message, Destination::BlindedPath(response.reply_path), None,
987+
format_args!(
988+
"when responding with {} to an onion message with path_id {:02x?}",
989+
message_type,
990+
response.path_id
991+
)
992+
);
994993
}
995994
}
996995

@@ -1074,22 +1073,18 @@ where
10741073

10751074
match message {
10761075
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-
)
1076+
let responder = reply_path.map(
1077+
|reply_path| Responder::new(reply_path, path_id)
10831078
);
1079+
let response_instructions = self.offers_handler.handle_message(msg, responder);
1080+
self.handle_onion_message_response(response_instructions);
10841081
},
10851082
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-
)
1083+
let responder = reply_path.map(
1084+
|reply_path| Responder::new(reply_path, path_id)
10921085
);
1086+
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
1087+
self.handle_onion_message_response(response_instructions);
10931088
},
10941089
}
10951090
},

lightning/src/onion_message/offers.rs

Lines changed: 9 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,13 @@ impl OnionMessageContents for OffersMessage {
117118
OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
118119
}
119120
}
121+
fn msg_type(&self) -> &'static str {
122+
match &self {
123+
OffersMessage::InvoiceRequest(_) => "Invoice Request",
124+
OffersMessage::Invoice(_) => "Invoice",
125+
OffersMessage::InvoiceError(_) => "Invoice Error",
126+
}
127+
}
120128
}
121129

122130
impl Writeable for OffersMessage {

0 commit comments

Comments
 (0)