[Lightning-dev] Stateless invoices with proof-of-payment

Olaoluwa Osuntokun laolu32 at gmail.com
Wed Sep 22 23:40:55 UTC 2021


Hi Joost,

> 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?

Isn't this ultimately an engineering issue? How much exactly is "too much"
in this case? Invoices are relatively small, and also don't even necessarily
need to be ever written to disk assuming a slim expiration window. It's
likely the case that a service can just throw everything in Redis and call
it a day. In terms of rate limiting a service would likely already need to
implement that on the API/service level to mitigate app level DoS attacks.

As far as pre-images go, this can already be "stateless" by generating a
single random seed (storing that somewhere w/ a counter likely) and then
using shachain or elkrem to deterministically generate payment hashes. You
can then either use the payment_addr/secret to index into the hash chain, or
have the user send some counter extracted from the invoice as a custom
record. Similar schemes have been proposed in the past to support "offline"
vending machine payments.

Taking it one step further, the service could maintain a unique
elkrem/shachain state for each unique user, which would then allow them to
also collapse the pre-image into the hash chain, which lets them save space
and be able to reproduce a given "proof that someone in the world paid"
(that no service/wallet seems to accept/generate in an
automated/standardized manner) statement dynamically.

-- Laolu


On Tue, Sep 21, 2021 at 3:08 AM Joost Jager <joost.jager at 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 at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20210922/d6fd7732/attachment-0001.html>


More information about the Lightning-dev mailing list