Skip to content

Commit

Permalink
Update handle_message to accept recipient_data as an input field
Browse files Browse the repository at this point in the history
1. The recipient data, if present, will be used by the handler to
   abandon outbound payments that have failed for some reason.
2. Also update handle_custom_message to accept optional recipient
   data for consistency. This will remain unused in this PR for now.
  • Loading branch information
shaavan committed May 29, 2024
1 parent a249303 commit e057531
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 17 deletions.
6 changes: 3 additions & 3 deletions fuzz/src/onion_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -98,7 +98,7 @@ impl MessageRouter for TestMessageRouter {
struct TestOffersMessageHandler {}

impl OffersMessageHandler for TestOffersMessageHandler {
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>, _recipient_data: RecipientData) -> ResponseInstruction<OffersMessage> {
ResponseInstruction::NoResponse
}
}
Expand Down Expand Up @@ -128,7 +128,7 @@ struct TestCustomMessageHandler {}

impl CustomOnionMessageHandler for TestCustomMessageHandler {
type CustomMessage = TestCustomMessage;
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>, _recipient_data: RecipientData) -> ResponseInstruction<Self::CustomMessage> {
match responder {
Some(responder) => responder.respond(message),
None => ResponseInstruction::NoResponse
Expand Down
16 changes: 14 additions & 2 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -10360,10 +10361,16 @@ where
R::Target: Router,
L::Target: Logger,
{
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>, recipient_data: RecipientData) -> ResponseInstruction<OffersMessage> {
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 {
Expand Down Expand Up @@ -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."
Expand All @@ -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;
},
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/ln/peer_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -137,13 +138,13 @@ impl OnionMessageHandler for IgnoringMessageHandler {
}

impl OffersMessageHandler for IgnoringMessageHandler {
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>, _recipient_data: RecipientData) -> ResponseInstruction<OffersMessage> {
ResponseInstruction::NoResponse
}
}
impl CustomOnionMessageHandler for IgnoringMessageHandler {
type CustomMessage = Infallible;
fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option<Responder>, _recipient_data: RecipientData) -> ResponseInstruction<Self::CustomMessage> {
// Since we always return `None` in the read the handle method should never be called.
unreachable!();
}
Expand Down
11 changes: 6 additions & 5 deletions lightning/src/onion_message/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -74,7 +75,7 @@ impl Drop for MessengerNode {
struct TestOffersMessageHandler {}

impl OffersMessageHandler for TestOffersMessageHandler {
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>, _recipient_data: RecipientData) -> ResponseInstruction<OffersMessage> {
ResponseInstruction::NoResponse
}
}
Expand Down Expand Up @@ -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<Responder>) -> ResponseInstruction<Self::CustomMessage> {
fn handle_custom_message(&self, msg: Self::CustomMessage, responder: Option<Responder>, _recipient_data: RecipientData) -> ResponseInstruction<Self::CustomMessage> {
let expectation = self.get_next_expectation();
assert_eq!(msg, expectation.expect);

Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/onion_message/messenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Responder>) -> ResponseInstruction<Self::CustomMessage>;
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>, recipient_data: RecipientData) -> ResponseInstruction<Self::CustomMessage>;

/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
/// message type is unknown.
Expand Down Expand Up @@ -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: {:?}",
Expand All @@ -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);
},
}
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/onion_message/offers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Responder>) -> ResponseInstruction<OffersMessage>;
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>, recipient_data: RecipientData) -> ResponseInstruction<OffersMessage>;

/// Releases any [`OffersMessage`]s that need to be sent.
///
Expand Down

0 comments on commit e057531

Please sign in to comment.