Skip to content

Commit 704074c

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 f9e4b83 commit 704074c

File tree

7 files changed

+108
-58
lines changed

7 files changed

+108
-58
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

@@ -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>) -> ResponseInstruction<OffersMessage> {
100+
ResponseInstruction::NoResponse
101101
}
102102
}
103103

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

116119
impl Writeable for TestCustomMessage {
@@ -123,8 +126,11 @@ struct TestCustomMessageHandler {}
123126

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

lightning/src/ln/channelmanager.rs

Lines changed: 37 additions & 15 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,31 @@ 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>) -> ResponseInstruction<OffersMessage> {
94549455
let secp_ctx = &self.secp_ctx;
94559456
let expanded_key = &self.inbound_payment_key;
94569457

94579458
match message {
94589459
OffersMessage::InvoiceRequest(invoice_request) => {
9460+
let responder = match responder {
9461+
Some(responder) => responder,
9462+
None => return ResponseInstruction::NoResponse,
9463+
};
9464+
94599465
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
94609466
&invoice_request
94619467
) {
94629468
Ok(amount_msats) => amount_msats,
9463-
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
9469+
Err(error) => {
9470+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9471+
}
94649472
};
94659473
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
94669474
Ok(invoice_request) => invoice_request,
94679475
Err(()) => {
94689476
let error = Bolt12SemanticError::InvalidMetadata;
9469-
return Some(OffersMessage::InvoiceError(error.into()));
9470-
},
9477+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9478+
}
94719479
};
94729480

94739481
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
@@ -9477,8 +9485,8 @@ where
94779485
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
94789486
Err(()) => {
94799487
let error = Bolt12SemanticError::InvalidAmount;
9480-
return Some(OffersMessage::InvoiceError(error.into()));
9481-
},
9488+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9489+
}
94829490
};
94839491

94849492
let payment_paths = match self.create_blinded_payment_paths(
@@ -9487,8 +9495,8 @@ where
94879495
Ok(payment_paths) => payment_paths,
94889496
Err(()) => {
94899497
let error = Bolt12SemanticError::MissingPaths;
9490-
return Some(OffersMessage::InvoiceError(error.into()));
9491-
},
9498+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9499+
}
94929500
};
94939501

94949502
#[cfg(not(feature = "std"))]
@@ -9508,8 +9516,8 @@ where
95089516
let builder: Result<InvoiceBuilder<DerivedSigningPubkey>, _> =
95099517
builder.map(|b| b.into());
95109518
match builder.and_then(|b| b.allow_mpp().build_and_sign(secp_ctx)) {
9511-
Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
9512-
Err(error) => Some(OffersMessage::InvoiceError(error.into())),
9519+
Ok(invoice) => return responder.respond(OffersMessage::Invoice(invoice)),
9520+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
95139521
}
95149522
} else {
95159523
#[cfg(feature = "std")]
@@ -9538,13 +9546,14 @@ where
95389546
}
95399547
});
95409548
match response {
9541-
Ok(invoice) => Some(invoice),
9542-
Err(error) => Some(error),
9549+
Ok(invoice) => return responder.respond(invoice),
9550+
Err(error) => return responder.respond(error),
95439551
}
95449552
}
95459553
},
9554+
95469555
OffersMessage::Invoice(invoice) => {
9547-
match invoice.verify(expanded_key, secp_ctx) {
9556+
let response = match invoice.verify(expanded_key, secp_ctx) {
95489557
Err(()) => {
95499558
Some(OffersMessage::InvoiceError(InvoiceError::from_string("Unrecognized invoice".to_owned())))
95509559
},
@@ -9559,11 +9568,24 @@ where
95599568
None
95609569
}
95619570
},
9571+
};
9572+
9573+
match (responder, response) {
9574+
(Some(responder), Some(response)) => return responder.respond(response),
9575+
(None, Some(_)) => {
9576+
log_trace!(
9577+
self.logger,
9578+
"A response was generated, but there is no reply_path specified for sending the response."
9579+
);
9580+
return ResponseInstruction::NoResponse
9581+
},
9582+
_ => return ResponseInstruction::NoResponse
95629583
}
95639584
},
9585+
95649586
OffersMessage::InvoiceError(invoice_error) => {
95659587
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
9566-
None
9588+
return ResponseInstruction::NoResponse
95679589
},
95689590
}
95699591
}

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>) -> 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>) -> 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: 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

@@ -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>) -> 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, msg: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
126129
match self.expected_messages.lock().unwrap().pop_front() {
127130
Some(expected_msg) => assert_eq!(expected_msg, msg),
128131
None => panic!("Unexpected message: {:?}", msg),
129132
}
130-
131-
match msg {
133+
let response_option = match msg {
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 & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
134134
/// # let your_custom_message_type = 42;
135135
/// your_custom_message_type
136136
/// }
137+
/// fn msg_type(&self) -> &'static str { "YourCustomMessageType" }
137138
/// }
138139
/// // Send a custom onion message to a node id.
139140
/// let destination = Destination::Node(destination_node_id);
@@ -269,7 +270,6 @@ impl Responder {
269270
}
270271

271272
/// This struct contains the information needed to reply to a received message.
272-
#[allow(unused)]
273273
pub struct OnionMessageResponse<T: OnionMessageContents> {
274274
message: T,
275275
reply_path: BlindedPath,
@@ -552,7 +552,7 @@ pub trait CustomOnionMessageHandler {
552552
/// Called with the custom message that was received, returning a response to send, if any.
553553
///
554554
/// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
555-
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage>;
555+
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage>;
556556

557557
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
558558
/// message type is unknown.
@@ -888,19 +888,12 @@ where
888888
}
889889

890890
fn handle_onion_message_response<T: OnionMessageContents>(
891-
&self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
891+
&self, response: ResponseInstruction<T>, log_suffix: fmt::Arguments
892892
) {
893-
if let Some(response) = response {
894-
match reply_path {
895-
Some(reply_path) => {
896-
let _ = self.find_path_and_enqueue_onion_message(
897-
response, Destination::BlindedPath(reply_path), None, log_suffix
898-
);
899-
},
900-
None => {
901-
log_trace!(self.logger, "Missing reply path {}", log_suffix);
902-
},
903-
}
893+
if let ResponseInstruction::WithoutReplyPath(response) = response {
894+
let _ = self.find_path_and_enqueue_onion_message(
895+
response.message, Destination::BlindedPath(response.reply_path), None, log_suffix
896+
);
904897
}
905898
}
906899

@@ -980,24 +973,25 @@ where
980973
"Received an onion message with path_id {:02x?} and {} reply_path: {:?}",
981974
path_id, if reply_path.is_some() { "a" } else { "no" }, message);
982975

976+
let message_type = message.msg_type();
983977
match message {
984978
ParsedOnionMessageContents::Offers(msg) => {
985-
let response = self.offers_handler.handle_message(msg);
986-
self.handle_onion_message_response(
987-
response, reply_path, format_args!(
988-
"when responding to Offers onion message with path_id {:02x?}",
989-
path_id
990-
)
991-
);
979+
let responder = reply_path.map(|path| Responder::new(path));
980+
let response_instructions = self.offers_handler.handle_message(msg, responder);
981+
self.handle_onion_message_response(response_instructions, format_args!(
982+
"when responding to {} onion message with path_id {:02x?}",
983+
message_type,
984+
path_id
985+
))
992986
},
993987
ParsedOnionMessageContents::Custom(msg) => {
994-
let response = self.custom_handler.handle_custom_message(msg);
995-
self.handle_onion_message_response(
996-
response, reply_path, format_args!(
997-
"when responding to Custom onion message with path_id {:02x?}",
998-
path_id
999-
)
1000-
);
988+
let responder = reply_path.map(|path| Responder::new(path));
989+
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
990+
self.handle_onion_message_response(response_instructions, format_args!(
991+
"when responding to {} onion message with path_id {:02x?}",
992+
message_type,
993+
path_id
994+
))
1001995
},
1002996
}
1003997
},

lightning/src/onion_message/offers.rs

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

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

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

123127
impl Writeable for OffersMessage {

0 commit comments

Comments
 (0)