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

BOLT 4, 9, 11: Base Atomic Multipath Payments. #511

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .aspell.en.pws
Expand Up @@ -328,3 +328,6 @@ regtest
ratelimiting
zlib
ZLIB
atomicity
multipath
Multipath
93 changes: 92 additions & 1 deletion 04-onion-routing.md
Expand Up @@ -181,7 +181,8 @@ The `realm` byte determines the format of the `per_hop` field; currently, only `
* [`8`:`short_channel_id`]
* [`8`:`amt_to_forward`]
* [`4`:`outgoing_cltv_value`]
* [`12`:`padding`]
* [`1`:`flags0`]
* [`11`:`padding`]

Using the `per_hop` field, the origin node is able to precisely specify the path and
structure of the HTLCs forwarded at each hop. As the `per_hop` is protected
Expand Down Expand Up @@ -232,8 +233,21 @@ Field descriptions:
`outgoing_cltv_value`, whether it is the final node or not, to avoid
leaking its position in the route.

* `flags0`: A bitfield of various bit flags.
In keeping with "It's OK to be odd", odd-indexed bits (1, 3, 5, 7)
can be safely ignored by the receiver if set.
The receiver MUST fail the HTLC if an undefined even-indexed bit is set.

The bits of this field are defined as below:

* Bit 0: `incomplete_payment` atomic multipath payment.
Can only be set if the receiver is the final node (i.e. `HMAC` == 0).
See section "Base Atomic Multipath Payments".

* `padding`: This field is for future use and also for ensuring that future non-0-`realm`
`per_hop`s won't change the overall `hops_data` size.
The bytes of this field MUST be set to 0;
future uses may set some bytes to non-zero.

When forwarding HTLCs, nodes MUST construct the outgoing HTLC as specified within
`per_hop` above; otherwise, deviation from the specified HTLC parameters
Expand All @@ -257,6 +271,61 @@ compare its values against those of the HTLC. See the
If not for the above, since it need not forward payments, the final node could
simply discard its payload.

### Base Atomic Multipath Payments
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's drop this phrase altogether. "Partial Payments" is better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Atomic Multipath Payments is how the users know this feature, so I am hesitant to change it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which users now this as AMP? When the majority of those that are aware of LN, here "AMP", they think of the original ML post. The only individuals that know of this partial payment feature are those that were at the summit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I shall change it then.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ZKCP-preseerving proper multipath payments"


If the final node receives an onion packet with the `incomplete_payment` flag
set, then the payment MAY be a "base" atomic multipath payment.
Such "base" atomic multipath payments will use the same `payment_hash` for all paths.

The `amt_to_forward` value will be the amount for this partial payment only.
The `incomplete_payment` flag is a promise by the ultimate sender
that the rest of the payment will follow
in succeeding HTLCs.

#### Requirements

The payer:
- if `wait_on_incomplete` is not set in the invoice:
- MUST NOT set the `incomplete_payment` flag.
- otherwise:
- If they split the payment into multiple HTLCs:
- MUST use the same `payment_preimage` on all HTLCs.
- MUST set the `incomplete_payment` flag on all HTLC onions.
- MUST ensure that the total amount of all the HTLCs at the payee meets the `amount` requirement of the invoice.
- SHOULD send all payments at approximately the same time.
- SHOULD try to use diverse paths to the recipient for each HTLC.
- SHOULD retry and/or re-divide HTLCs which fail.
- MUST NOT allow the total value of active HTLCs to exceed the amount it is prepared to pay.

The payee:
- if an onion with `incomplete_payment` is set for an invoice which flagged `wait_on_incomplete`:
- MUST not immediately fail the HTLC if it is valid except for the amount being too small.
- SHOULD wait for at least 60 seconds for more partial payments for the same `payment_preimage`.
- MUST accept all partial payments once the total amount meets or exceeds the invoice `amount`.
- MUST reply with `incomplete_payment_too_slow` to all partial payments which it times out.

#### Rationale

If `incomplete_payment` is set, but the total expected value has not
arrived at the final node, and the final node claims the payment,
then the final node has effectively sold the `payment_preimage` at a
discount.

This is effectively "economically rational atomicity".
A final node that wants to lose money may voluntarily claim a partial
payment that is less than its advertised payment amount.
We assume that no final node would want to lose money.

Since invoices have lifetimes, it might seem
that a final node has incentive to grab a partial payment
before the invoice lifetime ends.
However, the fact still remains
that the `payment_preimage` has been released
for less than its market value,
meaning the final node still loses value in the transaction.
It would be better for the final node to simply not release the preimage
or offer to sell it to someone else who is willing to pay the full value.

# Shared Secret

The origin node establishes a shared secret with each hop along the route using
Expand Down Expand Up @@ -791,6 +860,17 @@ The channel from the processing node has been disabled.

The CLTV expiry in the HTLC is too far in the future.

1. type: PERM|22 (`invalid_flag`)

An even-numbered bit of `flags0` is set, which is not understood
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In keeping, with "It's OK to be odd" rule, which has the corollary "It's BAD to be even".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BADONION has a specific meaning here, which means "I can't even decode it, so you're getting a message from the prevoius node". This is weaker, so should not have that bit set.

by the hop, or is otherwise invalid for the node that decoded it.
This is in keeping with "It's OK to be odd" rule.

1. type: 23 (`incomplete_payment_too_slow`)

The final node has been waiting too long for an incomplete payment
to complete.

### Requirements

An _erring node_:
Expand All @@ -809,6 +889,8 @@ Any _erring node_ MAY:
- if a node has requirements advertised in its `node_announcement` `features`,
which were NOT included in the onion:
- return a `required_node_feature_missing` error.
- if an even bit of `flags0` is set:
- return an `invalid_flag` error.

A _forwarding node_ MAY, but a _final node_ MUST NOT:
- if the onion `version` byte is unknown:
Expand Down Expand Up @@ -875,6 +957,15 @@ An _intermediate hop_ MUST NOT, but the _final node_:
- if the `amt_to_forward` is greater than the `incoming_htlc_amt` from the
final node's HTLC:
- MUST return a `final_incorrect_htlc_amount` error.
- if the `incomplete_payment` flag is set:
- SHOULD NOT immediately fail the HTLC if the `amt_to_forward`
is less than the expected amount.
- SHOULD claim the HTLC if the total `amt_to_forward` on all
incoming HTLC with same `payment_hash` equals or exceeds the
payment amount.
- if the HTLC has been unclaimed for too long:
- MUST fail the HTLC.
- MUST return `incomplete_payment_too_slow` error.

## Receiving Failure Codes

Expand Down
9 changes: 9 additions & 0 deletions 09-features.md
Expand Up @@ -31,6 +31,15 @@ These flags may only be used in the `init` message:

There are currently no `globalfeatures` flags.

## Assigned `invoicefeatures` flags

These flags are used in the `9` field
of [BOLT #11](11-payment-encoding.md) invoices:

| Bits | Name |Description | Link |
|------|----------------------|------------------------------------------------|---------------------------------------------------------------------|
| 1 | `wait_on_incomplete` |Indicates that the payee allows the payment to be split into multiple paths.| [BOLT #4](04-onion-routing.md#base-atomic-multipath-payments)|

## Requirements

The requirements for receiving specific bits are defined in the linked sections in the table above.
Expand Down
5 changes: 4 additions & 1 deletion 11-payment-encoding.md
Expand Up @@ -134,6 +134,9 @@ Currently defined tagged fields are:
* `fee_base_msat` (32 bits, big-endian)
* `fee_proportional_millionths` (32 bits, big-endian)
* `cltv_expiry_delta` (16 bits, big-endian)
* `9` (5): `data_length` variable. One or more bytes containing features
supported for receiving this payment.
See [BOLT #9](09-features.md#assigned-invoicefeatures-flags).

### Requirements

Expand All @@ -152,7 +155,7 @@ A writer MAY include one `x` field.
A writer MAY include one `c` field, which MUST be set to the minimum `cltv_expiry` it
will accept for the last HTLC in the route.

A writer SHOULD use the minimum `data_length` possible for `x` and `c` fields.
A writer SHOULD use the minimum `data_length` possible for `x`, `c`, and `9` fields.

A writer MAY include one `n` field, which MUST be set to the public key
used to create the `signature`.
Expand Down