Use a tuple, not a struct, for `PendingOnionMessage` in bindings
authorMatt Corallo <git@bluematt.me>
Mon, 23 Oct 2023 18:55:17 +0000 (18:55 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 23 Oct 2023 19:42:32 +0000 (19:42 +0000)
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
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/mod.rs
lightning/src/onion_message/offers.rs

index 2bf60cdc7971454d2afb30f8c6aef9eed9508d4a..c4efd895796e67d1f3c1ecc46e5559b277c5cc9b 100644 (file)
@@ -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);
                                        }
                                }
index 200ee44ee32b89a93d8b8907c7dc949ce77522cb..cf0f9e086b5c41a12c2e9b1b5e27f3a03949fae7 100644 (file)
@@ -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<T: OnionMessageContents> {
        /// The message contents to send in an [`OnionMessage`].
        pub contents: T,
@@ -170,6 +171,22 @@ pub struct PendingOnionMessage<T: OnionMessageContents> {
        pub reply_path: Option<BlindedPath>,
 }
 
+#[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: OnionMessageContents> = (T, Destination, Option<BlindedPath>);
+
+pub(crate) fn new_pending_onion_message<T: OnionMessageContents>(
+       contents: T, destination: Destination, reply_path: Option<BlindedPath>
+) -> PendingOnionMessage<T> {
+       #[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<PendingOnionMessage<Self::CustomMessage>>;
+
+       /// 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<BlindedPath>)>;
 }
 
 /// 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<OnionMessage> {
                // 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")
                        );
index 07482c3092e610e978512969ecc48c562b3d1190..ff6e0cd8e5d59a44324838a9156bce79ae0ea45e 100644 (file)
@@ -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;
index 254db7b81bdf12d89c3a1b739e4da7e06faa5d18..533b4cb571805c98be6d4235fef190de00d7ff7c 100644 (file)
@@ -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<PendingOnionMessage<OffersMessage>> { 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<crate::blinded_path::BlindedPath>)> { vec![] }
 }
 
 /// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`].