]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Introduce MessageContext in ReceiveTlvs
authorshaavan <shaavan.github@gmail.com>
Fri, 14 Jun 2024 12:36:05 +0000 (18:06 +0530)
committershaavan <shaavan.github@gmail.com>
Mon, 8 Jul 2024 20:15:13 +0000 (01:45 +0530)
1. New Enum for Enhanced Data Handling:
   - Introduced the `MessageContext` enum, which allows the node to include
     additional context data along with the `reply_path` sent to the counterparty.
   - The node anticipates receiving this data back for further processing.

2. Variants in MessageContext:
   - The `MessageContext` enum includes two variants: "Offers" and
     "Context"
   - One of the variants, `Offers`, holds the `payment_id`
     of the associated Outbound BOLT12 Payment.

3. Future Usage:
   - This enum will be utilized in a subsequent commit to abandon outbound
     payments that have failed to complete for various reasons.

lightning/src/blinded_path/message.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/packet.rs

index bdbb4be4541d2ce8f3aa34840263de963b23ec57..973df8539ce191045e928d4992b9436b5b87df62 100644 (file)
@@ -12,7 +12,6 @@
 //! [`BlindedPath`]: crate::blinded_path::BlindedPath
 
 use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
-
 #[allow(unused_imports)]
 use crate::prelude::*;
 
@@ -20,6 +19,7 @@ use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NextMessage
 use crate::blinded_path::utils;
 use crate::io;
 use crate::io::Cursor;
+use crate::ln::channelmanager::PaymentId;
 use crate::ln::onion_utils;
 use crate::onion_message::packet::ControlTlvs;
 use crate::sign::{NodeSigner, Recipient};
@@ -52,10 +52,10 @@ pub(crate) struct ForwardTlvs {
 
 /// Similar to [`ForwardTlvs`], but these TLVs are for the final node.
 pub(crate) struct ReceiveTlvs {
-       /// If `path_id` is `Some`, it is used to identify the blinded path that this onion message is
+       /// If `context` is `Some`, it is used to identify the blinded path that this onion message is
        /// sending to. This is useful for receivers to check that said blinded path is being used in
        /// the right context.
-       pub(crate) path_id: Option<[u8; 32]>,
+       pub context: Option<MessageContext>
 }
 
 impl Writeable for ForwardTlvs {
@@ -78,12 +78,58 @@ impl Writeable for ReceiveTlvs {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                // TODO: write padding
                encode_tlv_stream!(writer, {
-                       (6, self.path_id, option),
+                       (65537, self.context, option),
                });
                Ok(())
        }
 }
 
+/// Represents additional data included by the recipient in a [`BlindedPath`].
+///
+/// This data is encrypted by the recipient and remains invisible to anyone else.
+/// It is included in the [`BlindedPath`], making it accessible again to the recipient
+/// whenever the [`BlindedPath`] is used.
+/// The recipient can authenticate the message and utilize it for further processing
+/// if needed.
+#[derive(Clone, Debug)]
+pub enum MessageContext {
+       /// Represents the data specific to [`OffersMessage`]
+       ///
+       /// [`OffersMessage`]: crate::onion_message::offers::OffersMessage
+       Offers(OffersContext),
+       /// Represents custom data received in a Custom Onion Message.
+       Custom(Vec<u8>),
+}
+
+/// Contains the data specific to [`OffersMessage`]
+///
+/// [`OffersMessage`]: crate::onion_message::offers::OffersMessage
+#[derive(Clone, Debug)]
+pub enum OffersContext {
+       /// Represents an unknown BOLT12 payment context.
+       /// This variant is used when a message is sent without
+       /// using a [`BlindedPath`] or over one created prior to
+       /// LDK version 0.0.124.
+       Unknown {},
+       /// Represents an outbound BOLT12 payment context.
+       OutboundPayment {
+               /// Payment ID of the outbound BOLT12 payment.
+               payment_id: PaymentId
+       },
+}
+
+impl_writeable_tlv_based_enum!(MessageContext, ;
+       (0, Offers),
+       (1, Custom),
+);
+
+impl_writeable_tlv_based_enum!(OffersContext,
+       (0, Unknown) => {},
+       (1, OutboundPayment) => {
+               (0, payment_id, required),
+       },
+;);
+
 /// Construct blinded onion message hops for the given `intermediate_nodes` and `recipient_node_id`.
 pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
        secp_ctx: &Secp256k1<T>, intermediate_nodes: &[ForwardNode], recipient_node_id: PublicKey,
@@ -99,7 +145,7 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
                        None => NextMessageHop::NodeId(*pubkey),
                })
                .map(|next_hop| ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override: None }))
-               .chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs { path_id: None })));
+               .chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs { context: None })));
 
        utils::construct_blinded_hops(secp_ctx, pks, tlvs, session_priv)
 }
index abab6714df1e50aed2c293fee3398726b7e1cd34..03d35bbba5570c50d43e531b2cf392e25f806eaf 100644 (file)
@@ -16,7 +16,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
 
 use crate::blinded_path::{BlindedPath, IntroductionNode, NextMessageHop, NodeIdLookUp};
-use crate::blinded_path::message::{advance_path_by_one, ForwardNode, ForwardTlvs, ReceiveTlvs};
+use crate::blinded_path::message::{advance_path_by_one, ForwardNode, ForwardTlvs, ReceiveTlvs, MessageContext};
 use crate::blinded_path::utils;
 use crate::events::{Event, EventHandler, EventsProvider};
 use crate::sign::{EntropySource, NodeSigner, Recipient};
@@ -795,8 +795,8 @@ pub trait CustomOnionMessageHandler {
 pub enum PeeledOnion<T: OnionMessageContents> {
        /// Forwarded onion, with the next node id and a new onion
        Forward(NextMessageHop, OnionMessage),
-       /// Received onion message, with decrypted contents, path_id, and reply path
-       Receive(ParsedOnionMessageContents<T>, Option<[u8; 32]>, Option<BlindedPath>)
+       /// Received onion message, with decrypted contents, context, and reply path
+       Receive(ParsedOnionMessageContents<T>, Option<MessageContext>, Option<BlindedPath>)
 }
 
 
@@ -946,9 +946,23 @@ where
                (control_tlvs_ss, custom_handler.deref(), logger.deref())
        ) {
                Ok((Payload::Receive::<ParsedOnionMessageContents<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage>> {
-                       message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
+                       message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { context }), reply_path,
                }, None)) => {
-                       Ok(PeeledOnion::Receive(message, path_id, reply_path))
+                       match (&message, &context) {
+                               (_, None) => {
+                                       Ok(PeeledOnion::Receive(message, None, reply_path))
+                               }
+                               (ParsedOnionMessageContents::Offers(_), Some(MessageContext::Offers(_))) => {
+                                       Ok(PeeledOnion::Receive(message, context, reply_path))
+                               }
+                               (ParsedOnionMessageContents::Custom(_), Some(MessageContext::Custom(_))) => {
+                                       Ok(PeeledOnion::Receive(message, context, reply_path))
+                               }
+                               _ => {
+                                       log_trace!(logger, "Received message was sent on a blinded path with the wrong context.");
+                                       Err(())
+                               }
+                       }
                },
                Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {
                        next_hop, next_blinding_override
@@ -1432,11 +1446,11 @@ 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, _context, reply_path)) => {
                                log_trace!(
                                        logger,
-                                       "Received an onion message with path_id {:02x?} and {} reply_path: {:?}",
-                                       path_id, if reply_path.is_some() { "a" } else { "no" }, message);
+                                       "Received an onion message with {} reply_path: {:?}",
+                                       if reply_path.is_some() { "a" } else { "no" }, message);
 
                                let responder = reply_path.map(Responder::new);
                                match message {
@@ -1727,7 +1741,7 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
                }, prev_control_tlvs_ss.unwrap()));
        } else {
                payloads.push((Payload::Receive {
-                       control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id: None, }),
+                       control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { context: None }),
                        reply_path: reply_path.take(),
                        message,
                }, prev_control_tlvs_ss.unwrap()));
index fca7dd6a91ac6a1eda39e5519822c1c9101df78c..49b3f6642ab47ff6d76fbb6402c2158c74fe8911 100644 (file)
@@ -319,8 +319,8 @@ impl Readable for ControlTlvs {
                        (1, _padding, option),
                        (2, short_channel_id, option),
                        (4, next_node_id, option),
-                       (6, path_id, option),
                        (8, next_blinding_override, option),
+                       (65537, context, option),
                });
                let _padding: Option<Padding> = _padding;
 
@@ -331,7 +331,7 @@ impl Readable for ControlTlvs {
                        (None, None) => None,
                };
 
-               let valid_fwd_fmt = next_hop.is_some() && path_id.is_none();
+               let valid_fwd_fmt = next_hop.is_some();
                let valid_recv_fmt = next_hop.is_none() && next_blinding_override.is_none();
 
                let payload_fmt = if valid_fwd_fmt {
@@ -341,7 +341,7 @@ impl Readable for ControlTlvs {
                        })
                } else if valid_recv_fmt {
                        ControlTlvs::Receive(ReceiveTlvs {
-                               path_id,
+                               context,
                        })
                } else {
                        return Err(DecodeError::InvalidValue)