From joost.jager at gmail.com Tue Sep 21 10:08:06 2021 From: joost.jager at gmail.com (Joost Jager) Date: Tue, 21 Sep 2021 12:08:06 +0200 Subject: [Lightning-dev] Stateless invoices with proof-of-payment Message-ID: <CAJBJmV_nazFFf1SDhzo2gLRDe+ASChPxWKPM4zG9ObtyaXz6KQ@mail.gmail.com> Problem One of the qualities of lightning is that it can provide light-weight, no-login payments with minimal friction. Games, paywalls, podcasts, etc can immediately present a QR code that is ready for scan and pay. Optimistically presenting payment requests does lead to many of those payment requests going unused. A user visits a news site and decides not to buy the article. The conventional approach is to create a lightning invoice on a node and store the invoice together with order details in a database. If the order then goes unfulfilled, cleaning processes remove the data from the node and database again. The problem with this setup is that it needs protection against unbounded generation of payment requests. There are solutions for that such as rate limiting, but wouldn't it be nice if invoices can be generated without the need to keep any state at all? Stateless invoices What would happen if a lightning invoice is only generated and stored nowhere on the recipient side? To the user, it won't make a difference. They would still scan and pay the invoice. When the payment arrives at the recipient though, two problems arise: 1. Recipient doesn't know whom or what the payment is for. This can be solved by attaching additional custom tlv records to the htlc. On the wire, this is all arranged for. The only missing piece is the ability to specify additional data for that custom tlv record in a bolt11 invoice. One way would be to define a new tagged field for this in which the recipient can encode the order details. An alternative is to use the existing invoice description field and simply always pass that along with the htlc as a custom tlv record. A second alternative that already works today is to use part (for example 16 out of 32 bytes) of the payment_secret (aka payment address) to encode the order details in. This assumes that the secret is still secret enough with reduced entropy. Also there may not be enough space for every application. 2. Recipient doesn't know the preimage that is needed to settle the htlc(s). One option is to use a keysend payment or AMP payment. In that case, the sender includes the preimage with the htlc. Unfortunately this doesn't provide the sender with a proof of payment that they'd get with a regular lightning payment. An alternative solution is to use a deterministic preimage based on a (recipient node key-derived) secret, the payment secret and other relevant properties. This allows the recipient to derive the same preimage twice: Once when the lightning invoice is generated and again when a payment arrives. It could be something like this: payment_secret = random preimage = H(node_secret | payment_secret | payment_amount | encoded_order_details) invoice_hash = H(preimage) The sender sends an htlc locked to invoice_hash for payment_amount and passes along payment_secret and encoded_order_details in a custom tlv record. When the recipient receives the htlc, they reconstruct the preimage according to the formula above. At this point, all data is available to do so. When H(preimage) indeed matches the htlc hash, they can settle the payment knowing that this is an order that they committed to earlier. Settling could be implemented as a just-in-time inserted invoice to keep the diff small. The preimage is returned to the sender and serves as a proof of payment. Resilience To me it seems that stateless invoices can be a relatively simple way to improve the resiliency of systems that deal with lightning invoices. Unlimited amounts of invoices can be generated without worrying about storage or memory, no matter if the requests are due to popularity of a service or a deliberate dos attack. Interested to hear your thoughts. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20210921/788f449b/attachment-0001.html>