Skip to content

Commit

Permalink
Introduce MessageContext in ReceiveTlvs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
shaavan committed Jul 8, 2024
1 parent 7e2fde7 commit 7f82cde
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 17 deletions.
56 changes: 51 additions & 5 deletions lightning/src/blinded_path/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
//! [`BlindedPath`]: crate::blinded_path::BlindedPath
use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};

#[allow(unused_imports)]
use crate::prelude::*;

use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NextMessageHop, NodeIdLookUp};
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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand All @@ -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)
}
Expand Down
32 changes: 23 additions & 9 deletions lightning/src/onion_message/messenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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>)
}


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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()));
Expand Down
6 changes: 3 additions & 3 deletions lightning/src/onion_message/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {
Expand All @@ -341,7 +341,7 @@ impl Readable for ControlTlvs {
})
} else if valid_recv_fmt {
ControlTlvs::Receive(ReceiveTlvs {
path_id,
context,
})
} else {
return Err(DecodeError::InvalidValue)
Expand Down

0 comments on commit 7f82cde

Please sign in to comment.