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

Open
wants to merge 7 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>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • 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 testing code 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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 using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • 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/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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 Outdated Show resolved Hide resolved
lightning/src/onion_message/packet.rs Outdated 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
lightning/src/blinded_path/message.rs Outdated Show resolved Hide resolved
@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
lightning/src/blinded_path/payment.rs Outdated Show resolved Hide resolved
lightning/src/blinded_path/message.rs Outdated Show resolved Hide resolved
lightning/src/util/ser_macros.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
@shaavan
Copy link
Contributor Author

shaavan commented Oct 25, 2024

Updated from pr2380.02 to pr2830.03 (diff):
Addressed @TheBlueMatt comments

Changes:

  • Rebase on main branch to resolve conflicts.
  • Introduce custom TLVs as a simple Option<Vec>.
  • Expose an interface to allow users to add custom TLVs to message::ReceiveTlvs.

Note:

  • The Option<Vec<u8>> field in message::ReceiveTlvs was chosen to support initializing Receive Payload with None fields, needed for a case in fn packet_payloads_and_keys.

I'm still refining the approach for custom TLVs within payment::ReceiveTlvs. Before moving forward with testing, I’d appreciate feedback on this initial approach. Thanks so much for your input!

@shaavan
Copy link
Contributor Author

shaavan commented Nov 5, 2024

Updated from pr2380.03 to pr2830.04 (diff):

Changes:

  1. Introduce the sender_custom_tlvs & user_custom_tlvs distinction.
  2. Introduce custom_tlvs in payment::ReceiveTlvs

@shaavan
Copy link
Contributor Author

shaavan commented Nov 7, 2024

Updated from pr2380.04 to pr2830.05 (diff):

Changes:

  1. Finalise & corrected the approach.
  2. Introduced test.

@shaavan
Copy link
Contributor Author

shaavan commented Nov 7, 2024

Updated from pr2380.05 to pr2830.06 (diff):

Changes:

  1. Rebase on main.

@shaavan shaavan marked this pull request as ready for review November 7, 2024 13:56
Copy link

codecov bot commented Nov 7, 2024

Codecov Report

Attention: Patch coverage is 95.98854% with 14 lines in your changes missing coverage. Please review.

Project coverage is 89.23%. Comparing base (ba3d4ff) to head (7399605).

Files with missing lines Patch % Lines
lightning/src/ln/outbound_payment.rs 85.71% 3 Missing and 1 partial ⚠️
lightning/src/onion_message/messenger.rs 91.66% 3 Missing ⚠️
lightning-dns-resolver/src/lib.rs 50.00% 2 Missing ⚠️
lightning/src/ln/channelmanager.rs 96.87% 0 Missing and 1 partial ⚠️
lightning/src/ln/msgs.rs 97.72% 0 Missing and 1 partial ⚠️
lightning/src/ln/offers_tests.rs 80.00% 1 Missing ⚠️
lightning/src/ln/peer_handler.rs 0.00% 1 Missing ⚠️
lightning/src/onion_message/functional_tests.rs 98.70% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2830      +/-   ##
==========================================
- Coverage   89.25%   89.23%   -0.02%     
==========================================
  Files         130      130              
  Lines      106959   107116     +157     
  Branches   106959   107116     +157     
==========================================
+ Hits        95464    95590     +126     
- Misses       8706     8727      +21     
- Partials     2789     2799      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

lightning/src/blinded_path/message.rs Outdated Show resolved Hide resolved
lightning/src/blinded_path/message.rs Show resolved Hide resolved
lightning/src/blinded_path/message.rs Outdated Show resolved Hide resolved
@@ -187,7 +187,9 @@ pub enum PendingHTLCRouting {
/// For HTLCs received by LDK, this will ultimately be exposed in
/// [`Event::PaymentClaimable::onion_fields`] as
/// [`RecipientOnionFields::custom_tlvs`].
custom_tlvs: Vec<(u64, Vec<u8>)>,
sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
/// Custom TLVs which were set by us through the reply path
Copy link
Contributor

Choose a reason for hiding this comment

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

"Sent by us" isn't really accurate. The sender is still sending them to us. It's just that we construct a blinded path for them to use which included the TLVs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the docs to clarify how user_custom_tlvs will be used in pr2830.08. Let me know if they look good! Thanks!

pub context: Option<MessageContext>,

/// Custom Tlvs. A user can use this to send custom tlvs information back to themself.
pub custom_tlvs: Option<Vec<u8>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this is just custom data rather than custom TLVs. Nothing is enforcing that this data is encoded as a TLV stream.

@TheBlueMatt Not sure if you have any thoughts on how if we should make this a Vec<(u64, Vec<u8>)> instead? And, if so, if we should encode it inside type 65539 or place them directly in ReceiveTlvs, restricting TLVs >= 2^16 and all the checks that that entails.

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 not sure why it needs to be TLVs explicitly. ISTM users can just do whatever encoding of whatever data they want and we can store it in a single TLV. We should of course have some documentation that suggests users consider forward-compatibility in their encoding, pushing it all through TLVs on our end seems like overkill, I think? I don't feel incredibly strongly here, though, if we want to eat all the work of verifying TLV types and such we can go that route again instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now, I've updated the documentation to include a clear note on Forward Compatibility.
Let me know if we prefer moving to the Vec<(u64, Vec<u8>)> approach—I’d would love to integrate that!

} => {
// We need to update [`ln::outbound_payment::RecipientOnionFields::with_custom_tlvs`]
// to reject any reserved types in the experimental range if new ones are ever
// standardized.
let user_custom_tlv = (!user_custom_tlvs.is_empty()).then(|| (65537, user_custom_tlvs.to_vec()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to allocate a new Vec here?

@shaavan
Copy link
Contributor Author

shaavan commented Nov 25, 2024

Updated from pr2380.06 to pr2830.07 (diff):

Changes:

  1. Rebase on main to resolve merge conflicts.

- Introduces the ability for users to include custom TLVs
within blinded paths.
- For paths used to reach them (e.g., offer or reply paths),
users can attach custom data that is returned when the path
is utilized.
- This update introduces a clear separation between two types
  of custom TLVs: those sent by the sender for the user, and
  those added by the user to the reply path, which are expected
  to return with the response.
- This commit establishes this distinction in the codebase at
  relevant points.
- The next commit will build on this by providing an interface for
  users to add their own custom TLVs to the reply path, allowing
  them to receive specific data back in the response.

Note:
1. Similar to keysend, for serialization purposes, user_custom_tlv
   are assigned a specific TLV number.
2. For uniformity, user_custom_tlv are assigned the lowest possible
   odd number after (1 << 16), which is 65537.
- Building on the previous commit, this update allows users to
  include their own custom TLVs within the reply path of a sent
  onion message.
- With this, users can attach custom data to the message, which
  will be returned in the response, providing more flexibility for
  custom use cases.
@shaavan
Copy link
Contributor Author

shaavan commented Nov 26, 2024

Updated from pr2380.07 to pr2830.08 (diff):
Addressed @jkczyz comments

Changes:

  1. Updated documentation.
  2. Update create_blinded_path to take receive_tlvs as input.
  3. Fix CI.

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.

4 participants