From 49a5fdf6aa00c06645290da8343bb2efff0380ee Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 23 Oct 2023 18:55:17 +0000 Subject: [PATCH] Use a tuple, not a struct, for `PendingOnionMessage` in bindings Bindings aren't currently able to handle a struct with a generic which is actually exposed - we map all structs concretely to a single type, whereas having fluctuating types on a struct requires mapping the inner field to a trait first. Since this isn't super practical, we make `PendingOnionMessage` a tuple in bindings, rather than a struct. --- lightning/src/ln/channelmanager.rs | 42 ++++++++++++------------ lightning/src/onion_message/messenger.rs | 31 +++++++++++++++++ lightning/src/onion_message/mod.rs | 1 + lightning/src/onion_message/offers.rs | 8 +++++ 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 2bf60cdc7..c4efd8957 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -63,7 +63,7 @@ use crate::offers::merkle::SignError; use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder}; use crate::offers::parse::Bolt12SemanticError; use crate::offers::refund::{Refund, RefundBuilder}; -use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage}; +use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message}; use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, WriteableEcdsaChannelSigner}; use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate}; use crate::util::wakers::{Future, Notifier}; @@ -7505,11 +7505,11 @@ where let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap(); if offer.paths().is_empty() { - let message = PendingOnionMessage { - contents: OffersMessage::InvoiceRequest(invoice_request), - destination: Destination::Node(offer.signing_pubkey()), - reply_path: Some(reply_path), - }; + let message = new_pending_onion_message( + OffersMessage::InvoiceRequest(invoice_request), + Destination::Node(offer.signing_pubkey()), + Some(reply_path), + ); pending_offers_messages.push(message); } else { // Send as many invoice requests as there are paths in the offer (with an upper bound). @@ -7517,11 +7517,11 @@ where // one invoice for a given payment id will be paid, even if more than one is received. const REQUEST_LIMIT: usize = 10; for path in offer.paths().into_iter().take(REQUEST_LIMIT) { - let message = PendingOnionMessage { - contents: OffersMessage::InvoiceRequest(invoice_request.clone()), - destination: Destination::BlindedPath(path.clone()), - reply_path: Some(reply_path.clone()), - }; + let message = new_pending_onion_message( + OffersMessage::InvoiceRequest(invoice_request.clone()), + Destination::BlindedPath(path.clone()), + Some(reply_path.clone()), + ); pending_offers_messages.push(message); } } @@ -7574,19 +7574,19 @@ where let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap(); if refund.paths().is_empty() { - let message = PendingOnionMessage { - contents: OffersMessage::Invoice(invoice), - destination: Destination::Node(refund.payer_id()), - reply_path: Some(reply_path), - }; + let message = new_pending_onion_message( + OffersMessage::Invoice(invoice), + Destination::Node(refund.payer_id()), + Some(reply_path), + ); pending_offers_messages.push(message); } else { for path in refund.paths() { - let message = PendingOnionMessage { - contents: OffersMessage::Invoice(invoice.clone()), - destination: Destination::BlindedPath(path.clone()), - reply_path: Some(reply_path.clone()), - }; + let message = new_pending_onion_message( + OffersMessage::Invoice(invoice.clone()), + Destination::BlindedPath(path.clone()), + Some(reply_path.clone()), + ); pending_offers_messages.push(message); } } diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 200ee44ee..cf0f9e086 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -159,6 +159,7 @@ where /// /// These are obtained when released from [`OnionMessenger`]'s handlers after which they are /// enqueued for sending. +#[cfg(not(c_bindings))] pub struct PendingOnionMessage { /// The message contents to send in an [`OnionMessage`]. pub contents: T, @@ -170,6 +171,22 @@ pub struct PendingOnionMessage { pub reply_path: Option, } +#[cfg(c_bindings)] +/// An [`OnionMessage`] for [`OnionMessenger`] to send. +/// +/// These are obtained when released from [`OnionMessenger`]'s handlers after which they are +/// enqueued for sending. +pub type PendingOnionMessage = (T, Destination, Option); + +pub(crate) fn new_pending_onion_message( + contents: T, destination: Destination, reply_path: Option +) -> PendingOnionMessage { + #[cfg(not(c_bindings))] + return PendingOnionMessage { contents, destination, reply_path }; + #[cfg(c_bindings)] + return (contents, destination, reply_path); +} + /// A trait defining behavior for routing an [`OnionMessage`]. pub trait MessageRouter { /// Returns a route for sending an [`OnionMessage`] to the given [`Destination`]. @@ -286,7 +303,15 @@ pub trait CustomOnionMessageHandler { /// /// Typically, this is used for messages initiating a message flow rather than in response to /// another message. The latter should use the return value of [`Self::handle_custom_message`]. + #[cfg(not(c_bindings))] fn release_pending_custom_messages(&self) -> Vec>; + + /// Releases any [`Self::CustomMessage`]s that need to be sent. + /// + /// Typically, this is used for messages initiating a message flow rather than in response to + /// another message. The latter should use the return value of [`Self::handle_custom_message`]. + #[cfg(c_bindings)] + fn release_pending_custom_messages(&self) -> Vec<(Self::CustomMessage, Destination, Option)>; } /// A processed incoming onion message, containing either a Forward (another onion message) @@ -686,7 +711,10 @@ where fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option { // Enqueue any initiating `OffersMessage`s to send. for message in self.offers_handler.release_pending_messages() { + #[cfg(not(c_bindings))] let PendingOnionMessage { contents, destination, reply_path } = message; + #[cfg(c_bindings)] + let (contents, destination, reply_path) = message; self.find_path_and_enqueue_onion_message( contents, destination, reply_path, format_args!("when sending OffersMessage") ); @@ -694,7 +722,10 @@ where // Enqueue any initiating `CustomMessage`s to send. for message in self.custom_handler.release_pending_custom_messages() { + #[cfg(not(c_bindings))] let PendingOnionMessage { contents, destination, reply_path } = message; + #[cfg(c_bindings)] + let (contents, destination, reply_path) = message; self.find_path_and_enqueue_onion_message( contents, destination, reply_path, format_args!("when sending CustomMessage") ); diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index 07482c309..ff6e0cd8e 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -33,3 +33,4 @@ pub use self::messenger::{SimpleArcOnionMessenger, SimpleRefOnionMessenger}; pub use self::offers::{OffersMessage, OffersMessageHandler}; pub use self::packet::{Packet, ParsedOnionMessageContents}; pub(crate) use self::packet::ControlTlvs; +pub(crate) use self::messenger::new_pending_onion_message; diff --git a/lightning/src/onion_message/offers.rs b/lightning/src/onion_message/offers.rs index 254db7b81..533b4cb57 100644 --- a/lightning/src/onion_message/offers.rs +++ b/lightning/src/onion_message/offers.rs @@ -44,7 +44,15 @@ pub trait OffersMessageHandler { /// /// Typically, this is used for messages initiating a payment flow rather than in response to /// another message. The latter should use the return value of [`Self::handle_message`]. + #[cfg(not(c_bindings))] fn release_pending_messages(&self) -> Vec> { vec![] } + + /// Releases any [`OffersMessage`]s that need to be sent. + /// + /// Typically, this is used for messages initiating a payment flow rather than in response to + /// another message. The latter should use the return value of [`Self::handle_message`]. + #[cfg(c_bindings)] + fn release_pending_messages(&self) -> Vec<(OffersMessage, crate::onion_message::Destination, Option)> { vec![] } } /// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`]. -- 2.39.5