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

2. Variants in RecipientData:
   - The `RecipientData` enum includes two variants.
   - One of the variants, `OffersContext`, 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

index bdbb4be4541d2ce8f3aa34840263de963b23ec57..f299fbfd9f5bd28f6fa36e22dd2c461b6f1d526b 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,11 +19,13 @@ 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::msgs::DecodeError;
 use crate::ln::onion_utils;
 use crate::onion_message::packet::ControlTlvs;
 use crate::sign::{NodeSigner, Recipient};
 use crate::crypto::streams::ChaChaPolyReadAdapter;
-use crate::util::ser::{FixedLengthReader, LengthReadableArgs, Writeable, Writer};
+use crate::util::ser::{FixedLengthReader, LengthReadableArgs, Readable, Writeable, Writer};
 
 use core::mem;
 use core::ops::Deref;
@@ -55,7 +56,7 @@ pub(crate) struct ReceiveTlvs {
        /// If `path_id` 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 path_id: Option<MessageContext>
 }
 
 impl Writeable for ForwardTlvs {
@@ -84,6 +85,57 @@ impl Writeable for ReceiveTlvs {
        }
 }
 
+impl Readable for ReceiveTlvs {
+       fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
+               _init_and_read_tlv_stream!(r, {
+                       (6, path_id, option),
+               });
+               Ok(ReceiveTlvs { path_id })
+       }
+}
+
+/// Represents additional data included by the recipient in a [`BlindedPath`].
+///
+/// This data is encrypted and will be included when sending through
+/// [`BlindedPath`]. 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 the data appended with 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 context.
+       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,
index c3f920a85883c73a16e4dcf4be8c64ac07b27088..3bd5c08c9e22272ca19472a5e946976c259ade66 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, recipient data, 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 { path_id: 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, _recipient_data, 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 { path_id: None }),
                        reply_path: reply_path.take(),
                        message,
                }, prev_control_tlvs_ss.unwrap()));