[c-lightning] Towards atomic multipath payments

ZmnSCPxj ZmnSCPxj at protonmail.com
Fri Nov 16 15:49:42 AEDT 2018


Good morning c-lightningers,

I would like to propose a JSON-RPC interface for low-level atomic multipath payments.

Currently exists, the `sendpay`/`waitsendpay`/`listpayments`.
`sendpay` and `waitsendpay` are low-level interfaces for making a single payment attempt.
`listpayments` indicates status of payments.

These interfaces manage a table of payment attempts.
`sendpay` will create one, or reuse a payment attempt if it is marked as failing.
`waitsendpay` waits for a specific payment attempt to change its status to either completed or failing.

This table of payment attempts is used also to provide the high-level `pay` interface.
The `pay` interface leaves the payment attempt on the table if it succeeds, and just reuses the same entry (from the lower-level `sendpay` behavior) to keep retrying.
Thus `listpayments` serves as both a high-level and low-level interface.

Currently those interfaces are keyed to the `payment_hash`.
Each payment attempt has a unique `payment_hash`.

For simplicity to JSON-RPC users, I want to keep the existing `sendpay`/`waitsendpay` interfaces as-is without adding special multipath options to them.
However, atomic multipath means making separate attempts simultaneously with the same `payment_hash`, and the `sendpay`/`waitsendpay` are keyed according to `payment_hash`.
Further, the `listpayments` table also serves as a high-level interface, and I think atomic multipath should be low-level and not be exposed on `listpayments`.

So I want to propose a separate interface:

`sendpartialpay` `route` `payment_hash` `intended_msatoshi` [`description`]
=>
{ "id" : 42, ... }

`waitpartialpay` `id`

`listpartialpayments` [`id`]

This handles a separate table for partial payments.
There is a many-to-one mapping from partial payments in `listpartialpayments` to payments in `listpayments`.

Then, `sendpartialpay` does:

1.  Check if there already exists a payment attempt with same `payment_hash` in `listpayments` table.
1.1.  If there is not, create it, with the `msatoshi` equal to the `intended_msatoshi` for this `sendpartialpay` call.
1.2.  Otherwise:
1.2.1.  If the `intended_msatoshi` does not match the `msatoshi` in the `listpayments` table, fail immediately and do nothing.
1.2.2.  If the existing `listpayments` entry is completed, return immediately with success and do nothing.
1.2.3.  If the existing `listpayments` entry is failed, change it to pending and continue.
2.  Create a payment attempt in `listpartialpayments` table, trigger the payment, and return the ID for the payment attempt.

When a partial payment returns either `update_fulfill_htlc` or `update_fail_htlc`:

1.  Change the state of the `listpartialpayments` entry to completed/failed.
2.  If completed, also set the `listpayments` entry to completed and trigger any `waitsendpay` waiters.
3.  If failed, and all other partial payments to the same `payment_hash` failed, set the `listpayments` entry to failed and trigger any `waitsendpay` waiters.
4.  Trigger any `waitpartialpay` waiters.

Regards,
ZmnSCPxj
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/c-lightning/attachments/20181116/52f9f956/attachment.html>


More information about the c-lightning mailing list