Skip to content

Commit f75e088

Browse files
committed
Introduce ReceivedOnionMessage Enum
Reasoning: 1. To expose `reply_path` and `path_id` to message handlers for various operations within functions. Logic: 1. The `ReceivedOnionMessage` enum, with variants `WithReplyPath` and `WithoutReplyPath`, exposes the message and path_id, providing a responder interface. 2. The introduced enum is passed to offers and custom message handlers. Other Changes: 1. Moved the `handle_onion_message_response` declaration to the `OnionMessageHandler` trait for use with the introduced enum and simplified function input values. 2. Revised the code flow to ensure `handle_message_response` is called only when there's a response to send and a valid `reply_path`.
1 parent d70124c commit f75e088

File tree

8 files changed

+223
-151
lines changed

8 files changed

+223
-151
lines changed

fuzz/src/onion_message.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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<OMH: OnionMessageHandler, T: OnionMessageContents>(&self, received_onion_message: &ReceivedOnionMessage<OMH, T>) {
127+
if let ReceivedOnionMessage::WithReplyPath(responder) = received_onion_message {
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: 108 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use crate::offers::merkle::SignError;
6464
use crate::offers::offer::{DerivedMetadata, 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, ReceivedOnionMessage};
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,8 @@ 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+
use super::msgs::OnionMessageHandler;
79+
7880
#[cfg(not(c_bindings))]
7981
use {
8082
crate::routing::router::DefaultRouter,
@@ -9261,124 +9263,130 @@ where
92619263
}
92629264
}
92639265

9264-
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
9265-
OffersMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, L>
9266+
impl<M: Deref, BI: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
9267+
OffersMessageHandler for ChannelManager<M, BI, ES, NS, SP, F, R, L>
92669268
where
92679269
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
9268-
T::Target: BroadcasterInterface,
9270+
BI::Target: BroadcasterInterface,
92699271
ES::Target: EntropySource,
92709272
NS::Target: NodeSigner,
92719273
SP::Target: SignerProvider,
92729274
F::Target: FeeEstimator,
92739275
R::Target: Router,
92749276
L::Target: Logger,
92759277
{
9276-
fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage> {
9278+
fn handle_message<OMH: OnionMessageHandler>(&self, received_onion_message: &ReceivedOnionMessage<OMH, OffersMessage>) {
92779279
let secp_ctx = &self.secp_ctx;
92789280
let expanded_key = &self.inbound_payment_key;
92799281

9280-
match message {
9281-
OffersMessage::InvoiceRequest(invoice_request) => {
9282-
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
9283-
&invoice_request
9284-
) {
9285-
Ok(amount_msats) => amount_msats,
9286-
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
9287-
};
9288-
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
9289-
Ok(invoice_request) => invoice_request,
9290-
Err(()) => {
9291-
let error = Bolt12SemanticError::InvalidMetadata;
9292-
return Some(OffersMessage::InvoiceError(error.into()));
9293-
},
9294-
};
9295-
9296-
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
9297-
let (payment_hash, payment_secret) = match self.create_inbound_payment(
9298-
Some(amount_msats), relative_expiry, None
9299-
) {
9300-
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
9301-
Err(()) => {
9302-
let error = Bolt12SemanticError::InvalidAmount;
9303-
return Some(OffersMessage::InvoiceError(error.into()));
9304-
},
9305-
};
9282+
if let ReceivedOnionMessage::WithReplyPath(responder) = received_onion_message {
9283+
let response_option = match &responder.message {
9284+
OffersMessage::InvoiceRequest(invoice_request) => {
9285+
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
9286+
&invoice_request
9287+
) {
9288+
Ok(amount_msats) => amount_msats,
9289+
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
9290+
};
9291+
let invoice_request = match invoice_request.clone().verify(expanded_key, secp_ctx) {
9292+
Ok(invoice_request) => invoice_request,
9293+
Err(()) => {
9294+
let error = Bolt12SemanticError::InvalidMetadata;
9295+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9296+
},
9297+
};
93069298

9307-
let payment_paths = match self.create_blinded_payment_paths(
9308-
amount_msats, payment_secret
9309-
) {
9310-
Ok(payment_paths) => payment_paths,
9311-
Err(()) => {
9312-
let error = Bolt12SemanticError::MissingPaths;
9313-
return Some(OffersMessage::InvoiceError(error.into()));
9314-
},
9315-
};
9299+
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
9300+
let (payment_hash, payment_secret) = match self.create_inbound_payment(
9301+
Some(amount_msats), relative_expiry, None
9302+
) {
9303+
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
9304+
Err(()) => {
9305+
let error = Bolt12SemanticError::InvalidAmount;
9306+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9307+
},
9308+
};
93169309

9317-
#[cfg(not(feature = "std"))]
9318-
let created_at = Duration::from_secs(
9319-
self.highest_seen_timestamp.load(Ordering::Acquire) as u64
9320-
);
9310+
let payment_paths = match self.create_blinded_payment_paths(
9311+
amount_msats, payment_secret
9312+
) {
9313+
Ok(payment_paths) => payment_paths,
9314+
Err(()) => {
9315+
let error = Bolt12SemanticError::MissingPaths;
9316+
return responder.respond(OffersMessage::InvoiceError(error.into()));
9317+
},
9318+
};
93219319

9322-
if invoice_request.keys.is_some() {
9323-
#[cfg(feature = "std")]
9324-
let builder = invoice_request.respond_using_derived_keys(
9325-
payment_paths, payment_hash
9326-
);
93279320
#[cfg(not(feature = "std"))]
9328-
let builder = invoice_request.respond_using_derived_keys_no_std(
9329-
payment_paths, payment_hash, created_at
9321+
let created_at = Duration::from_secs(
9322+
self.highest_seen_timestamp.load(Ordering::Acquire) as u64
93309323
);
9331-
match builder.and_then(|b| b.allow_mpp().build_and_sign(secp_ctx)) {
9332-
Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
9333-
Err(error) => Some(OffersMessage::InvoiceError(error.into())),
9324+
9325+
if invoice_request.keys.is_some() {
9326+
#[cfg(feature = "std")]
9327+
let builder = invoice_request.respond_using_derived_keys(
9328+
payment_paths, payment_hash
9329+
);
9330+
#[cfg(not(feature = "std"))]
9331+
let builder = invoice_request.respond_using_derived_keys_no_std(
9332+
payment_paths, payment_hash, created_at
9333+
);
9334+
match builder.and_then(|b| b.allow_mpp().build_and_sign(secp_ctx)) {
9335+
Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
9336+
Err(error) => Some(OffersMessage::InvoiceError(error.into())),
9337+
}
9338+
} else {
9339+
#[cfg(feature = "std")]
9340+
let builder = invoice_request.respond_with(payment_paths, payment_hash);
9341+
#[cfg(not(feature = "std"))]
9342+
let builder = invoice_request.respond_with_no_std(
9343+
payment_paths, payment_hash, created_at
9344+
);
9345+
let response = builder.and_then(|builder| builder.allow_mpp().build())
9346+
.map_err(|e| OffersMessage::InvoiceError(e.into()))
9347+
.and_then(|invoice|
9348+
match invoice.sign(|invoice| self.node_signer.sign_bolt12_invoice(invoice)) {
9349+
Ok(invoice) => Ok(OffersMessage::Invoice(invoice)),
9350+
Err(SignError::Signing(())) => Err(OffersMessage::InvoiceError(
9351+
InvoiceError::from_string("Failed signing invoice".to_string())
9352+
)),
9353+
Err(SignError::Verification(_)) => Err(OffersMessage::InvoiceError(
9354+
InvoiceError::from_string("Failed invoice signature verification".to_string())
9355+
)),
9356+
});
9357+
match response {
9358+
Ok(invoice) => Some(invoice),
9359+
Err(error) => Some(error),
9360+
}
93349361
}
9335-
} else {
9336-
#[cfg(feature = "std")]
9337-
let builder = invoice_request.respond_with(payment_paths, payment_hash);
9338-
#[cfg(not(feature = "std"))]
9339-
let builder = invoice_request.respond_with_no_std(
9340-
payment_paths, payment_hash, created_at
9341-
);
9342-
let response = builder.and_then(|builder| builder.allow_mpp().build())
9343-
.map_err(|e| OffersMessage::InvoiceError(e.into()))
9344-
.and_then(|invoice|
9345-
match invoice.sign(|invoice| self.node_signer.sign_bolt12_invoice(invoice)) {
9346-
Ok(invoice) => Ok(OffersMessage::Invoice(invoice)),
9347-
Err(SignError::Signing(())) => Err(OffersMessage::InvoiceError(
9348-
InvoiceError::from_string("Failed signing invoice".to_string())
9349-
)),
9350-
Err(SignError::Verification(_)) => Err(OffersMessage::InvoiceError(
9351-
InvoiceError::from_string("Failed invoice signature verification".to_string())
9352-
)),
9353-
});
9354-
match response {
9355-
Ok(invoice) => Some(invoice),
9356-
Err(error) => Some(error),
9362+
},
9363+
OffersMessage::Invoice(invoice) => {
9364+
match invoice.verify(expanded_key, secp_ctx) {
9365+
Err(()) => {
9366+
Some(OffersMessage::InvoiceError(InvoiceError::from_string("Unrecognized invoice".to_owned())))
9367+
},
9368+
Ok(_) if invoice.invoice_features().requires_unknown_bits_from(&self.bolt12_invoice_features()) => {
9369+
Some(OffersMessage::InvoiceError(Bolt12SemanticError::UnknownRequiredFeatures.into()))
9370+
},
9371+
Ok(payment_id) => {
9372+
if let Err(e) = self.send_payment_for_bolt12_invoice(&invoice, payment_id) {
9373+
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
9374+
Some(OffersMessage::InvoiceError(InvoiceError::from_string(format!("{:?}", e))))
9375+
} else {
9376+
None
9377+
}
9378+
},
93579379
}
9358-
}
9359-
},
9360-
OffersMessage::Invoice(invoice) => {
9361-
match invoice.verify(expanded_key, secp_ctx) {
9362-
Err(()) => {
9363-
Some(OffersMessage::InvoiceError(InvoiceError::from_string("Unrecognized invoice".to_owned())))
9364-
},
9365-
Ok(_) if invoice.invoice_features().requires_unknown_bits_from(&self.bolt12_invoice_features()) => {
9366-
Some(OffersMessage::InvoiceError(Bolt12SemanticError::UnknownRequiredFeatures.into()))
9367-
},
9368-
Ok(payment_id) => {
9369-
if let Err(e) = self.send_payment_for_bolt12_invoice(&invoice, payment_id) {
9370-
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
9371-
Some(OffersMessage::InvoiceError(InvoiceError::from_string(format!("{:?}", e))))
9372-
} else {
9373-
None
9374-
}
9375-
},
9376-
}
9377-
},
9378-
OffersMessage::InvoiceError(invoice_error) => {
9379-
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
9380-
None
9381-
},
9380+
},
9381+
OffersMessage::InvoiceError(invoice_error) => {
9382+
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
9383+
None
9384+
},
9385+
};
9386+
9387+
if let Some(response) = response_option {
9388+
responder.respond(response);
9389+
}
93829390
}
93839391
}
93849392

lightning/src/ln/msgs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ use bitcoin::blockdata::script::ScriptBuf;
3232
use bitcoin::hash_types::Txid;
3333

3434
use crate::blinded_path::payment::{BlindedPaymentTlvs, ForwardTlvs, ReceiveTlvs};
35+
use crate::blinded_path::BlindedPath;
3536
use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
3637
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
3738
use crate::ln::onion_utils;
3839
use crate::onion_message;
40+
use crate::onion_message::packet::OnionMessageContents;
3941
use crate::sign::{NodeSigner, Recipient};
4042

4143
use crate::prelude::*;
@@ -1590,6 +1592,8 @@ pub trait OnionMessageHandler: EventsProvider {
15901592
/// Handle an incoming `onion_message` message from the given peer.
15911593
fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage);
15921594

1595+
fn handle_onion_message_response<T: OnionMessageContents>(&self, response: T, reply_path: BlindedPath, log_suffix: fmt::Arguments);
1596+
15931597
/// Returns the next pending onion message for the peer with the given node id.
15941598
fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<OnionMessage>;
15951599

lightning/src/ln/peer_handler.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use bitcoin::blockdata::constants::ChainHash;
1919
use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey};
2020

21+
use crate::blinded_path::BlindedPath;
2122
use crate::sign::{NodeSigner, Recipient};
2223
use crate::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
2324
use crate::ln::ChannelId;
@@ -28,7 +29,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
2829
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor, NextNoiseStep, MessageBuf, MSG_BUF_ALLOC_SIZE};
2930
use crate::ln::wire;
3031
use crate::ln::wire::{Encode, Type};
31-
use crate::onion_message::messenger::{CustomOnionMessageHandler, PendingOnionMessage};
32+
use crate::onion_message::messenger::{CustomOnionMessageHandler, PendingOnionMessage, ReceivedOnionMessage};
3233
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
3334
use crate::onion_message::packet::OnionMessageContents;
3435
use crate::routing::gossip::{NodeId, NodeAlias};
@@ -120,8 +121,10 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
120121
}
121122
fn processing_queue_high(&self) -> bool { false }
122123
}
124+
123125
impl OnionMessageHandler for IgnoringMessageHandler {
124126
fn handle_onion_message(&self, _their_node_id: &PublicKey, _msg: &msgs::OnionMessage) {}
127+
fn handle_onion_message_response<T: OnionMessageContents>(&self, _response: T, _reply_path: BlindedPath, _log_suffix: fmt::Arguments) {}
125128
fn next_onion_message_for_peer(&self, _peer_node_id: PublicKey) -> Option<msgs::OnionMessage> { None }
126129
fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init, _inbound: bool) -> Result<(), ()> { Ok(()) }
127130
fn peer_disconnected(&self, _their_node_id: &PublicKey) {}
@@ -131,12 +134,13 @@ impl OnionMessageHandler for IgnoringMessageHandler {
131134
InitFeatures::empty()
132135
}
133136
}
137+
134138
impl OffersMessageHandler for IgnoringMessageHandler {
135-
fn handle_message(&self, _msg: OffersMessage) -> Option<OffersMessage> { None }
139+
fn handle_message<OMH: OnionMessageHandler>(&self, _received_onion_message: &ReceivedOnionMessage<OMH, OffersMessage>) {}
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<OMH: OnionMessageHandler>(&self, _received_onion_message: &ReceivedOnionMessage<OMH, 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 {

0 commit comments

Comments
 (0)