diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index 4e563e28a46..5e6c671761b 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -7,7 +7,7 @@ use bitcoin::secp256k1::ecdsa::RecoverableSignature; use bitcoin::secp256k1::schnorr; use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp}; -use lightning::blinded_path::message::ForwardNode; +use lightning::blinded_path::message::{ForwardNode, RecipientData}; use lightning::ln::features::InitFeatures; use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler}; use lightning::ln::script::ShutdownScript; @@ -98,7 +98,7 @@ impl MessageRouter for TestMessageRouter { struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { - fn handle_message(&self, _message: OffersMessage, _responder: Option) -> ResponseInstruction { + fn handle_message(&self, _message: OffersMessage, _responder: Option, _recipient_data: RecipientData) -> ResponseInstruction { ResponseInstruction::NoResponse } } @@ -128,7 +128,7 @@ struct TestCustomMessageHandler {} impl CustomOnionMessageHandler for TestCustomMessageHandler { type CustomMessage = TestCustomMessage; - fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option) -> ResponseInstruction { + fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option, _recipient_data: RecipientData) -> ResponseInstruction { match responder { Some(responder) => responder.respond(message), None => ResponseInstruction::NoResponse diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 51b3fc1539b..3af435aae01 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -31,6 +31,7 @@ use bitcoin::secp256k1::{SecretKey,PublicKey}; use bitcoin::secp256k1::Secp256k1; use bitcoin::{secp256k1, Sequence}; +use crate::blinded_path::message::RecipientData; use crate::blinded_path::{BlindedPath, NodeIdLookUp}; use crate::blinded_path::message::ForwardNode; use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentConstraints, PaymentContext, ReceiveTlvs}; @@ -10360,10 +10361,16 @@ where R::Target: Router, L::Target: Logger, { - fn handle_message(&self, message: OffersMessage, responder: Option) -> ResponseInstruction { + fn handle_message(&self, message: OffersMessage, responder: Option, recipient_data: RecipientData) -> ResponseInstruction { let secp_ctx = &self.secp_ctx; let expanded_key = &self.inbound_payment_key; + let abandon_if_payment = |payment_id| { + if let Some(payment_id) = payment_id { + self.abandon_payment(payment_id); + } + }; + match message { OffersMessage::InvoiceRequest(invoice_request) => { let responder = match responder { @@ -10472,8 +10479,12 @@ where }); match (responder, response) { - (Some(responder), Err(e)) => responder.respond(OffersMessage::InvoiceError(e)), + (Some(responder), Err(e)) => { + abandon_if_payment(recipient_data.payment_id); + responder.respond(OffersMessage::InvoiceError(e)) + }, (None, Err(_)) => { + abandon_if_payment(recipient_data.payment_id); log_trace!( self.logger, "A response was generated, but there is no reply_path specified for sending the response." @@ -10484,6 +10495,7 @@ where } }, OffersMessage::InvoiceError(invoice_error) => { + abandon_if_payment(recipient_data.payment_id); log_trace!(self.logger, "Received invoice_error: {}", invoice_error); return ResponseInstruction::NoResponse; }, diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index f31a8e131e0..69e00356f47 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -18,6 +18,7 @@ use bitcoin::blockdata::constants::ChainHash; use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey}; +use crate::blinded_path::message::RecipientData; use crate::sign::{NodeSigner, Recipient}; use crate::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; use crate::ln::types::ChannelId; @@ -137,13 +138,13 @@ impl OnionMessageHandler for IgnoringMessageHandler { } impl OffersMessageHandler for IgnoringMessageHandler { - fn handle_message(&self, _message: OffersMessage, _responder: Option) -> ResponseInstruction { + fn handle_message(&self, _message: OffersMessage, _responder: Option, _recipient_data: RecipientData) -> ResponseInstruction { ResponseInstruction::NoResponse } } impl CustomOnionMessageHandler for IgnoringMessageHandler { type CustomMessage = Infallible; - fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option) -> ResponseInstruction { + fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option, _recipient_data: RecipientData) -> ResponseInstruction { // Since we always return `None` in the read the handle method should never be called. unreachable!(); } diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 0c3c67d4483..908c3746970 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -9,6 +9,7 @@ //! Onion message testing and test utilities live here. +use crate::blinded_path::message::RecipientData; use crate::blinded_path::{BlindedPath, EmptyNodeIdLookUp}; use crate::blinded_path::message::ForwardNode; use crate::events::{Event, EventsProvider}; @@ -74,7 +75,7 @@ impl Drop for MessengerNode { struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { - fn handle_message(&self, _message: OffersMessage, _responder: Option) -> ResponseInstruction { + fn handle_message(&self, _message: OffersMessage, _responder: Option, _recipient_data: RecipientData) -> ResponseInstruction { ResponseInstruction::NoResponse } } @@ -161,7 +162,7 @@ impl Drop for TestCustomMessageHandler { impl CustomOnionMessageHandler for TestCustomMessageHandler { type CustomMessage = TestCustomMessage; - fn handle_custom_message(&self, msg: Self::CustomMessage, responder: Option) -> ResponseInstruction { + fn handle_custom_message(&self, msg: Self::CustomMessage, responder: Option, _recipient_data: RecipientData) -> ResponseInstruction { let expectation = self.get_next_expectation(); assert_eq!(msg, expectation.expect); @@ -424,7 +425,7 @@ fn async_response_over_one_blinded_hop() { // 5. Expect Alice to receive the message and create a response instruction for it. alice.custom_message_handler.expect_message(message.clone()); - let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, responder); + let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, responder, RecipientData::new()); // 6. Simulate Alice asynchronously responding back to Bob with a response. assert_eq!( @@ -458,7 +459,7 @@ fn async_response_with_reply_path_succeeds() { // Alice asynchronously responds to Bob, expecting a response back from him. let responder = Responder::new(reply_path, path_id); alice.custom_message_handler.expect_message_and_response(message.clone()); - let response_instruction = alice.custom_message_handler.handle_custom_message(message, Some(responder)); + let response_instruction = alice.custom_message_handler.handle_custom_message(message, Some(responder), RecipientData::new()); assert_eq!( alice.messenger.handle_onion_message_response(response_instruction), @@ -496,7 +497,7 @@ fn async_response_with_reply_path_fails() { // Therefore, the reply_path cannot be used for the response. let responder = Responder::new(reply_path, path_id); alice.custom_message_handler.expect_message_and_response(message.clone()); - let response_instruction = alice.custom_message_handler.handle_custom_message(message, Some(responder)); + let response_instruction = alice.custom_message_handler.handle_custom_message(message, Some(responder), RecipientData::new()); assert_eq!( alice.messenger.handle_onion_message_response(response_instruction), diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 51b7ad7f7d3..fa1c85cbab5 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -623,7 +623,7 @@ pub trait CustomOnionMessageHandler { /// Called with the custom message that was received, returning a response to send, if any. /// /// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`]. - fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option) -> ResponseInstruction; + fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option, recipient_data: RecipientData) -> ResponseInstruction; /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the /// message type is unknown. @@ -1236,7 +1236,7 @@ where fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage) { let logger = WithContext::from(&self.logger, Some(*peer_node_id), None, None); match self.peel_onion_message(msg) { - Ok(PeeledOnion::Receive(message, path_id, _, reply_path)) => { + Ok(PeeledOnion::Receive(message, path_id, recipient_data, reply_path)) => { log_trace!( logger, "Received an onion message with path_id {:02x?} and {} reply_path: {:?}", @@ -1247,14 +1247,14 @@ where let responder = reply_path.map( |reply_path| Responder::new(reply_path, path_id) ); - let response_instructions = self.offers_handler.handle_message(msg, responder); + let response_instructions = self.offers_handler.handle_message(msg, responder, recipient_data); let _ = self.handle_onion_message_response(response_instructions); }, ParsedOnionMessageContents::Custom(msg) => { let responder = reply_path.map( |reply_path| Responder::new(reply_path, path_id) ); - let response_instructions = self.custom_handler.handle_custom_message(msg, responder); + let response_instructions = self.custom_handler.handle_custom_message(msg, responder, recipient_data); let _ = self.handle_onion_message_response(response_instructions); }, } diff --git a/lightning/src/onion_message/offers.rs b/lightning/src/onion_message/offers.rs index 42c6914157e..3db6eee054d 100644 --- a/lightning/src/onion_message/offers.rs +++ b/lightning/src/onion_message/offers.rs @@ -10,6 +10,7 @@ //! Message handling for BOLT 12 Offers. use core::fmt; +use crate::blinded_path::message::RecipientData; use crate::io::{self, Read}; use crate::ln::msgs::DecodeError; use crate::offers::invoice_error::InvoiceError; @@ -40,7 +41,7 @@ pub trait OffersMessageHandler { /// The returned [`OffersMessage`], if any, is enqueued to be sent by [`OnionMessenger`]. /// /// [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger - fn handle_message(&self, message: OffersMessage, responder: Option) -> ResponseInstruction; + fn handle_message(&self, message: OffersMessage, responder: Option, recipient_data: RecipientData) -> ResponseInstruction; /// Releases any [`OffersMessage`]s that need to be sent. ///