Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce custom TLV support for OnionMessage #2830

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

shaavan
Copy link
Contributor

@shaavan shaavan commented Jan 15, 2024

Part of #1970

Follow up with custom TLV support for blinded paths

TODO:

  • Introduced Custom TLV support for ControlTlvs
  • Update test suite to test for this change
  • Update documentation

Copy link

coderabbitai bot commented Jan 15, 2024

Walkthrough

The updates involve the integration of custom_tlvs fields within various structures and enumerations related to onion messaging, enhancing the protocol's extensibility. New macros for decoding custom TLV (Type-Length-Value) streams have been introduced, streamlining the handling of these new fields. The modifications to the blinded_hops and advance_path_by_one functions reflect the need to process these additional custom TLV elements within the messaging flow.

Changes

Files Change Summary
.../blinded_path/message.rs
.../blinded_path/payment.rs
.../ln/blinded_payment_tests.rs
Added and updated custom_tlvs fields and related logic.
.../ln/channelmanager.rs Added custom_tlvs field to a data structure.
.../ln/msgs.rs
.../onion_message/messenger.rs
.../onion_message/packet.rs
Added custom_tlvs fields and adjusted logic for message handling.
.../util/ser_macros.rs Introduced new macros for custom TLV decoding and added explanatory comments.

🐇✨
To the code with love and glee,
We've added TLVs, as you can see.
With macros new, and structures bright,
Our onion messages take flight! 🚀🌠

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between ea5de93 and 55098b4.
Files selected for processing (4)
  • lightning/src/blinded_path/message.rs (4 hunks)
  • lightning/src/onion_message/messenger.rs (4 hunks)
  • lightning/src/onion_message/packet.rs (2 hunks)
  • lightning/src/util/ser_macros.rs (2 hunks)
Additional comments: 13
lightning/src/blinded_path/message.rs (4)
  • 25-26: The addition of the custom_tlvs field to the ForwardTlvs struct is consistent with the PR's objective to support custom TLVs.
  • 35-36: The addition of the custom_tlvs field to the ReceiveTlvs struct aligns with the PR's goal of extending TLV support.
  • 67-69: The update to the blinded_hops function correctly initializes custom_tlvs with an empty vector, which is consistent with the changes made to the ForwardTlvs and ReceiveTlvs structs.
  • 87-87: The changes in the advance_path_by_one function correctly handle the custom_tlvs when reading the ControlTlvs::Forward variant, aligning with the PR's objectives to support custom TLVs.
lightning/src/onion_message/packet.rs (2)
  • 285-300: The custom TLV decoding logic added to the ControlTlvs enum is consistent with the PR's objective to support custom TLVs and appears to correctly handle the decoding process.
  • 312-317: The handling of custom_tlvs in the ControlTlvs enum when constructing the payload format is appropriate and aligns with the changes made to support custom TLVs.
lightning/src/onion_message/messenger.rs (5)
  • 630-630: The addition of custom_tlvs to the ReceiveControlTlvs::Unblinded variant aligns with the PR's objective to support custom TLVs.
  • 635-636: The addition of custom_tlvs to the ForwardControlTlvs::Unblinded variant is consistent with the changes made to ReceiveControlTlvs and supports the PR's goal for custom TLV support.
  • 1112-1112: The initialization of custom_tlvs with Vec::new() in the ForwardTlvs struct is correct and ensures that the vector is empty by default.
  • 1123-1123: The addition of custom_tlvs with an empty vector in the ForwardTlvs struct within the ForwardControlTlvs::Unblinded variant is consistent with the other changes and is correctly implemented.
  • 1157-1157: The ReceiveTlvs struct is correctly updated to include custom_tlvs with an empty vector, which is in line with the PR's objectives.
lightning/src/util/ser_macros.rs (2)
  • 475-475: The macro decode_tlv_stream_with_custom_tlv_decode is correctly defined and follows the established pattern for TLV stream decoding with the addition of custom TLV handling.
  • 829-845: The macro _init_and_read_tlv_stream_with_custom_tlv_decode is correctly defined and follows the established pattern for initializing and reading a TLV stream with custom TLV decoding.

lightning/src/blinded_path/message.rs Outdated Show resolved Hide resolved
lightning/src/blinded_path/message.rs Show resolved Hide resolved
lightning/src/onion_message/packet.rs Show resolved Hide resolved
@shaavan
Copy link
Contributor Author

shaavan commented Jan 15, 2024

With the current version of PR, I am seeking concept/approach ACKs before I start working on the test suite.

A gentle ping, @jkczyz :)
Thanks!

lightning/src/blinded_path/message.rs Outdated Show resolved Hide resolved
@@ -30,6 +32,8 @@ pub(crate) struct ReceiveTlvs {
/// 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]>,
/// Custom Tlvs
pub(crate) custom_tlvs: Vec<(u64, Vec<u8>)>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valentinewallace is this one also LDK-specific in the way payment::ReceiveTlvs is?

In any case, we should really focus on including custom tlvs in payment::ReceiveTlvs (or, not sure if we need "generic custom TLVs" so much as "user provides one Vec<u8> that we put in one TLV).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valentinewallace is this one also LDK-specific in the way payment::ReceiveTlvs is?

Yep!

Copy link
Contributor Author

@shaavan shaavan Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was planning to handle the changes related to OnionMessage and BlindedPayment separately.
But it seems more logical now to handle them together.
Introduced custom_tlvs support for payment::ReceiveTlvs in c9d57f8
Let me know if I am on the right track approach-wise!
Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valentinewallace is this one also LDK-specific in the way payment::ReceiveTlvs is?

In any case, we should really focus on including custom tlvs in payment::ReceiveTlvs (or, not sure if we need "generic custom TLVs" so much as "user provides one Vec<u8> that we put in one TLV).

@TheBlueMatt FYI, the BOLT 12 payment notifications scheme that Jeff wrote up includes blinded payment paths that aren't constructed by the receiver, so this may not be LDK specific anymore.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll have to follow up on that separately, but good call out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second part of the comment here I think still stands, though - there's no reason to support generic custom TLVs, I think, but rather we should focus on supporting reading a single Vec<u8> that users can put whatever they want in (including a TLV stream).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not convinced this needs to be a vec of pairs, rather than a single Vec<u8>. Is there a reason you left this as-is?

@shaavan
Copy link
Contributor Author

shaavan commented Jan 17, 2024

Updated from pr2380.01 to pr2830.02 (diff):
Address @TheBlueMatt comments

  1. Removed custom_tlvs for ForwardTlvs, as they don't seem logically feasible.
  2. Added custom_tlvs for BlindedPaths::payment:: ReceiveTlvs
  3. Fixed issues as pointed out by @coderabbitai

Note:
Some of the tests related to BlindedPaths and OnionMessages are failing due to the changes in this PR.
To avoid unnecessary work, I will address those once I get an approach ACK with the changes in this PR.
Thanks!

Copy link

coderabbitai bot commented Jan 17, 2024

@shaavan It sounds like you've made significant progress on the PR by addressing previous comments and making adjustments to the custom_tlvs implementation. Regarding the failing tests for BlindedPaths and OnionMessages, it's a prudent approach to wait for an ACK on the current changes before proceeding with test suite updates. If there's anything specific you'd like me to look into or any particular area you need feedback on, please let me know.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fbeb7ac and c9d57f8.
Files selected for processing (8)
  • lightning/src/blinded_path/message.rs (3 hunks)
  • lightning/src/blinded_path/payment.rs (10 hunks)
  • lightning/src/ln/blinded_payment_tests.rs (3 hunks)
  • lightning/src/ln/channelmanager.rs (1 hunks)
  • lightning/src/ln/msgs.rs (1 hunks)
  • lightning/src/onion_message/messenger.rs (2 hunks)
  • lightning/src/onion_message/packet.rs (2 hunks)
  • lightning/src/util/ser_macros.rs (2 hunks)
Files skipped from review as they are similar to previous changes (4)
  • lightning/src/blinded_path/message.rs
  • lightning/src/onion_message/messenger.rs
  • lightning/src/onion_message/packet.rs
  • lightning/src/util/ser_macros.rs
Additional comments: 17
lightning/src/blinded_path/payment.rs (9)
  • 19-19: The Read trait has been imported from crate::io.
  • 57-58: A custom_tlvs field of type Vec<(u64, Vec<u8>)> has been added to the ReceiveTlvs struct to store custom TLV entries.
  • 127-127: The Writeable trait implementation for ReceiveTlvs has been updated to include the custom_tlvs field with an optional_vec encoding.
  • 145-173: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [148-182]

The Readable trait implementation for BlindedPaymentTlvs has been modified to decode custom TLVs and populate the custom_tlvs field in ReceiveTlvs.

  • 344-344: The test compute_payinfo has been updated to include an empty custom_tlvs vector in the ReceiveTlvs struct.
  • 363-363: The test compute_payinfo_1_hop has been updated similarly to include an empty custom_tlvs vector in the ReceiveTlvs struct.
  • 417-417: The test simple_aggregated_htlc_min has been updated to include an empty custom_tlvs vector in the ReceiveTlvs struct.
  • 468-468: The test aggregated_htlc_min has been updated to include an empty custom_tlvs vector in the ReceiveTlvs struct.
  • 523-523: The test aggregated_htlc_max has been updated to include an empty custom_tlvs vector in the ReceiveTlvs struct.
lightning/src/ln/blinded_payment_tests.rs (3)
  • 59-59: The addition of custom_tlvs: Vec::new() initializes an empty vector for custom TLVs. This is consistent with the PR's objective to introduce custom TLV support. However, it's important to ensure that this new field is actually used somewhere in the code or tests, otherwise it's dead code.
Verification successful

The custom_tlvs field is actively used throughout the codebase, including in tests, message handling, and payment processing. This confirms that the addition of this field is not dead code and aligns with the PR's objectives.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify if custom_tlvs are used elsewhere in the codebase
rg "custom_tlvs" --type rust

Length of output: 11880

* 93-93: The same `custom_tlvs: Vec::new()` addition here. The comment for the `get_blinded_route_parameters` function applies here as well. Ensure that the `custom_tlvs` field is utilized effectively in the codebase. * 136-136: Again, `custom_tlvs: Vec::new()` is added. The same verification is needed to ensure that this field is not just dead code and is actually being used as intended.
Verification successful

The custom_tlvs field is actively used throughout the codebase, including in payment processing and onion message handling. The initialization of custom_tlvs with an empty vector is consistent with its usage in other parts of the code, where it is later populated and utilized. Therefore, the addition of custom_tlvs: Vec::new(), in the mpp_to_one_hop_blinded_path function aligns with the intended use of custom TLVs within the codebase.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Reusing the previous verification script as it applies here too
rg "custom_tlvs" --type rust

Length of output: 11880

lightning/src/ln/msgs.rs (3)
  • 2400-2401: The custom_tlvs field in the ReceiveTlvs struct is being matched to _, which indicates that any value is accepted but not used within the block. Please confirm if this is the intended behavior, as it may be necessary to handle custom_tlvs explicitly if they are to be used for processing or validation.
  • 2401-2401: The use of unwrap_or(0) for total_msat assumes that a missing total_msat can be treated as 0. Please ensure that this assumption is valid in all cases, as it could lead to unexpected behavior if total_msat is expected to be provided but is not.
  • 2401-2401: The error handling for amt_msat using ok_or(DecodeError::InvalidValue) is appropriate and ensures that a missing amt_msat results in a decode error.
lightning/src/ln/channelmanager.rs (2)
  • 7942-7942: The addition of the custom_tlvs field initialized with an empty vector seems appropriate for optional or extendable features. Ensure that this field is properly populated and utilized in the downstream logic where the blinded payment paths are created.
  • 7942-7942: Verify if the custom_tlvs field should be passed to the create_blinded_payment_paths function. If it is intended to be used for handling custom TLVs within the blinded payment paths, it may need to be included in the function call.

Copy link

coderabbitai bot commented Jan 17, 2024

@shaavan Great to hear that you've addressed the comments from @TheBlueMatt and made the necessary changes to the custom_tlvs. It's a sound strategy to wait for an approach ACK before tackling the failing tests. If you need a review on the recent changes or any other assistance, feel free to ask.

Action performed

Review triggered.

@shaavan
Copy link
Contributor Author

shaavan commented Feb 7, 2024

The are still some conceptual kinks to be ironed out before finalising the custom TLV's implementation.
So Drafting up the PR for now! ♻️

@shaavan shaavan marked this pull request as draft February 7, 2024 11:53
});
let _padding: Option<utils::Padding> = _padding;

if let Some(short_channel_id) = scid {
if payment_secret.is_some() { return Err(DecodeError::InvalidValue) }
if !custom_tlvs.is_empty() { return Err(DecodeError::InvalidValue) }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We dont want to reject unknown odd tlvs.

@@ -30,6 +32,8 @@ pub(crate) struct ReceiveTlvs {
/// 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]>,
/// Custom Tlvs
pub(crate) custom_tlvs: Vec<(u64, Vec<u8>)>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not convinced this needs to be a vec of pairs, rather than a single Vec<u8>. Is there a reason you left this as-is?

@@ -472,6 +472,7 @@ macro_rules! decode_tlv_stream {
///
/// [`FixedLengthReader`]: crate::util::ser::FixedLengthReader
/// [`DecodeError`]: crate::ln::msgs::DecodeError
#[macro_export]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you start exporting this?

@@ -7939,6 +7939,7 @@ where
max_cltv_expiry,
htlc_minimum_msat: 1,
},
custom_tlvs: Vec::new(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we be exposing this to users so they can start using it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants