bolts icon indicating copy to clipboard operation
bolts copied to clipboard

Offers

Open rustyrussell opened this issue 4 years ago • 81 comments

Offers are "static invoices", with many more features. This is mostly implemented in c-lightning already, and is now ready for wider testing.

This PR is based on onion messages specified in #759

rustyrussell avatar Aug 31 '20 20:08 rustyrussell

I have merged the million-fixup-commits into one commit, and trivially rebased onto the updated #759.

The last two commits are new:

  1. Make spelling happy.
  2. Add a method to replace invoices; I've not yet implemented this though!

rustyrussell avatar Apr 16 '21 05:04 rustyrussell

I have a question with respect to replacing invoices and the fact that we can proof if the payee claimed both htlcs:

What is the use of that? As far as I understand we could sue the person but this won't give us a cryptographic guarantee to get our money back as even a convicted person might have run or just have already spent the money. Or do I miss something?

The only fix that cryptographically would give us a guarantee to not pay twice that I can think of only seems to shift the problem of stuck payments (and would thus create a burden to the network) and is the following:

  • Assume Alice sends out an onion to Bob over some path that gets stuck
  • Alice wants to use your replacement mechanism to cancle the payment.
  • before (!) sending out a new onion with the new payment hash alice waits for an incoming htlc of the old payment hash (this assumes that Bob after sending out the replacement invoice sets a "reimbursement path" to Alice.

Now we have 2 scenarios:

  1. The orinal payment times out and gets unstuck. Alice would also cancle the reimbursement payment (of course opening Bob to a stuck payment attack from Alice or actually from anyone else when he sets up the reimbursement path)
  2. The original onion arrives at Bob. He should fail the onion and if so Alice should fail the reimbursement onion once her initial htlc is withdrawn or if Bob claims the funds Alice can use the preimage on the reimbursement path to claim her money back.

As said initially: I don't think the reimbursement path (which is by the way inspired by the boomerang paper c.f.: https://arxiv.org/abs/1910.01834 ) solves any issue in our case because the reimbursement path is also open to stuck payment attacks and overall we bind liquidity in two directions now.

renepickhardt avatar Apr 16 '21 06:04 renepickhardt

What is the use of that? As far as I understand we could sue the person but this won't give us a cryptographic guarantee to get our money back as even a convicted person might have run or just have already spent the money. Or do I miss something?

Today, the seller can already accept the payment and not deliver the product which is not very different from accepting the payment twice. These real world interactions can't be enforced by cryptography, we need to trust the seller (or the legal system in which the seller operates). The best we can get is a cryptographic proof that the seller misbehaved that can be used so that other people stop trusting this seller (or for prosecuting the seller).

thomash-acinq avatar Apr 16 '21 07:04 thomash-acinq

What is the use of that? As far as I understand we could sue the person but this won't give us a cryptographic guarantee to get our money back as even a convicted person might have run or just have already spent the money. Or do I miss something?

Today, the seller can already accept the payment and not deliver the product which is not very different from accepting the payment twice. These real world interactions can't be enforced by cryptography, we need to trust the seller (or the legal system in which the seller operates). The best we can get is a cryptographic proof that the seller misbehaved that can be used so that other people stop trusting this seller (or for prosecuting the seller).

Exactly, you still risk paying twice, but you can prove it happened and that they promised it wouldn't. Not perfect, but it's an option.

rustyrussell avatar Jun 30 '21 06:06 rustyrussell

OK, trivial rebase to fixup, and also new commits:

  1. signatures on offers are now optional. This makes them much smaller, particularly on mainnet where it's just "node_id", "description" and any optional fields. We might deprecate them altogether?
  2. @renepickhardt suggested that adding capacities for each blinded path would be a good feature, and as it's completely optional I added it.
  3. @niftynei suggested a payer note field, where the payer could make some comment. This is particularly useful for tips, and again completely optional to implement, so I added it.

rustyrussell avatar Jun 30 '21 06:06 rustyrussell

It would be cool, if offers included a standard way to exchange information to comply with the FATF travel rule. VASPs need a way to verify that a customer has control over the wallet where a deposit comes from or a withdrawal goes to. For On-chain this is usually done by either signing a message or executing a micro transaction. Now maybe it is enough to define a workflow to require the customer to put a specific message to the payer_note field. But even if that works out, it might be better to have specific fields and a standardized workflow.

ulrichard avatar Aug 25 '21 13:08 ulrichard

@rustyrussell Is it possible to use a BOLT12 that's generated on the fly by the payer with just the payee's node pubkey? Since the signature on Offers is optional, I'm thinking that it could be used as a safe way to have the functionality of keysend where the only known thing is the payee's node pubkey, but without keysend's downsides/risks.

Kudos for doing this btw.

cryptagoras avatar Sep 01 '21 13:09 cryptagoras

@rustyrussell Is it possible to use a BOLT12 that's generated on the fly by the payer with just the payee's node pubkey? Since the signature on Offers is optional, I'm thinking that it could be used as a safe way to have the functionality of keysend where the only known thing is the payee's node pubkey, but without keysend's downsides/risks.

Kudos for doing this btw.

Indeed, it's possible to have a "default" offer, where we assume all other fields are absent, and simply try paying it. But it's also trivial to add later, so...

rustyrussell avatar Sep 21 '21 04:09 rustyrussell

OK, at @t-bast 's suggestion I removed recurrence for now. You're free to implement it, ofc, but don't assume wallets support it yet.

I've also (trivially) rebased on the latest #759 draft.

rustyrussell avatar Oct 13 '21 03:10 rustyrussell

OK, I fixed the incorrect placement of the offers fields, rebased onto the latest #759 and squashed some fixup commits. It's still more than one commitment because I think it's useful to see the broad changes which have occurred, just not every typo!

rustyrussell avatar Nov 18 '21 03:11 rustyrussell

I just finished reading up on stateless bolt11 invoices (https://github.com/lightning/bolts/pull/912), would there be a similar mechanism for bolt12 invoices? would it just be a matter of including the payment_metadata tlv or are there other considerations?

jb55 avatar Mar 24 '22 17:03 jb55

I just finished reading up on stateless bolt11 invoices (#912), would there be a similar mechanism for bolt12 invoices? would it just be a matter of including the payment_metadata tlv or are there other considerations?

With blinded routes, you can include any payment_metadata you want in the last blinded payload.

thomash-acinq avatar Mar 24 '22 17:03 thomash-acinq

@thomash-acinq: ah yes I just found this comment by @t-bast which mentioned this. neat, thx!

jb55 avatar Mar 24 '22 17:03 jb55

Hey everyone, super pumped for BOLT12. One thing: is there a way we could add a signature to this offer? As an example, I have a website that's presenting a BOLT12 invoice for payment. However, there is a malicious web extension in the browser, which swaps the QR/invoice on the page. User pays the attacker and payment flow gets broken.

Is there a way we can add a recoverable, compressed secp256k1 signature to the offer, as well as a domain? This would (1) allow us to verify public key of the signature with public key available at the domain (whether through DNS or HTTPS, haven't decided yet), letting us put a big green checkmark in the user's wallet to show they're indeed paying the company they want to.

And (2) would then allow us to do info fetching outside payment flow. For example, fetching an image of the company's logo and formatted company name to display in the wallet (which is very useful for UX).

If not and we want to keep this down, that's okay too. We'll likely be looking at building another specification which would incorporate a BOLT12 and other features, and we could add this functionality in there.

Zk2u avatar Apr 18 '22 09:04 Zk2u

Yes, it is optional but the offer can include a signature if you want. However I would expect most offers to not be signed to fit in smaller QR codes. But even if the offer is not signed, the invoice will be, so any check that would have done on the offer can be done on the invoice.

thomash-acinq avatar Apr 19 '22 08:04 thomash-acinq

Thanks, this makes a lot of sense. Assuming we don't put a signature in the offer, could we add some sort of domain field then? Actually, rather than adding it directly into BOLT12 which could bloat it, it would probably be optimal to do this in a wrapper protocol, right? Maybe the domain approves a certain list of node IDs that it owns and that is available outside LN.

Zk2u avatar Apr 19 '22 09:04 Zk2u

Submitted a PR to force the use blinded routes when paying: https://github.com/rustyrussell/lightning-rfc/pull/4

thomash-acinq avatar Jul 01 '22 14:07 thomash-acinq

New PR to switch to full public keys (like everywhere else in the spec): https://github.com/rustyrussell/lightning-rfc/pull/5 I'll update my code and will post some tests vectors here soon.

thomash-acinq avatar Jul 20 '22 08:07 thomash-acinq

I've added some new test vectors: https://github.com/rustyrussell/lightning-rfc/pull/6 They should be up to date with all the recent changes (including mandatory blinded paths and full 33 bytes keys).

thomash-acinq avatar Jul 20 '22 15:07 thomash-acinq

@rustyrussell Is it possible to use a BOLT12 that's generated on the fly by the payer with just the payee's node pubkey? Since the signature on Offers is optional, I'm thinking that it could be used as a safe way to have the functionality of keysend where the only known thing is the payee's node pubkey, but without keysend's downsides/risks.

Kudos for doing this btw.

Yes, this can be done, by convention. Simply define a "default" offer, (e.g. no, or empty description), any anyone can generate that offer given the pubkey. If you want to accept that kind of offer, you generate that locally, and it will Just Work.

rustyrussell avatar Aug 01 '22 03:08 rustyrussell

I just finished reading up on stateless bolt11 invoices (#912), would there be a similar mechanism for bolt12 invoices? would it just be a matter of including the payment_metadata tlv or are there other considerations?

@thomash-acinq points out that you can do this with blinded paths already, which simply says "put this blob inside the onion"...

rustyrussell avatar Aug 01 '22 04:08 rustyrussell

Hey everyone, super pumped for BOLT12.

First off, thanks for your spelling review! I applied almost all ("e.g." is used in the style guide, so I left that).

One thing: is there a way we could add a signature to this offer? As an example, I have a website that's presenting a BOLT12 invoice for payment. However, there is a malicious web extension in the browser, which swaps the QR/invoice on the page. User pays the attacker and payment flow gets broken.

The sensitivity here is "is this the right nodeid"? For that, you want something like https://github.com/rustyrussell/bolt12address

And (2) would then allow us to do info fetching outside payment flow. For example, fetching an image of the company's logo and formatted company name to display in the wallet (which is very useful for UX).

Definitely: I would love to add this metadata to the proposal above.

To be clear: I don't want to normalize "your wallet reaches to company X's website when scanning their offer" as it's such a huge privacy leak. Hence having a bundle you can validate yourself, so you can fetch it from anyone...

If not and we want to keep this down, that's okay too. We'll likely be looking at building another specification which would incorporate a BOLT12 and other features, and we could add this functionality in there.

Yeah, I think this is best built on-top, but it is important!

rustyrussell avatar Aug 01 '22 04:08 rustyrussell

OK, rebased on latest #759 and folded into a single, neat "draft 5" commit.

I've added one commit, which defines our first invoice feature (mpp). Feedback welcome!

rustyrussell avatar Sep 15 '22 02:09 rustyrussell

Rebased again, with more quantity_max requirement tweaks thanks to @jkczyz

rustyrussell avatar Oct 17 '22 02:10 rustyrussell

BOLT 12 offers static QR codes for "offers" that won't change. How is it possible for the QR code to be static if a blinded path is used? Since routes are not guaranteed to be static forever, it seems like this is not possible. Or, is the static QR code just not applicable when blinded paths are used?

AndySchroder avatar Nov 02 '22 13:11 AndySchroder

Since routes are not guaranteed to be static forever, it seems like this is not possible.

I believe you're mostly referring to payment blinded paths which expire quickly (for privacy reasons), but the offer blinded path is used to fetch invoices over onion messages, where you can have blinded paths that don't expire. An offer blinded path will only expire if:

  • one of the nodes inside the path has permanently disappeared
  • a pair of nodes in the path have no channels between themselves and disabled onion messages relay to non-channel peers

So there are cases where you'll need to refresh the offer's blinded path depending on your use-case, but it shouldn't be that often.

t-bast avatar Nov 02 '22 13:11 t-bast

Okay, so choosing a blinded path where all peers in the path have many channels between each other gives me a high likelihood of the path remaining static because (1) if they have a lot of channels between each other that hints to me that they likely won't disappear in the future because they are committed to their presence in the network, and (2) they have lots of channels between each other so if one gets closed for whatever reason there will still be a redundant channel to fall back on to send the invoice request message over?

Also, it's unclear whether I can specify multiple blinded paths in an offer to give even more redundancy over a node in the path permanently disappearing (or if only one blinded path is allowed).

Why do payment blinded paths need to expire quickly for privacy reasons by offer blinded paths don't need to expire quickly for privacy reasons?

AndySchroder avatar Nov 02 '22 13:11 AndySchroder

Why do payment blinded paths need to expire quickly for privacy reasons by offer blinded paths don't need to expire quickly for privacy reasons?

This is quite technical, have a look at the route blinding PR for that. Long story short is that a payment has many parameters that a sender can tweak, which may lead to different decisions from intermediate nodes, which gives the sender a way to probe and figure out which channels are actually used. Onion messages don't have any of those.

t-bast avatar Nov 02 '22 14:11 t-bast

General comment: BOLT 12 seems to rely on changes to other BOLTS for the route blinding and onion messaging features. There doesn't seem to be any revision to a BOLT other than what GIT provides. I'm aware that "The specifications are currently a work-in-progress and currently being drafted.", but it seems if they should remain in an alpha or beta state, there should be some indicator that a major overhaul to a BOLT was made and that a feature in a new BOLT relies on a feature in a heavily revised existing BOLT. It's hard for me to follow where all the stuff advertised on https://bolt12.org/ comes from when reading https://bolt12.org/bolt12.html .

AndySchroder avatar Nov 02 '22 14:11 AndySchroder

Also, it's unclear whether I can specify multiple blinded paths in an offer to give even more redundancy over a node in the path permanently disappearing (or if only one blinded path is allowed).

The * in the following notation indicates more than one blinded path can be specified:

[...*blinded_path:paths]

jkczyz avatar Nov 02 '22 14:11 jkczyz