Skip to content

Send normal failures for Bolt12 payments#773

Merged
t-bast merged 1 commit into
masterfrom
rework-bolt12-errors
Apr 1, 2025
Merged

Send normal failures for Bolt12 payments#773
t-bast merged 1 commit into
masterfrom
rework-bolt12-errors

Conversation

@t-bast
Copy link
Copy Markdown
Member

@t-bast t-bast commented Mar 28, 2025

Since we are always using 1-hop blinded paths from our LSP to ourselves, there are no public intermediate nodes that could be probed inside that blinded path. The requirement to always return malformed failure is thus unnecessary (and harmful for the payer who doesn't know why the payment failed). We now return normal failures in that case, which should be forwarded by our LSP to the upstream nodes.

This also fixes an issue where non-trampoline blinded payments were not correctly failed because the extraction of the onion shared secret did not uses the path_key to derive the blinded onion decryption key.

Since we are always using 1-hop blinded paths from our LSP to ourselves,
there are no public intermediate nodes that could be probed inside that
blinded path. The requirement to always return malformed failure is thus
unnecessary (and harmful for the payer who doesn't know why the payment
failed). We now return normal failures in that case, which should be
forwarded by our LSP to the upstream nodes.

This also fixes an issue where non-trampoline blinded payments were not
correctly failed because the extraction of the onion shared secret did
not uses the `path_key` to derive the blinded onion decryption key.
@t-bast t-bast requested review from dpad85, pm47 and thomash-acinq March 28, 2025 14:18
@thomash-acinq
Copy link
Copy Markdown
Contributor

There are no public intermediate nodes but the sender doesn't know it. By returning normal failures we would tell the sender that the recipient is a phoenix.
But maybe it's just the spec that's too restrictive and should be changed: intermediate nodes should obfuscate their errors to not leak information but the final node can return unobfuscated errors. We would need to check if some error from the recipient could leak information on the path.

@t-bast
Copy link
Copy Markdown
Member Author

t-bast commented Mar 28, 2025

There are no public intermediate nodes but the sender doesn't know it. By returning normal failures we would tell the sender that the recipient is a phoenix.

Sure, but that doesn't hurt because they're thus hiding in the anonymity set of all wallet users directly connected to our node (which in the future will include more than Phoenix once the LSP specs are stabilized). Since it doesn't reveal their node_id (they encrypt with their blinded node_id), it doesn't reveal any identifying information that wasn't already in the invoice?

But maybe it's just the spec that's too restrictive and should be changed: intermediate nodes should obfuscate their errors to not leak information but the final node can return unobfuscated errors. We would need to check if some error from the recipient could leak information on the path.

We already had this discussion on the spec, and we cannot do that in the general case, otherwise this lets intermediate nodes inside the blinded path probe who the recipient is. I think we should only lift this requirement in this specific case of a wallet node (which thus has no public channels) connected to an LSP (and thus benefiting from the anonymity set of that LSP).

@thomash-acinq
Copy link
Copy Markdown
Contributor

It does reduce the anonymity set from "any peer of the LSP (public nodes and wallets)" to only "wallets using this non-standard variation (so just phoenix)".

@t-bast
Copy link
Copy Markdown
Member Author

t-bast commented Mar 28, 2025

It does reduce the anonymity set from "any peer of the LSP (public nodes and wallets)"

We're already in the anonymity set of only Phoenix wallet users because we use a 1-hop blinded path, which nobody else will use.

Other wallets that support on-the-fly-funding will also want to return non-blinded failures in that case, so it will eventually be all mobile wallet users connected to that LSP.

Also, we already discussed with @pm47 that in the future, we may allow phoenix users to customize their blinded path (e.g. using a different introduction node than ours), in which case they will send blinded failures. I believe that by default, sending non-blinded failures is a better trade-off: an attacker doesn't learn much by just learning that you're using Phoenix (which they already know based on feature bits in the invoice).

Copy link
Copy Markdown
Member

@pm47 pm47 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 too unfamiliar with blinded payments to validate the implementation, but ACK on the approach.

@dpad85 is preparing a custom phoenix build for validation before an official release.

@t-bast t-bast merged commit 1222f8e into master Apr 1, 2025
@t-bast t-bast deleted the rework-bolt12-errors branch April 1, 2025 13:30
dpad85 pushed a commit that referenced this pull request Apr 3, 2025
Since we are always using 1-hop blinded paths from our LSP to ourselves,
there are no public intermediate nodes that could be probed inside that
blinded path. The requirement to always return malformed failure is thus
unnecessary (and harmful for the payer who doesn't know why the payment
failed). We now return normal failures in that case, which should be
forwarded by our LSP to the upstream nodes.

This also fixes an issue where non-trampoline blinded payments were not
correctly failed because the extraction of the onion shared secret did
not uses the `path_key` to derive the blinded onion decryption key.

(cherry picked from commit 1222f8e)
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