What if instead of the payer generating the preimage the payee could generate stateless invoices? Basically just use some secret to compute the preimage upon receiving the HTLC, for example:
1. Payer requests an invoice. 2. Payee computes hash = sha256(hmac(local_secret, arbitrary_invoice_id)), then encodes arbitrary_invoice_id into the invoice somehow. 3. Payer sends payment with arbitrary_invoice_id as tlv_record_a. 4. Upon receiving the HTLC, payee computes preimage = hmac(local_secret, tlv_record_a) and resolves it. I've implemented such a scheme on @lntxbot, but it required low level code in a c-lightning plugin and a hack with route hints: since TLV payloads were not an option (as payers wouldn't know how to send them) I've used a "shadow" route hint to a private channel that didn't exist, so preimage was generated on the payee using preimage = hmac(local_secret, next_channel_scid). If however node implementations could provide such a thing it would reduce database requirements and improve the lives of application developers very much. On Tue, Sep 21, 2021 at 7:09 AM Joost Jager <joost.ja...@gmail.com> wrote: > 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. > > _______________________________________________ > Lightning-dev mailing list > Lightning-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev >
_______________________________________________ Lightning-dev mailing list Lightning-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev