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

NodeRelayer should index payments by payment_hash || payment_secret #1723

Closed
t-bast opened this issue Mar 8, 2021 · 4 comments · Fixed by #1770
Closed

NodeRelayer should index payments by payment_hash || payment_secret #1723

t-bast opened this issue Mar 8, 2021 · 4 comments · Fixed by #1770
Assignees

Comments

@t-bast
Copy link
Member

t-bast commented Mar 8, 2021

Right now, the NodeRelayer indexes child actors by payment_hash only.
It means that senders must know beforehand the total amount they will send through each trampoline node.
This works fine for single-trampoline scenarios, but will not work with multi-trampoline scenarios: if the payer splits his payment between several trampoline routes and one fails, he may end up sending more additional HTLCs to a previous route when retrying.
Right now, we will reject them because the payment_secret doesn't match, or we'll simply fail to relay them (if the payment_secret is reused) and wait for a timeout from the final recipient.

We should instead index by payment_hash || payment_secret, but that requires extracting the payment_secret a bit higher up in our call stack.

@t-bast t-bast self-assigned this Mar 8, 2021
@pm47
Copy link
Member

pm47 commented Mar 8, 2021

That one looks subtle 🤓

It means that senders must know beforehand the total amount they will send through each trampoline node.

Can you clarify?

We should instead index by payment_hash || payment_secret,

Wouldn't that have the side effect of us not being able anymore to differentiate between a wrong payment_secret and a missing payment part?

@t-bast
Copy link
Member Author

t-bast commented Mar 8, 2021

Imagine Alice tries to make the following payment, where Bob and Carol are distinct trampoline nodes:

  +-------> Bob -------+
  |                    |
Alice                 Dave
  |                    |
  +-------> Carol -----+

Alice sends N htlcs to Bob and M htlcs to Carol, all part of the same payment to Dave.
Bob correctly forwards to Dave, which starts waiting for the remaining parts.
But Carol doesn't have enough liquidity so she fails the payment.
Alice retries ignoring Carol and ends up sending another batch of htlcs through Bob.
Right now these htlcs will be instantly rejected by Bob, so the payment cannot succeed.
But if that second batch uses a different payment_secret (which it should), Bob could treat it separately from the first batch and Dave will receive the complete payment.

Wouldn't that have the side effect of us not being able anymore to differentiate between a wrong payment_secret and a missing payment part?

I don't think we have a choice, we must allow having multiple payments for the same payment_hash but with distinct payment_secrets to unblock the multi-trampoline scenario...there is not such thing as a "wrong" payment_secret for intermediate trampoline nodes, different payment_secrets mean different payment attempts by the sender.

t-bast added a commit that referenced this issue Apr 15, 2021
We need to group incoming HTLCs together by payment_hash and payment_secret,
otherwise we will reject valid payments that are split into multiple distinct
trampoline parts (same payment_hash but different payment_secret).

Fixes #1723
t-bast added a commit that referenced this issue May 4, 2021
We need to group incoming HTLCs together by payment_hash and payment_secret,
otherwise we will reject valid payments that are split into multiple distinct
trampoline parts (same payment_hash but different payment_secret).

Fixes #1723
@ecdsa
Copy link

ecdsa commented Jun 10, 2021

is this currently deployed on the ACINQ node?

@t-bast
Copy link
Member Author

t-bast commented Jun 11, 2021

@ecdsa yes it is, let me know if you're seeing issues with 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 a pull request may close this issue.

3 participants