Skip to content

Commit ea0ff10

Browse files
committed
Update handle_message to accept OffersContext data as an input field
1. Handling Offers Data: - Updated `handle_message` to accept `OffersContext` data as an input field. - If it is present, it will be utilized by the handler to abandon outbound payments that have failed for any reason. 2. Consistency in Custom Message Handling: - Updated `handle_custom_message` to accept optional custom data. for consistency. - Note: `custom_data` will remain unused in this PR.
1 parent 4634abc commit ea0ff10

File tree

6 files changed

+67
-25
lines changed

6 files changed

+67
-25
lines changed

fuzz/src/onion_message.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use bitcoin::secp256k1::ecdsa::RecoverableSignature;
66
use bitcoin::secp256k1::schnorr;
77
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
88

9+
use lightning::blinded_path::message::{MessageContext, OffersContext};
910
use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
1011
use lightning::ln::features::InitFeatures;
1112
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
@@ -104,7 +105,7 @@ struct TestOffersMessageHandler {}
104105

105106
impl OffersMessageHandler for TestOffersMessageHandler {
106107
fn handle_message(
107-
&self, _message: OffersMessage, _responder: Option<Responder>,
108+
&self, _message: OffersMessage, _context: OffersContext, _responder: Option<Responder>,
108109
) -> ResponseInstruction<OffersMessage> {
109110
ResponseInstruction::NoResponse
110111
}
@@ -147,7 +148,7 @@ struct TestCustomMessageHandler {}
147148
impl CustomOnionMessageHandler for TestCustomMessageHandler {
148149
type CustomMessage = TestCustomMessage;
149150
fn handle_custom_message(
150-
&self, message: Self::CustomMessage, responder: Option<Responder>,
151+
&self, message: Self::CustomMessage, _context: Vec<u8>, responder: Option<Responder>,
151152
) -> ResponseInstruction<Self::CustomMessage> {
152153
match responder {
153154
Some(responder) => responder.respond(message),
@@ -337,9 +338,14 @@ mod tests {
337338
super::do_test(&<Vec<u8>>::from_hex(one_hop_om).unwrap(), &logger);
338339
{
339340
let log_entries = logger.lines.lock().unwrap();
340-
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
341-
"Received an onion message with path_id None and a reply_path: Custom(TestCustomMessage)"
342-
.to_string())), Some(&1));
341+
assert_eq!(
342+
log_entries.get(&(
343+
"lightning::onion_message::messenger".to_string(),
344+
"Received an onion message with a reply_path: Custom(TestCustomMessage)"
345+
.to_string()
346+
)),
347+
Some(&1)
348+
);
343349
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
344350
"Constructing onion message when responding with Custom Message to an onion message: TestCustomMessage".to_string())), Some(&1));
345351
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),

lightning/src/ln/channelmanager.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use bitcoin::secp256k1::{SecretKey,PublicKey};
3131
use bitcoin::secp256k1::Secp256k1;
3232
use bitcoin::{secp256k1, Sequence};
3333

34+
use crate::blinded_path::message::OffersContext;
3435
use crate::blinded_path::{BlindedPath, NodeIdLookUp};
3536
use crate::blinded_path::message::ForwardNode;
3637
use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentConstraints, PaymentContext, ReceiveTlvs};
@@ -10251,10 +10252,17 @@ where
1025110252
R::Target: Router,
1025210253
L::Target: Logger,
1025310254
{
10254-
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
10255+
fn handle_message(&self, message: OffersMessage, context: OffersContext, responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
1025510256
let secp_ctx = &self.secp_ctx;
1025610257
let expanded_key = &self.inbound_payment_key;
1025710258

10259+
let abandon_if_payment = |context| {
10260+
match context {
10261+
OffersContext::OutboundPayment { payment_id } => self.abandon_payment(payment_id),
10262+
_ => {},
10263+
}
10264+
};
10265+
1025810266
match message {
1025910267
OffersMessage::InvoiceRequest(invoice_request) => {
1026010268
let responder = match responder {
@@ -10367,12 +10375,21 @@ where
1036710375
};
1036810376

1036910377
match result {
10370-
Ok(()) => ResponseInstruction::NoResponse,
10371-
Err(e) => match responder {
10372-
Some(responder) => responder.respond(OffersMessage::InvoiceError(e)),
10378+
Ok(_) => ResponseInstruction::NoResponse,
10379+
Err(err) => match responder {
10380+
Some(responder) => {
10381+
abandon_if_payment(context);
10382+
responder.respond(OffersMessage::InvoiceError(err))
10383+
},
1037310384
None => {
10374-
log_trace!(self.logger, "No reply path for sending invoice error: {:?}", e);
10375-
ResponseInstruction::NoResponse
10385+
abandon_if_payment(context);
10386+
log_trace!(
10387+
self.logger,
10388+
"An error response was generated, but there is no reply_path specified \
10389+
for sending the response. Error: {}",
10390+
err
10391+
);
10392+
return ResponseInstruction::NoResponse;
1037610393
},
1037710394
},
1037810395
}
@@ -10389,6 +10406,7 @@ where
1038910406
}
1039010407
},
1039110408
OffersMessage::InvoiceError(invoice_error) => {
10409+
abandon_if_payment(context);
1039210410
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
1039310411
ResponseInstruction::NoResponse
1039410412
},

lightning/src/ln/peer_handler.rs

+3-2
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::message::OffersContext;
2122
use crate::sign::{NodeSigner, Recipient};
2223
use crate::events::{MessageSendEvent, MessageSendEventsProvider};
2324
use crate::ln::types::ChannelId;
@@ -145,7 +146,7 @@ impl OnionMessageHandler for IgnoringMessageHandler {
145146
}
146147

147148
impl OffersMessageHandler for IgnoringMessageHandler {
148-
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
149+
fn handle_message(&self, _message: OffersMessage, _context: OffersContext, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
149150
ResponseInstruction::NoResponse
150151
}
151152
}
@@ -159,7 +160,7 @@ impl AsyncPaymentsMessageHandler for IgnoringMessageHandler {
159160
}
160161
impl CustomOnionMessageHandler for IgnoringMessageHandler {
161162
type CustomMessage = Infallible;
162-
fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
163+
fn handle_custom_message(&self, _message: Self::CustomMessage, _context: Vec<u8>, _responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
163164
// Since we always return `None` in the read the handle method should never be called.
164165
unreachable!();
165166
}

lightning/src/onion_message/functional_tests.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! Onion message testing and test utilities live here.
1111
1212
use crate::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
13-
use crate::blinded_path::message::ForwardNode;
13+
use crate::blinded_path::message::{ForwardNode, OffersContext};
1414
use crate::events::{Event, EventsProvider};
1515
use crate::ln::features::{ChannelFeatures, InitFeatures};
1616
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
@@ -76,7 +76,7 @@ impl Drop for MessengerNode {
7676
struct TestOffersMessageHandler {}
7777

7878
impl OffersMessageHandler for TestOffersMessageHandler {
79-
fn handle_message(&self, _message: OffersMessage, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
79+
fn handle_message(&self, _message: OffersMessage, _context: OffersContext, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
8080
ResponseInstruction::NoResponse
8181
}
8282
}
@@ -174,7 +174,7 @@ impl Drop for TestCustomMessageHandler {
174174

175175
impl CustomOnionMessageHandler for TestCustomMessageHandler {
176176
type CustomMessage = TestCustomMessage;
177-
fn handle_custom_message(&self, msg: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
177+
fn handle_custom_message(&self, msg: Self::CustomMessage, _context: Vec<u8>, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
178178
let expectation = self.get_next_expectation();
179179
assert_eq!(msg, expectation.expect);
180180

@@ -437,7 +437,7 @@ fn async_response_over_one_blinded_hop() {
437437

438438
// 5. Expect Alice to receive the message and create a response instruction for it.
439439
alice.custom_message_handler.expect_message(message.clone());
440-
let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, responder);
440+
let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, Vec::new(), responder);
441441

442442
// 6. Simulate Alice asynchronously responding back to Bob with a response.
443443
assert_eq!(
@@ -470,7 +470,7 @@ fn async_response_with_reply_path_succeeds() {
470470
// Alice asynchronously responds to Bob, expecting a response back from him.
471471
let responder = Responder::new(reply_path);
472472
alice.custom_message_handler.expect_message_and_response(message.clone());
473-
let response_instruction = alice.custom_message_handler.handle_custom_message(message, Some(responder));
473+
let response_instruction = alice.custom_message_handler.handle_custom_message(message, Vec::new(), Some(responder));
474474

475475
assert_eq!(
476476
alice.messenger.handle_onion_message_response(response_instruction),
@@ -508,7 +508,7 @@ fn async_response_with_reply_path_fails() {
508508
disconnect_peers(alice, bob);
509509
let responder = Responder::new(reply_path);
510510
alice.custom_message_handler.expect_message_and_response(message.clone());
511-
let response_instruction = alice.custom_message_handler.handle_custom_message(message, Some(responder));
511+
let response_instruction = alice.custom_message_handler.handle_custom_message(message, Vec::new(), Some(responder));
512512

513513
assert_eq!(
514514
alice.messenger.handle_onion_message_response(response_instruction),

lightning/src/onion_message/messenger.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
1616
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
1717

1818
use crate::blinded_path::{BlindedPath, IntroductionNode, NextMessageHop, NodeIdLookUp};
19-
use crate::blinded_path::message::{advance_path_by_one, ForwardNode, ForwardTlvs, ReceiveTlvs, MessageContext};
19+
use crate::blinded_path::message::{advance_path_by_one, ForwardNode, ForwardTlvs, MessageContext, OffersContext, ReceiveTlvs};
2020
use crate::blinded_path::utils;
2121
use crate::events::{Event, EventHandler, EventsProvider};
2222
use crate::sign::{EntropySource, NodeSigner, Recipient};
@@ -768,7 +768,7 @@ pub trait CustomOnionMessageHandler {
768768
/// Called with the custom message that was received, returning a response to send, if any.
769769
///
770770
/// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
771-
fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage>;
771+
fn handle_custom_message(&self, message: Self::CustomMessage, context: Vec<u8>, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage>;
772772

773773
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
774774
/// message type is unknown.
@@ -1446,7 +1446,7 @@ where
14461446
fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage) {
14471447
let logger = WithContext::from(&self.logger, Some(*peer_node_id), None, None);
14481448
match self.peel_onion_message(msg) {
1449-
Ok(PeeledOnion::Receive(message, _context, reply_path)) => {
1449+
Ok(PeeledOnion::Receive(message, context, reply_path)) => {
14501450
log_trace!(
14511451
logger,
14521452
"Received an onion message with {} reply_path: {:?}",
@@ -1455,7 +1455,15 @@ where
14551455
let responder = reply_path.map(Responder::new);
14561456
match message {
14571457
ParsedOnionMessageContents::Offers(msg) => {
1458-
let response_instructions = self.offers_handler.handle_message(msg, responder);
1458+
let context = match context {
1459+
None => OffersContext::Unknown {},
1460+
Some(MessageContext::Offers(context)) => context,
1461+
Some(MessageContext::Custom(_)) => {
1462+
debug_assert!(false, "Shouldn't have triggered this case.");
1463+
return
1464+
}
1465+
};
1466+
let response_instructions = self.offers_handler.handle_message(msg, context, responder);
14591467
let _ = self.handle_onion_message_response(response_instructions);
14601468
},
14611469
#[cfg(async_payments)]
@@ -1470,7 +1478,15 @@ where
14701478
self.async_payments_handler.release_held_htlc(msg);
14711479
},
14721480
ParsedOnionMessageContents::Custom(msg) => {
1473-
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
1481+
let context = match context {
1482+
None => vec![],
1483+
Some(MessageContext::Custom(data)) => data,
1484+
Some(MessageContext::Offers(_)) => {
1485+
debug_assert!(false, "Shouldn't have triggered this case.");
1486+
return
1487+
}
1488+
};
1489+
let response_instructions = self.custom_handler.handle_custom_message(msg, context, responder);
14741490
let _ = self.handle_onion_message_response(response_instructions);
14751491
},
14761492
}

lightning/src/onion_message/offers.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//! Message handling for BOLT 12 Offers.
1111
1212
use core::fmt;
13+
use crate::blinded_path::message::OffersContext;
1314
use crate::io::{self, Read};
1415
use crate::ln::msgs::DecodeError;
1516
use crate::offers::invoice_error::InvoiceError;
@@ -44,7 +45,7 @@ pub trait OffersMessageHandler {
4445
/// The returned [`OffersMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
4546
///
4647
/// [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger
47-
fn handle_message(&self, message: OffersMessage, responder: Option<Responder>) -> ResponseInstruction<OffersMessage>;
48+
fn handle_message(&self, message: OffersMessage, context: OffersContext, responder: Option<Responder>) -> ResponseInstruction<OffersMessage>;
4849

4950
/// Releases any [`OffersMessage`]s that need to be sent.
5051
///

0 commit comments

Comments
 (0)