Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support async payments in BOLT 12 #1149

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .aspell.en.pws
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,14 @@ IFDUP
sats
anysegwit
onionmsg
unrequested
Merkle
whitespace
TLVs
LnLeaf
LnNonce
LnBranch
payinfo
griefing
unspendable
pkh
Expand Down
8 changes: 8 additions & 0 deletions 01-messaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,17 @@ The following convenience types are also defined:
* `channel_id`: a 32-byte channel_id (see [BOLT #2](02-peer-protocol.md#definition-of-channel-id))
* `sha256`: a 32-byte SHA2-256 hash
* `signature`: a 64-byte bitcoin Elliptic Curve signature
* `bip340sig`: a 64-byte bitcoin Elliptic Curve Schnorr signature as per [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki)
* `point`: a 33-byte Elliptic Curve point (compressed encoding as per [SEC 1 standard](http://www.secg.org/sec1-v2.pdf#subsubsection.2.3.3))
* `short_channel_id`: an 8 byte value identifying a channel (see [BOLT #7](07-routing-gossip.md#definition-of-short-channel-id))
* `sciddir_or_pubkey`: either 9 or 33 bytes referencing or identifying a node, respectively
* if the first byte is 0 or 1, then an 8-byte `short_channel_id` follows for a total of 9 bytes
* 0 for the first byte indicates this refers to `node_id_1` in the `channel_announcement` for `short_channel_id`
* 1 for the first byte indicates this refers to `node_id_2` in the `channel_announcement` for `short_channel_id`
(see [BOLT #7](07-routing-gossip.md#the-channel_announcement-message)
* if the first byte is 2 or 3, then the value is a 33-byte `point`
* `bigsize`: a variable-length, unsigned integer similar to Bitcoin's CompactSize encoding, but big-endian. Described in [BigSize](#appendix-a-bigsize-test-vectors).
* `utf8`: a byte as part of a UTF-8 string. A writer MUST ensure an array of these is a valid UTF-8 string, a reader MAY reject any messages containing an array of these which is not a valid UTF-8 string.

## Setup Messages

Expand Down
51 changes: 51 additions & 0 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -1912,6 +1912,25 @@ is destined, is described in [BOLT #4](04-onion-routing.md).
* [`sha256`:`payment_hash`]
* [`u32`:`cltv_expiry`]
* [`1366*byte`:`onion_routing_packet`]
* [`update_add_htlc_tlvs`:`tlvs`]

1. `tlv_stream`: `update_add_htlc_tlvs`
2. types:
1. type: 0 (`hold_htlc`)
2. data:
* [`32*bytes`:`payment_release_secret`]

#### TLV fields for `held_htlc_available`
1. `tlv_stream`: `held_htlc_available`
2. types:

#### TLV fields for `release_held_htlc`

1. `tlv_stream`: `release_held_htlc`
2. types:
1. type: 0 (`payment_release_secret`)
2. data:
* [`32*bytes`:`payment_release_secret`]

1. `tlv_stream`: `update_add_htlc_tlvs`
2. types:
Expand Down Expand Up @@ -1956,6 +1975,19 @@ A sending node:
- MUST increase the value of `id` by 1 for each successive offer.
- if it is relaying a payment inside a blinded route:
- MUST set `blinding_point` (see [Route Blinding](04-onion-routing.md#route-blinding))
- MUST NOT include a `hold_htlc` TLV unless the sending node expects the
final recipient of the HTLC to be offline at the time the HTLC would arrive
- MUST NOT include a `hold_htlc` TLV unless the sending node expects to be
offline for an extended duration starting soon.
- If the `hold_htlc` TLV is present:
- MUST immediately send at least two onion messages across at least two
different paths to the final HTLC recipient.
- Each onion message MUST contain a `held_htlc_available` TLV.
- Each onion message MUST contain a unique `reply_path`s which terminates
at the reciever of the `update_add_htlc` message.
- Each `reply_path` MUST contain a `release_held_htlc` TLV for the
`update_add_htlc` recipient in the `encrypted_data_tlvs` with a
`payment_release_secret` matching that in the `hold_htlc` TLV.

`id` MUST NOT be reset to 0 after the update is complete (i.e. after `revoke_and_ack` has
been received). It MUST continue incrementing instead.
Expand All @@ -1982,6 +2014,12 @@ A receiving node:
`error` and fail the channel.
- if `blinding_point` is provided:
- MUST use the corresponding blinded private key to decrypt the `onion_routing_packet` (see [Route Blinding](04-onion-routing.md#route-blinding))
- if the `hold_htlc` TLV is present:
- MUST NOT forward the HTLC until a corresponding `release_held_htlc` onion
message is received with a matching `payment_release_secret`.
- Upon receipt of a `release_held_htlc` onion message with a matching
`payment_release_secret` the HTLC SHOULD be treated as any HTLC without
the `hold_htlc` TLV and forwarded as usual.

The `onion_routing_packet` contains an obfuscated list of hops and instructions for each hop along the path.
It commits to the HTLC by setting the `payment_hash` as associated data, i.e. includes the `payment_hash` in the computation of HMACs.
Expand Down Expand Up @@ -2017,6 +2055,19 @@ maintaining its channel reserve (because of the increased weight of the
commitment transaction), resulting in a degraded channel. See [#728](https://github.com/lightningnetwork/lightning-rfc/issues/728)
for more details.

For often-offline recipients, e.g. mobile clients, nodes can use the
`hold_htlc` TLV to prevent further forwarding of an HTLC until the recipient
comes online. As long as the final recipients' counterparty is online and
storing onion messages for the recipient, the recipient can reply to the onion
message when they come online, unblock the HTLC, and expect to receive it
quickly thereafter.

Note that if the sender expects to be online when the recipient comes online,
they can utilize the `release_held_htlc` onion message without utilizing the
`hold_htlc` TLV - they can simply send a `held_htlc_available` onion message
to the final recipient and wait to send any HTLC at all until they receive a
`release_held_htlc` message back.

### Removing an HTLC: `update_fulfill_htlc`, `update_fail_htlc`, and `update_fail_malformed_htlc`

For simplicity, a node can only remove HTLCs added by the other node.
Expand Down
37 changes: 34 additions & 3 deletions 04-onion-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ This is formatted according to the Type-Length-Value format defined in [BOLT #1]

1. `tlv_stream`: `payload`
2. types:
1. type: 1 (`invoice_request`)
2. data:
* [`...*byte`:`invoice_request_tlv_stream`]
1. type: 2 (`amt_to_forward`)
2. data:
* [`tu64`:`amt_to_forward`]
Expand All @@ -213,6 +216,9 @@ This is formatted according to the Type-Length-Value format defined in [BOLT #1]
1. type: 18 (`total_amount_msat`)
2. data:
* [`tu64`:`total_msat`]
1. type: 5482373484 (`sender_provided_payment_preimage`)
2. data:
* [`32*byte`:`payment_preimage`]

`short_channel_id` is the ID of the outgoing channel used to route the
message; the receiving peer should operate the other end of this channel.
Expand All @@ -239,12 +245,18 @@ The requirements ensure consistency in responding to an unexpected
`outgoing_cltv_value`, whether it is the final node or not, to avoid
leaking its position in the route.

`sender_provided_payment_preimage` and `invoice_request` are set in the case
that the recipient is often-offline and another node provided a static BOLT 12
invoice on their behalf, where `invoice_request` is the sender's originl
invoice request corresponding to this HTLC.

### Requirements

The creator of `encrypted_recipient_data` (usually, the recipient of payment):

- MUST create `encrypted_data_tlv` for each node in the blinded route (including itself).
- MUST include `encrypted_data_tlv.short_channel_id` and `encrypted_data_tlv.payment_relay` for each non-final node.
- MUST include `encrypted_data_tlv.payment_relay` for each non-final node.
- MUST include exactly one of `encrypted_data_tlv.short_channel_id` or `encrypted_data_tlv.next_node_id` for each non-final node.
- MUST set `encrypted_data_tlv.payment_constraints` for each non-final node:
- `max_cltv_expiry` to the largest block height at which the route is allowed to be used, starting
from the final node and adding `encrypted_data_tlv.payment_relay.cltv_expiry_delta` at each hop.
Expand All @@ -268,6 +280,14 @@ The writer of the TLV `payload`:
- MUST use the current block height as a baseline value.
- if a [random offset](07-routing-gossip.md#recommendations-for-routing) was added to improve privacy:
- SHOULD add the offset to the baseline value.
- if paying to a static BOLT 12 invoice:
- MUST set `sender_provided_payment_preimage` to randomly generated unique bytes.
- MUST set `update_add_htlc.payment_hash` to match the SHA256 hash of
`sender_provided_payment_preimage`.
- MUST set `invoice_request` to the BOLT 12 invoice request
corresponding to this HTLC.
- otherwise:
- MUST NOT set `sender_provided_payment_preimage`.
- MUST NOT include any other tlv field.
- For every node outside of a blinded route:
- MUST include `amt_to_forward` and `outgoing_cltv_value`.
Expand Down Expand Up @@ -318,6 +338,7 @@ The reader:
- MUST return an error if `amt_to_forward` is below what it expects for the payment.
- MUST return an error if incoming `cltv_expiry` < `outgoing_cltv_value`.
- MUST return an error if incoming `cltv_expiry` < `current_block_height` + `min_final_cltv_expiry_delta`.
- MUST use `sender_provided_payment_preimage` when claiming the HTLC, if present
- Otherwise (it is not part of a blinded route):
- MUST return an error if `blinding_point` is set in the incoming `update_add_htlc` or `current_blinding_point` is present.
- MUST return an error if `amt_to_forward` or `outgoing_cltv_value` are not present.
Expand Down Expand Up @@ -1473,10 +1494,19 @@ even, of course!).
1. type: 4 (`encrypted_recipient_data`)
2. data:
* [`...*byte`:`encrypted_recipient_data`]
1. type: 64 (`invoice_request`)
2. data:
* [`tlv_invoice_request`:`invreq`]
1. type: 66 (`invoice`)
2. data:
* [`tlv_invoice`:`inv`]
1. type: 68 (`invoice_error`)
2. data:
* [`tlv_invoice_error`:`inverr`]

1. subtype: `blinded_path`
2. data:
* [`point`:`first_node_id`]
* [`sciddir_or_pubkey`:`first_node_id`]
* [`point`:`blinding`]
* [`byte`:`num_hops`]
* [`num_hops*onionmsg_hop`:`path`]
Expand Down Expand Up @@ -1533,7 +1563,8 @@ The reader:
- if the `encrypted_data_tlv` contains `path_id`:
- MUST ignore the message.
- otherwise:
- SHOULD forward the message using `onion_message` to the next peer indicated by `next_node_id`.
- SHOULD forward the message using `onion_message` to the next peer indicated by either `next_node_id`
or the channel counterparty with `short_channel_id`.
- if it forwards the message:
- MUST set `blinding` in the forwarded `onion_message` to the next blinding as calculated in [Route Blinding](#route-blinding).
- otherwise (it is the final node):
Expand Down
8 changes: 8 additions & 0 deletions 09-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The Context column decodes as follows:
* `C+`: presented in the `channel_announcement` message, but always even (required).
* `9`: presented in [BOLT 11](11-payment-encoding.md) invoices.
* `B`: presented in the `allowed_features` field of a blinded path.
* `R`: presented in [BOLT 12](12-offers.md) invoice requests.

| Bits | Name | Description | Context | Dependencies | Link |
|-------|-----------------------------------|-----------------------------------------------------------|----------|---------------------------|-----------------------------------------------------------------------|
Expand All @@ -50,11 +51,18 @@ The Context column decodes as follows:
| 46/47 | `option_scid_alias` | Supply channel aliases for routing | IN | | [BOLT #2][bolt02-channel-ready] |
| 48/49 | `option_payment_metadata` | Payment metadata in tlv record | 9 | | [BOLT #11](11-payment-encoding.md#tagged-fields) |
| 50/51 | `option_zeroconf` | Understands zeroconf channel types | IN | `option_scid_alias` | [BOLT #2][bolt02-channel-ready] |
| 52/53 | `option_htlc_hold` | Hold HTLCs and forward on receipt of an onion message | IN | `option_onion_messages` |
| 56/57 | `option_om_mailbox` | Store-and-forward onion messages for often-offline peers | IN | `option_onion_messages` | [BOLT #12](bolt12-offers.md) |
| 59 | `static_invoice_pay` | Supports paying BOLT 12 static invoices | R | `option_onion_messages` | [BOLT #12](bolt12-offers.md) |

## Definitions

We define `option_anchors` as `option_anchor_outputs || option_anchors_zero_fee_htlc_tx`.

We define `option_om_mailbox` as the ability to store an onion message on behalf
of an offline peer, and forward it once the peer comes online (subject to rate
limiting).

## Requirements

The origin node:
Expand Down
Loading