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

Blinded Paths: clarify outgoing_cltv_value for final hop #1097

Merged
merged 2 commits into from
Jul 31, 2023

Conversation

carlaKC
Copy link
Contributor

@carlaKC carlaKC commented Jul 24, 2023

This PR replaces #1066, picking this up as discussed in the spec meeting!

Senders making payments to a blinded route know the total cltv_delta for the blinded portion of the route, but not the min_final_cltv_delta for the final hop. This PR updates the instructions for the sender to set the final hop's outgoing_cltv_detla to current_height + any random offset added.

See gist for additional context.

When paying a blinded path, we don't have a CLTV delta at each hop
available, but rather only a total CLTV delta for the entire
blinded path.

However, the onion format currently still requires that we specify
an `outgoing_cltv_value` for the final hop. As the sender, we don't
have a sensible value to put there, as we don't know which part of
the total CLTV delta belongs to the recipient.

The sender is instructed to use the values that are known to them
when setting `outgoing_cltv_value` for the final hop:
- The current block height.
- Any additional delta added to account for block propagation and
  improve privacy.

This change reflects the behavior of some implementations at the time
of writing.
Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

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

LGTM 👍

People who implemented blinded paths should definitely take a look at https://gist.github.com/t-bast/b1371d357a2c5f3e8c09514a62db7079 and make sure I didn't miss anything (otherwise there may be a probing issue).


- For every node inside a blinded route:
- MUST include the `encrypted_recipient_data` provided by the recipient
- For the first node in the blinded route:
- MUST include the `blinding_point` provided by the recipient in `current_blinding_point`
- If it is the final node:
- MUST include `amt_to_forward`, `outgoing_cltv_value` and `total_amount_msat`.
- The value set for `outgoing_cltv_value`:
- MUST use the current block height as a baseline value.
Copy link
Contributor

@ProofOfKeags ProofOfKeags Jul 25, 2023

Choose a reason for hiding this comment

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

If I understand this correctly, the outgoing_cltv_value is a replacement integrity check on the final onion packet to make sure that nodes along the route haven't laid claim to larger shares of the original CLTV budget than they were alotted.

Looking here it states that the final node:

MUST return an error if incoming cltv_expiry < current_block_height + min_final_cltv_expiry_delta.

It seems to me that if I read your change as written then the final HTLC can be exactly equal to the current block height. This means that without the random offset (specified as SHOULD), then there is zero "headroom" to resolve the HTLC.

Maybe this edge case is allowable, but it does seem to me that we should EITHER:

  1. relax the baseline from MUST to SHOULD
  2. constrict the offset recommendation from SHOULD to MUST
  3. add a mandatory offset > 0 to the current block height as the baseline

Leaving this as is is also acceptable but it would mean that valid implementations of the spec can run into this weird edge case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems to me that if I read your change as written then the final HTLC can be exactly equal to the current block height. This means that without the random offset (specified as SHOULD), then there is zero "headroom" to resolve the HTLC.

This is not an issue, for two different reasons:

  1. The same issue exists with non-blinded payments: this is why implementations currently already add a small random offset to the current block height to avoid this issue
  2. Even if the sender doesn't add a random offset, the recipient will add one in the blinded path's total cltv_expiry_delta, to make sure it covers its min_final_cltv_expiry_delta (to allow the recipient enough time before fulfilling this HTLC without risk of the downstream node using the HTLC-timeout path)

Copy link
Contributor

@ProofOfKeags ProofOfKeags left a comment

Choose a reason for hiding this comment

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

ACK dd0af11

@rustyrussell
Copy link
Collaborator

Ack!

@niftynei niftynei merged commit 9ab3c87 into lightning:master Jul 31, 2023
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.

7 participants