From: shaavan Date: Fri, 14 Jun 2024 12:36:05 +0000 (+0530) Subject: Introduce MessageContext in ReceiveTlvs X-Git-Tag: v0.0.124-beta~56^2~2 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=7f82cde861e7b1842ac62df29711af73af62246b;p=rust-lightning Introduce MessageContext in ReceiveTlvs 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. --- diff --git a/lightning/src/blinded_path/message.rs b/lightning/src/blinded_path/message.rs index bdbb4be45..973df8539 100644 --- a/lightning/src/blinded_path/message.rs +++ b/lightning/src/blinded_path/message.rs @@ -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 } impl Writeable for ForwardTlvs { @@ -78,12 +78,58 @@ impl Writeable for ReceiveTlvs { fn write(&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), +} + +/// 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( secp_ctx: &Secp256k1, intermediate_nodes: &[ForwardNode], recipient_node_id: PublicKey, @@ -99,7 +145,7 @@ pub(super) fn blinded_hops( 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) } diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index abab6714d..03d35bbba 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -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 { /// 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, Option<[u8; 32]>, Option) + /// Received onion message, with decrypted contents, context, and reply path + Receive(ParsedOnionMessageContents, Option, Option) } @@ -946,9 +946,23 @@ where (control_tlvs_ss, custom_handler.deref(), logger.deref()) ) { Ok((Payload::Receive::::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 = _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)