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

Limit payment path length based on payment_metadata, custom TLVs, etc. #3026

Merged

Conversation

valentinewallace
Copy link
Contributor

Currently the maximum payment path length is hardcoded in the router to 19. However, the presence of payment_metadata, custom TLVs, and/or blinded paths may mean that the actual limit is much shorter. Account for these extra onion fields when calculating and setting the maximum path length for use in pathfinding.

Closes #2201.


let num_reserved_bytes = match &route_params.payment_params.payee {
Payee::Blinded { route_hints, .. } => {
let largest_path = route_hints
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: currently I’m evaluating the max path length based on the largest blinded path, i.e. the blinded path that limits us the most. Therefore, if some blinded paths are larger than others, this could unnecessarily limit us in pathfinding. We could set the max path length on a per-blinded-path basis? In practice, ISTM that blinded paths within the same invoice are likely to be of similar sizes to each other.

@codecov-commenter
Copy link

codecov-commenter commented Apr 25, 2024

Codecov Report

Attention: Patch coverage is 97.88732% with 12 lines in your changes are missing coverage. Please review.

Project coverage is 89.85%. Comparing base (da7a916) to head (3cc673b).
Report is 4 commits behind head on main.

Files Patch % Lines
lightning/src/routing/router.rs 77.14% 8 Missing ⚠️
lightning/src/ln/max_payment_path_len_tests.rs 99.22% 2 Missing ⚠️
lightning/src/ln/outbound_payment.rs 91.66% 1 Missing and 1 partial ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3026      +/-   ##
==========================================
+ Coverage   89.79%   89.85%   +0.06%     
==========================================
  Files         116      117       +1     
  Lines       96466    97278     +812     
  Branches    96466    97278     +812     
==========================================
+ Hits        86619    87413     +794     
- Misses       7290     7314      +24     
+ Partials     2557     2551       -6     

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

@valentinewallace valentinewallace added this to the 0.0.124 milestone Apr 29, 2024
@valentinewallace
Copy link
Contributor Author

I found some more edge cases around how get_route counts hops as part of a path, so feel free to hold off on review there.

@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch 2 times, most recently from 8ef1770 to c8fbb96 Compare April 30, 2024 19:21
@valentinewallace
Copy link
Contributor Author

Rebased to (hopefully) fix CI. This should be good for review.

@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch 3 times, most recently from 7ee7c37 to 8de126d Compare May 13, 2024 23:08
@valentinewallace
Copy link
Contributor Author

Feedback should be addressed. Also this needs a rebase so let me know when I can do that.

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

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

Feel free to squash, IMO.

node_features: NodeFeatures::empty(),
short_channel_id: 42,
channel_features: ChannelFeatures::empty(),
fee_msat: route_params.final_value_msat,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be higher if we have to overpay when routing, so the object could serialize a bit longer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added some buffer here. I think my buffer is a bit conservative so let me know if it needs tuning.

Will be useful when we reuse this enum to calculate the maximum path length,
to avoid cloning the vecs.
Doable now that we take Vecs by reference in OutboundOnionPayload.
Will be used in the next commit when we make this configurable in
PaymentParameters.
@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch from 8de126d to 6255996 Compare May 14, 2024 20:48
Comment on lines +355 to +354
node_features: NodeFeatures::empty(),
short_channel_id: 42,
channel_features: ChannelFeatures::empty(),
Copy link
Contributor

Choose a reason for hiding this comment

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

In practice, would the features not be empty? Perhaps it is negligible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These features aren't included in onion payloads so don't impact encoding size.

Comment on lines +608 to +610
/// Sets the maximum number of hops that can be included in a payment path, based on the provided
/// [`RecipientOnionFields`] and blinded paths.
pub fn set_max_path_length(
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 expose this if max_path_length is overridden by outbound_payments.rs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was requested here: #3026 (comment). I suppose it could be useful if the user is calculating routes separately from sending a payment. Don't feel strongly about including it, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm... I see, though we should update ChannelManager::send_payment's docs to indicate that max_path_length is not honored then. Or maybe it would it be better to use the existing setting if it is smaller than what is computed instead of the default MAX_PATH_LENGTH_ESTIMATE?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or maybe it would it be better to use the existing setting if it is smaller than what is computed instead of the default MAX_PATH_LENGTH_ESTIMATE?

I think that's a good point, went this way in a fixup.

@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch from 6255996 to 08fada7 Compare May 15, 2024 21:14
Copy link
Contributor

@jkczyz jkczyz left a comment

Choose a reason for hiding this comment

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

I'm good if you want to squash

Comment on lines +608 to +610
/// Sets the maximum number of hops that can be included in a payment path, based on the provided
/// [`RecipientOnionFields`] and blinded paths.
pub fn set_max_path_length(
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm... I see, though we should update ChannelManager::send_payment's docs to indicate that max_path_length is not honored then. Or maybe it would it be better to use the existing setting if it is smaller than what is computed instead of the default MAX_PATH_LENGTH_ESTIMATE?

@@ -328,8 +328,9 @@ pub(crate) fn set_max_path_length(
.serialized_length()
.saturating_add(PAYLOAD_HMAC_LEN);

const OVERPAY_ESTIMATE_MULTIPLER: u64 = 3;
Copy link
Contributor

Choose a reason for hiding this comment

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

Just checking if the change from 4 to 3 was intentional.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, should've called this out but 3 felt cleaner somehow? As noted here #3026 (comment), these numbers may want tuning.

Will be useful when we want to calculate the total size of the payloads without
actually allocating for them.
@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch from 08fada7 to e6785dd Compare May 16, 2024 22:16
@valentinewallace
Copy link
Contributor Author

valentinewallace commented May 16, 2024

Squashed with 1 new fixup.

.ok_or(())?;

route_params.payment_params.max_path_length =
[max_path_length, route_params.payment_params.max_path_length, MAX_PATH_LENGTH_ESTIMATE]
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we even include MAX_PATH_LENGTH_ESTIMATE? If the computed max_path_length is smaller than the given one, shouldn't we prefer that over an estimated one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to include MAX_PATH_LENGTH_ESTIMATE here because the router currently has hardcoded assumptions that 19 will be the maximum path length. So if the computed value and the user-provided value are both higher than that, we still want to set the parameter to be the estimate.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see. Should that be capped in the router, though? That is, is it conceivable that a different router implementation would not have that assumption?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do cap it in the router so you're right it's not necessary. I thought it made sense to have some kind of upper bound, but we can remove it if you prefer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Went ahead and removed it in the latest push.

@@ -684,6 +698,11 @@ pub struct PaymentParameters {
/// Defaults to [`DEFAULT_MAX_PATH_COUNT`].
pub max_path_count: u8,

/// The maximum total number of hops in any returned path, including [`Path::hops`] and
/// [`BlindedTail::hops`].
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this is fine, but should we really be included the blinded tail? Its not really a part of the "path" in the sense that the router didn't pick it and we refer to it separately from the hops themselves. It also results in code specifically to add/remove it as an offset here and in the limit calculator, which we could just elide.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough, done in fixups.

@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch 2 times, most recently from 7d417a6 to 6622736 Compare May 20, 2024 19:26
Copy link
Contributor

@jkczyz jkczyz left a comment

Choose a reason for hiding this comment

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

LGTM. Feel free to squash.

Will be used so the outbound_payment module can calculate the maximum path
length with knowledge of any custom TLVs or payment metadata present.
Also adds some testing by augmenting existing tests.
So the router knows how long the maximum payment path can be.
@valentinewallace valentinewallace force-pushed the 2024-04-limit-path-len branch from 6622736 to 3cc673b Compare May 20, 2024 22:57
@valentinewallace
Copy link
Contributor Author

Squashed.

@TheBlueMatt TheBlueMatt merged commit 37bf61c into lightningdevkit:main May 21, 2024
16 checks passed
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.

Figure out path-length-limiting when routing with metadata/blinded paths
4 participants