Skip to content

Commit 5b05294

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 5b05294

File tree

7 files changed

+106
-63
lines changed

7 files changed

+106
-63
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+
"CustomMessageType"
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: 33 additions & 17 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,32 @@ 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>
9455+
{
94549456
let secp_ctx = &self.secp_ctx;
94559457
let expanded_key = &self.inbound_payment_key;
94569458

94579459
match message {
94589460
OffersMessage::InvoiceRequest(invoice_request) => {
9461+
let responder = match responder {
9462+
Some(responder) => responder,
9463+
None => return ResponseInstruction::NoResponse,
9464+
};
9465+
94599466
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
94609467
&invoice_request
94619468
) {
94629469
Ok(amount_msats) => amount_msats,
9463-
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
9470+
Err(error) => {
9471+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9472+
}
94649473
};
94659474
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
94669475
Ok(invoice_request) => invoice_request,
94679476
Err(()) => {
94689477
let error = Bolt12SemanticError::InvalidMetadata;
9469-
return Some(OffersMessage::InvoiceError(error.into()));
9470-
},
9478+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9479+
}
94719480
};
94729481

94739482
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
@@ -9477,8 +9486,8 @@ where
94779486
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
94789487
Err(()) => {
94799488
let error = Bolt12SemanticError::InvalidAmount;
9480-
return Some(OffersMessage::InvoiceError(error.into()));
9481-
},
9489+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9490+
}
94829491
};
94839492

94849493
let payment_paths = match self.create_blinded_payment_paths(
@@ -9487,8 +9496,8 @@ where
94879496
Ok(payment_paths) => payment_paths,
94889497
Err(()) => {
94899498
let error = Bolt12SemanticError::MissingPaths;
9490-
return Some(OffersMessage::InvoiceError(error.into()));
9491-
},
9499+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9500+
}
94929501
};
94939502

94949503
#[cfg(not(feature = "std"))]
@@ -9508,8 +9517,8 @@ where
95089517
let builder: Result<InvoiceBuilder<DerivedSigningPubkey>, _> =
95099518
builder.map(|b| b.into());
95109519
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())),
9520+
Ok(invoice) => return responder.respond(OffersMessage::Invoice(invoice)),
9521+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
95139522
}
95149523
} else {
95159524
#[cfg(feature = "std")]
@@ -9538,13 +9547,14 @@ where
95389547
}
95399548
});
95409549
match response {
9541-
Ok(invoice) => Some(invoice),
9542-
Err(error) => Some(error),
9550+
Ok(invoice) => return responder.respond(invoice),
9551+
Err(error) => return responder.respond(error),
95439552
}
9544-
}
9553+
};
95459554
},
9555+
95469556
OffersMessage::Invoice(invoice) => {
9547-
match invoice.verify(expanded_key, secp_ctx) {
9557+
let response = match invoice.verify(expanded_key, secp_ctx) {
95489558
Err(()) => {
95499559
Some(OffersMessage::InvoiceError(InvoiceError::from_string("Unrecognized invoice".to_owned())))
95509560
},
@@ -9559,13 +9569,19 @@ where
95599569
None
95609570
}
95619571
},
9572+
};
9573+
9574+
match (responder, response) {
9575+
(Some(responder), Some(response)) => return responder.respond(response),
9576+
_ => return ResponseInstruction::NoResponse
95629577
}
95639578
},
9579+
95649580
OffersMessage::InvoiceError(invoice_error) => {
95659581
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
9566-
None
9582+
return ResponseInstruction::NoResponse
95679583
},
9568-
}
9584+
};
95699585
}
95709586

95719587
fn release_pending_messages(&self) -> Vec<PendingOnionMessage<OffersMessage>> {

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

0 commit comments

Comments
 (0)