Skip to content

Commit 2117c09

Browse files
committed
2/3 Use MessageSendInstructions instead of PendingOnionMessage
Now that the `MessageRouter` can `create_blinded_paths` forcing callers of the `OnionMessenger` to provide it with a reply path up front is unnecessary complexity, doubly so in message handlers. Here we take the next step towards untangling that, moving from `PendingOnionMessage` to `MessageSendInstructions` for the outbound message queue in `OffersMessageHandler`. Better, we can also drop the `c_bindings`-specific message queue variant, unifying the APIs. Because `ChannelManager` needs to actually control the reply path set in individual messages, however, we have to halfway this patch, adding a new `MessageSendInstructions` variant that allows specifying the `reply_path` explicitly. Still, because other message handlers are moving this way, its nice to be consistent.
1 parent 92fb3ad commit 2117c09

File tree

4 files changed

+88
-107
lines changed

4 files changed

+88
-107
lines changed

lightning/src/ln/channelmanager.rs

+28-28
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ use crate::offers::parse::Bolt12SemanticError;
7171
use crate::offers::refund::{Refund, RefundBuilder};
7272
use crate::offers::signer;
7373
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
74-
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction};
74+
use crate::onion_message::messenger::{Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction, MessageSendInstructions};
7575
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
7676
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
7777
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -2277,9 +2277,9 @@ where
22772277
needs_persist_flag: AtomicBool,
22782278

22792279
#[cfg(not(any(test, feature = "_test_utils")))]
2280-
pending_offers_messages: Mutex<Vec<PendingOnionMessage<OffersMessage>>>,
2280+
pending_offers_messages: Mutex<Vec<(OffersMessage, MessageSendInstructions)>>,
22812281
#[cfg(any(test, feature = "_test_utils"))]
2282-
pub(crate) pending_offers_messages: Mutex<Vec<PendingOnionMessage<OffersMessage>>>,
2282+
pub(crate) pending_offers_messages: Mutex<Vec<(OffersMessage, MessageSendInstructions)>>,
22832283

22842284
/// Tracks the message events that are to be broadcasted when we are connected to some peer.
22852285
pending_broadcast_messages: Mutex<Vec<MessageSendEvent>>,
@@ -9068,21 +9068,21 @@ where
90689068
.flat_map(|reply_path| offer.paths().iter().map(move |path| (path, reply_path)))
90699069
.take(OFFERS_MESSAGE_REQUEST_LIMIT)
90709070
.for_each(|(path, reply_path)| {
9071-
let message = new_pending_onion_message(
9072-
OffersMessage::InvoiceRequest(invoice_request.clone()),
9073-
Destination::BlindedPath(path.clone()),
9074-
Some(reply_path.clone()),
9075-
);
9076-
pending_offers_messages.push(message);
9071+
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
9072+
destination: Destination::BlindedPath(path.clone()),
9073+
reply_path: reply_path.clone(),
9074+
};
9075+
let message = OffersMessage::InvoiceRequest(invoice_request.clone());
9076+
pending_offers_messages.push((message, instructions));
90779077
});
90789078
} else if let Some(signing_pubkey) = offer.signing_pubkey() {
90799079
for reply_path in reply_paths {
9080-
let message = new_pending_onion_message(
9081-
OffersMessage::InvoiceRequest(invoice_request.clone()),
9082-
Destination::Node(signing_pubkey),
9083-
Some(reply_path),
9084-
);
9085-
pending_offers_messages.push(message);
9080+
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
9081+
destination: Destination::Node(signing_pubkey),
9082+
reply_path,
9083+
};
9084+
let message = OffersMessage::InvoiceRequest(invoice_request.clone());
9085+
pending_offers_messages.push((message, instructions));
90869086
}
90879087
} else {
90889088
debug_assert!(false);
@@ -9162,25 +9162,25 @@ where
91629162
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
91639163
if refund.paths().is_empty() {
91649164
for reply_path in reply_paths {
9165-
let message = new_pending_onion_message(
9166-
OffersMessage::Invoice(invoice.clone()),
9167-
Destination::Node(refund.payer_id()),
9168-
Some(reply_path),
9169-
);
9170-
pending_offers_messages.push(message);
9165+
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
9166+
destination: Destination::Node(refund.payer_id()),
9167+
reply_path,
9168+
};
9169+
let message = OffersMessage::Invoice(invoice.clone());
9170+
pending_offers_messages.push((message, instructions));
91719171
}
91729172
} else {
91739173
reply_paths
91749174
.iter()
91759175
.flat_map(|reply_path| refund.paths().iter().map(move |path| (path, reply_path)))
91769176
.take(OFFERS_MESSAGE_REQUEST_LIMIT)
91779177
.for_each(|(path, reply_path)| {
9178-
let message = new_pending_onion_message(
9179-
OffersMessage::Invoice(invoice.clone()),
9180-
Destination::BlindedPath(path.clone()),
9181-
Some(reply_path.clone()),
9182-
);
9183-
pending_offers_messages.push(message);
9178+
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
9179+
destination: Destination::BlindedPath(path.clone()),
9180+
reply_path: reply_path.clone(),
9181+
};
9182+
let message = OffersMessage::Invoice(invoice.clone());
9183+
pending_offers_messages.push((message, instructions));
91849184
});
91859185
}
91869186

@@ -10937,7 +10937,7 @@ where
1093710937
}
1093810938
}
1093910939

10940-
fn release_pending_messages(&self) -> Vec<PendingOnionMessage<OffersMessage>> {
10940+
fn release_pending_messages(&self) -> Vec<(OffersMessage, MessageSendInstructions)> {
1094110941
core::mem::take(&mut self.pending_offers_messages.lock().unwrap())
1094210942
}
1094310943
}

lightning/src/ln/offers_tests.rs

+29-43
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use crate::offers::invoice_error::InvoiceError;
5959
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestFields};
6060
use crate::offers::nonce::Nonce;
6161
use crate::offers::parse::Bolt12SemanticError;
62-
use crate::onion_message::messenger::{Destination, PeeledOnion, new_pending_onion_message};
62+
use crate::onion_message::messenger::{Destination, PeeledOnion, MessageSendInstructions};
6363
use crate::onion_message::offers::OffersMessage;
6464
use crate::onion_message::packet::ParsedOnionMessageContents;
6565
use crate::routing::gossip::{NodeAlias, NodeId};
@@ -1313,13 +1313,10 @@ fn fails_authentication_when_handling_invoice_request() {
13131313
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);
13141314

13151315
connect_peers(david, alice);
1316-
#[cfg(not(c_bindings))] {
1317-
david.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().destination =
1318-
Destination::Node(alice_id);
1319-
}
1320-
#[cfg(c_bindings)] {
1321-
david.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 =
1322-
Destination::Node(alice_id);
1316+
match &mut david.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 {
1317+
MessageSendInstructions::WithSpecifiedReplyPath { destination, .. } =>
1318+
*destination = Destination::Node(alice_id),
1319+
_ => panic!(),
13231320
}
13241321

13251322
let onion_message = david.onion_messenger.next_onion_message_for_peer(alice_id).unwrap();
@@ -1341,13 +1338,10 @@ fn fails_authentication_when_handling_invoice_request() {
13411338
.unwrap();
13421339
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);
13431340

1344-
#[cfg(not(c_bindings))] {
1345-
david.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().destination =
1346-
Destination::BlindedPath(invalid_path);
1347-
}
1348-
#[cfg(c_bindings)] {
1349-
david.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 =
1350-
Destination::BlindedPath(invalid_path);
1341+
match &mut david.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 {
1342+
MessageSendInstructions::WithSpecifiedReplyPath { destination, .. } =>
1343+
*destination = Destination::BlindedPath(invalid_path),
1344+
_ => panic!(),
13511345
}
13521346

13531347
connect_peers(david, bob);
@@ -1427,11 +1421,9 @@ fn fails_authentication_when_handling_invoice_for_offer() {
14271421
let mut pending_offers_messages = david.node.pending_offers_messages.lock().unwrap();
14281422
let pending_invoice_request = pending_offers_messages.pop().unwrap();
14291423
pending_offers_messages.clear();
1430-
#[cfg(not(c_bindings))] {
1431-
pending_invoice_request.reply_path
1432-
}
1433-
#[cfg(c_bindings)] {
1434-
pending_invoice_request.2
1424+
match pending_invoice_request.1 {
1425+
MessageSendInstructions::WithSpecifiedReplyPath { reply_path, .. } => reply_path,
1426+
_ => panic!(),
14351427
}
14361428
};
14371429

@@ -1445,11 +1437,10 @@ fn fails_authentication_when_handling_invoice_for_offer() {
14451437
{
14461438
let mut pending_offers_messages = david.node.pending_offers_messages.lock().unwrap();
14471439
let mut pending_invoice_request = pending_offers_messages.first_mut().unwrap();
1448-
#[cfg(not(c_bindings))] {
1449-
pending_invoice_request.reply_path = invalid_reply_path;
1450-
}
1451-
#[cfg(c_bindings)] {
1452-
pending_invoice_request.2 = invalid_reply_path;
1440+
match &mut pending_invoice_request.1 {
1441+
MessageSendInstructions::WithSpecifiedReplyPath { reply_path, .. } =>
1442+
*reply_path = invalid_reply_path,
1443+
_ => panic!(),
14531444
}
14541445
}
14551446

@@ -1531,13 +1522,10 @@ fn fails_authentication_when_handling_invoice_for_refund() {
15311522
let expected_invoice = alice.node.request_refund_payment(&refund).unwrap();
15321523

15331524
connect_peers(david, alice);
1534-
#[cfg(not(c_bindings))] {
1535-
alice.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().destination =
1536-
Destination::Node(david_id);
1537-
}
1538-
#[cfg(c_bindings)] {
1539-
alice.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 =
1540-
Destination::Node(david_id);
1525+
match &mut alice.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 {
1526+
MessageSendInstructions::WithSpecifiedReplyPath { destination, .. } =>
1527+
*destination = Destination::Node(david_id),
1528+
_ => panic!(),
15411529
}
15421530

15431531
let onion_message = alice.onion_messenger.next_onion_message_for_peer(david_id).unwrap();
@@ -1565,13 +1553,10 @@ fn fails_authentication_when_handling_invoice_for_refund() {
15651553

15661554
let expected_invoice = alice.node.request_refund_payment(&refund).unwrap();
15671555

1568-
#[cfg(not(c_bindings))] {
1569-
alice.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().destination =
1570-
Destination::BlindedPath(invalid_path);
1571-
}
1572-
#[cfg(c_bindings)] {
1573-
alice.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 =
1574-
Destination::BlindedPath(invalid_path);
1556+
match &mut alice.node.pending_offers_messages.lock().unwrap().first_mut().unwrap().1 {
1557+
MessageSendInstructions::WithSpecifiedReplyPath { destination, .. } =>
1558+
*destination = Destination::BlindedPath(invalid_path),
1559+
_ => panic!(),
15751560
}
15761561

15771562
connect_peers(alice, charlie);
@@ -2155,10 +2140,11 @@ fn fails_paying_invoice_with_unknown_required_features() {
21552140
.build_and_sign(&secp_ctx).unwrap();
21562141

21572142
// Enqueue an onion message containing the new invoice.
2158-
let pending_message = new_pending_onion_message(
2159-
OffersMessage::Invoice(invoice), Destination::BlindedPath(reply_path), None
2160-
);
2161-
alice.node.pending_offers_messages.lock().unwrap().push(pending_message);
2143+
let instructions = MessageSendInstructions::WithoutReplyPath {
2144+
destination: Destination::BlindedPath(reply_path),
2145+
};
2146+
let message = OffersMessage::Invoice(invoice);
2147+
alice.node.pending_offers_messages.lock().unwrap().push((message, instructions));
21622148

21632149
let onion_message = alice.onion_messenger.next_onion_message_for_peer(charlie_id).unwrap();
21642150
charlie.onion_messenger.handle_onion_message(&alice_id, &onion_message);

lightning/src/onion_message/messenger.rs

+29-24
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,14 @@ impl ResponseInstruction {
403403
/// Instructions for how and where to send a message.
404404
#[derive(Clone)]
405405
pub enum MessageSendInstructions {
406+
/// Indicates that a message should be sent including the provided reply path for the recipient
407+
/// to respond.
408+
WithSpecifiedReplyPath {
409+
/// The desination where we need to send our message.
410+
destination: Destination,
411+
/// The reply path which should be included in the message.
412+
reply_path: BlindedMessagePath,
413+
},
406414
/// Indicates that a message should be sent including a reply path for the recipient to
407415
/// respond.
408416
WithReplyPath {
@@ -1183,24 +1191,25 @@ where
11831191
fn send_onion_message_internal<T: OnionMessageContents>(
11841192
&self, message: T, instructions: MessageSendInstructions, log_suffix: fmt::Arguments,
11851193
) -> Result<Option<SendSuccess>, SendError> {
1186-
let (destination, context) = match instructions {
1187-
MessageSendInstructions::WithReplyPath { destination, context } => (destination, Some(context)),
1188-
MessageSendInstructions::WithoutReplyPath { destination } => (destination, None),
1189-
};
1190-
1191-
let reply_path = if let Some(context) = context {
1192-
match self.create_blinded_path(context) {
1193-
Ok(reply_path) => Some(reply_path),
1194-
Err(err) => {
1195-
log_trace!(
1196-
self.logger,
1197-
"Failed to create reply path {}: {:?}",
1198-
log_suffix, err
1199-
);
1200-
return Err(err);
1194+
let (destination, reply_path) = match instructions {
1195+
MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path } =>
1196+
(destination, Some(reply_path)),
1197+
MessageSendInstructions::WithReplyPath { destination, context } => {
1198+
match self.create_blinded_path(context) {
1199+
Ok(reply_path) => (destination, Some(reply_path)),
1200+
Err(err) => {
1201+
log_trace!(
1202+
self.logger,
1203+
"Failed to create reply path {}: {:?}",
1204+
log_suffix, err
1205+
);
1206+
return Err(err);
1207+
}
12011208
}
1202-
}
1203-
} else { None };
1209+
},
1210+
MessageSendInstructions::WithoutReplyPath { destination } =>
1211+
(destination, None),
1212+
};
12041213

12051214
self.find_path_and_enqueue_onion_message(
12061215
message, destination, reply_path, log_suffix,
@@ -1737,13 +1746,9 @@ where
17371746
// node, and then enqueue the message for sending to the first peer in the full path.
17381747
fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<OnionMessage> {
17391748
// Enqueue any initiating `OffersMessage`s to send.
1740-
for message in self.offers_handler.release_pending_messages() {
1741-
#[cfg(not(c_bindings))]
1742-
let PendingOnionMessage { contents, destination, reply_path } = message;
1743-
#[cfg(c_bindings)]
1744-
let (contents, destination, reply_path) = message;
1745-
let _ = self.find_path_and_enqueue_onion_message(
1746-
contents, destination, reply_path, format_args!("when sending OffersMessage")
1749+
for (message, instructions) in self.offers_handler.release_pending_messages() {
1750+
let _ = self.send_onion_message_internal(
1751+
message, instructions, format_args!("when sending OffersMessage")
17471752
);
17481753
}
17491754

lightning/src/onion_message/offers.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ use crate::offers::static_invoice::StaticInvoice;
2222
use crate::onion_message::packet::OnionMessageContents;
2323
use crate::util::logger::Logger;
2424
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
25-
use crate::onion_message::messenger::{ResponseInstruction, Responder};
26-
#[cfg(not(c_bindings))]
27-
use crate::onion_message::messenger::PendingOnionMessage;
25+
use crate::onion_message::messenger::{ResponseInstruction, Responder, MessageSendInstructions};
2826

2927
use crate::prelude::*;
3028

@@ -53,15 +51,7 @@ pub trait OffersMessageHandler {
5351
///
5452
/// Typically, this is used for messages initiating a payment flow rather than in response to
5553
/// another message. The latter should use the return value of [`Self::handle_message`].
56-
#[cfg(not(c_bindings))]
57-
fn release_pending_messages(&self) -> Vec<PendingOnionMessage<OffersMessage>> { vec![] }
58-
59-
/// Releases any [`OffersMessage`]s that need to be sent.
60-
///
61-
/// Typically, this is used for messages initiating a payment flow rather than in response to
62-
/// another message. The latter should use the return value of [`Self::handle_message`].
63-
#[cfg(c_bindings)]
64-
fn release_pending_messages(&self) -> Vec<(OffersMessage, crate::onion_message::messenger::Destination, Option<crate::blinded_path::message::BlindedMessagePath>)> { vec![] }
54+
fn release_pending_messages(&self) -> Vec<(OffersMessage, MessageSendInstructions)> { vec![] }
6555
}
6656

6757
/// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`].

0 commit comments

Comments
 (0)