BitcoinAndLightningLayerSpecs / lsp

API specifications for Lightning Service Providers
MIT License
109 stars 31 forks source link

Prepayment probing conflicts with LSPS2 (and JIT Channels in general) #44

Open ZmnSCPxj-jr opened 1 year ago

ZmnSCPxj-jr commented 1 year ago

As reported in the 2023-07-26 meeting, prepayment probing causes LSPS2 JIT channels to open prematurely.

Briefly, prepayment probing is a technique where a payer temporarily replaces the payment hash of an invoice with a randomly-generated one, then performs normal payment attempt. If the payment fails at the payee (client in LSPS2) with unknown_or_incorrect_payment_details, then the payer knows it was able to reach the payee with a specific fee paid to the routing nodes, and can with high probability reuse the same path with the correct payment hash to reach the payee.

The typical use-case is with a custodial wallet where the UI first shows "calculating LN fees" to the user while performing the prepayment probe. Then once the payment has reached the payee and gotten unknown_or_incorrect_payment_details failure, the UI displays the fee (which is deducted from the custodial user account) and a confirmation prompt whether to pay with the fee or not.

With JIT channels (not just LSPS2 specifically), there are two problems:

The latter is the problem we need to fix in LSPS2.

Here are solutions proposed so far:

kingonly commented 1 year ago

There's also a simple workaround Breez and Muun are implementing currently: https://github.com/breez/lspd#probing-support

https://github.com/lightningnetwork/lnd/pull/4785

ZmnSCPxj-jr commented 1 year ago

There's also a simple workaround Breez and Muun are implementing currently: https://github.com/breez/lspd#probing-support

This still requires the LSP to know the payment hash, which is not compatible with keysend-style payments (and therefore asynchronous payments), has the error unknown_or_incorrect_payment_details arise from the LSP hop instead of the final payee (violates BOLT spec), and requires that payers implement this kind of probing as opposed to just a random payment_hash. LSPS4 remains a more complete solution.

An even simpler (non-)solution of the same style would be to just have the client always give every payment hash it issues to the LSP, and if the LSP receives a payment hash outside of the set given by the client, give the same error as that proposal. No need to modify payers to use SHA256("probing-01"|payment_hash). Because for the LSP to recognize this the client has to hand over the payment_hash anyway. At least that way payers do not have to be modified.

yaslama commented 1 year ago

We can add a field jit_channel_probing_scid in the return object of lsps2.buy and this scid will be used for the probing.

ZmnSCPxj-jr commented 1 year ago

We can add a field jit_channel_probing_scid in the return object of lsps2.buy and this scid will be used for the probing.

It is the payer which does probing. Often the way the payer learns anything from the payee (client in this case) is via BOLT11 invoice. Are you proposing to add a new bespoke BOLT11 field for this? That seems like an even harder solution; now you have to convince everyone to add such a field to BOLT11 invoices, not just payers but probably needs more feedback from the wider set of users of BOLT11.

yaslama commented 1 year ago

We can add a field jit_channel_probing_scid in the return object of lsps2.buy and this scid will be used for the probing.

It is the payer which does probing. Often the way the payer learns anything from the payee (client in this case) is via BOLT11 invoice. Are you proposing to add a new bespoke BOLT11 field for this? That seems like an even harder solution; now you have to convince everyone to add such a field to BOLT11 invoices.

The payee can send two invoices to the payer or better let jit_channel_probing_scid be calculated from jit_channel_scid (for instance by xoring the 3 bytes of the tx index to 0xffffff). So the LSP can always detect that it's a probing for a specific channel request.

ZmnSCPxj-jr commented 1 year ago

The payee can send two invoices to the payer or better let jit_channel_probing_scid be calculated from jit_channel_scid (for instance by xoring the 3 bytes of the tx index to 0xffffff). So the LSP can always detect that it's a probing for a specific channel request.

Still needs a payer implementation change. It is better if we adapt to existing payer implementations than to force payer implementations to adapt to us.

kingonly commented 1 year ago

Still needs a payer implementation change. It is better if we adapt to existing payer implementations than to force payer implementations to adapt to us.

Depends on the alternative. The probing landscape is pretty clear: Strike, Galoy, Binance and perhaps a couple of more. It's very manageable and we were able to work with them to adopt the payer implementations. If there's a BLIP, I don't think this would be an issue.

kingonly commented 1 year ago

lnd is now documenting this for private channel probing: https://docs.lightning.engineering/lightning-network-tools/lnd/payments#prepay-probes-to-private-wallets

Binance has agreed to implement it and Galoy are already implementing it. I think it's a good enough solution.

ZmnSCPxj-jr commented 1 year ago

@kingonly looks good. Still, I think having some text, in case someone else implements naive probing that goes all the way to the payee.

tnull commented 1 year ago

lnd is now documenting this for private channel probing: https://docs.lightning.engineering/lightning-network-tools/lnd/payments#prepay-probes-to-private-wallets

Binance has agreed to implement it and Galoy are already implementing it. I think it's a good enough solution.

Note that the corresponding paragraphs are somehow gone from the LND docs (cf. https://docs.lightning.engineering/lightning-network-tools/lnd/payments#prepay-probes)

kingonly commented 1 year ago

Note that the corresponding paragraphs are somehow gone from the LND docs (cf. https://docs.lightning.engineering/lightning-network-tools/lnd/payments#prepay-probes)

I believe this because lnd decided to implement it as part of their estimatefee.