Skip to content
Merged
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
358 changes: 358 additions & 0 deletions 0003-lightning-as-alpha-ledger.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,358 @@
= LND as Alpha Ledger as described in RFC003
Philipp Hoenisch <philipp@tenx.tech>
:revdate: 2019-04-24

NOTE: Author: {authors} +
Date: {revdate} +
Tracking issue: TBA

Comment thread
bonomat marked this conversation as resolved.
:toc:

== Context

The **Hold invoice feature** was introduced in the following PR: https://github.com/lightningnetwork/lnd/pull/2022[lightningnetwork/lnd/pull/2022].
____
A hold invoice is a new type of invoice that triggers a different flow at the receiver's end.
Instead of immediately locking in and settling the htlc when the payment arrives, the htlc for a hold invoice is only locked in and not yet settled.
At that point, it is not possible anymore for the sender to revoke the payment, but the receiver still can choose whether to settle or cancel the htlc and invoice.
____

This allows us to trade Bitcoin on the Lightning Network (LN) for an asset _X_ on a different ledger where LN is the _alpha ledger_ as per the definition in https://github.com/comit-network/RFCs/blob/master/RFC-003-SWAP-Basic.md[RFC003].
For the other way around, Bitcoin on the Lightning Network is the _beta asset/ledger_, we can make use of `createinvoice` as Alice would instantly release the secret by settling Bob's LN payment, or we can follow the same approach as described below.

NOTE: Within this spike we only focus on LN as the Alpha Ledger using https://github.com/lightningnetwork/lnd/[LND].

== Research

=== Standard _hold invoice_ process

____
Assumption: Alice wants to pay Bob _X_ Bitcoin using the LN but Bob does not generate the preimage - Alice does it.
____

1) Alice generates a secret preimage `p` and sends the hash of it `h(p)` to Bob.
2) Bob calls `addholdinvoice` with an amount `X` and the hashed preimage `h(p)` (https://github.com/lightningnetwork/lnd/blob/aa1cd04dbf07a9195d5ada752f383988d8d01fa7/cmd/lncli/invoicesrpc_active.go#L142[more details]).
3) Bob sends the generated invoice to Alice.
Comment thread
bonomat marked this conversation as resolved.
4) Alice now can pay the invoice using `sendpayment`.
5) As soon as Alice is happy (because she is in a good mood), she tells Bob the secret (or he learns it otherwise, see below).
6) Bob settles the payment by calling `settleInvoice` (https://github.com/lightningnetwork/lnd/blob/aa1cd04dbf07a9195d5ada752f383988d8d01fa7/cmd/lncli/invoicesrpc_active.go#L53[more details]).

The payment is complete.

== Lightning Network as Alpha Ledger within the bounds of RFC003?

Below, we try if Lightning Network as Alpha Ledger _fits_ into the definition of RFC003:

____
Assumption: Bob wants to receive _X_ Bitcoin (**A** Asset) on the LN (**alpha** Ledger) for _Y_ Ether (**B** Asset) on Ethereum (**beta** Ledger)
Alice magically finds out about this _wish_ or using a COMIT link.

* Alpha Ledger: Lightning Network
* Alpha Asset: Bitcoin
* Beta Ledger: Ethereum
* Beta Asset: Ether
____

According to https://github.com/comit-network/RFCs/blob/master/RFC-003-SWAP-Basic.md[RFC003], Alice needs to send the following information to Bob for initiating a swap.
Comment thread
bonomat marked this conversation as resolved.

[cols=3*,options=header]
|===
| Name
| JSON Encoding
| Description

| `alpha_expiry`
| `u32`
| The UNIX timestamp of the time-lock on the alpha HTLC

| `beta_expiry`
| `u32`
| The UNIX timestamp of the time-lock on the beta HTLC

| `alpha_refund_identity`
| `α::Identity`
| The identity on α that A can be transferred to after `alpha_expiry`

| `beta_redeem_identity`
| `β::Identity`
| The identity on beta that **B** will be transferred to when the beta-HTLC is activated with the correct secret

| `secret_hash`
| `hex-encoded-bytes`
| The output of calling `hash_function` on the secret
|===

And Bob would respond with the following:

[cols=3*,options=header]
|===
| Name
| JSON Encoding
| Description

| `alpha_redeem_identity`
| `α::Identity`
| The identity on alpha that **A**, this is the LN `invoice`

| `beta_refund_identity`
| `β::Identity`
| The identity on beta that **B** will be transferred to when the beta-HTLC is activated after `beta_expiry`
|===


However, using LND, various complication need to be tackled:

* `alpha_expiry` -> Similar to other RFC003 implementations, for LND `alpha_expiry` will need to be set when sending the payment, i.e. by adding `--final_cltv_delta=T`.
The caveat here is that Alice can not set the actual `cltv_expiry` on the last hop but only the delta.
The LN node calculates what the `cltv_expiry` will be based on `final_cltv_delta` and what it perceives to be the current block height.
* `alpha_refund_identity` -> When using LN (or LND), one is not in direct control of the refund path. If a channel update expires, the refund path is handled automatically by the LN implementation.
* `alpha_redeem_identity` -> Similar to `alpha_refund_identity`, the `alpha_redeem_identity` on the actual HTLC cannot be directly configured as this is done by the LN implementation. However, this field is still required as it should specify the final reciepient, i.e. the final node.

Because of these limitations, we should introduce a new protocol for using LN as Alpha Ledger.


== Proposal: A new protocol for LN as Alpha Ledger

=== Step-by-step description

1. Alice generates a secret preimage `p` and sends a swap request to Bob, this includes (assets with amounts are emitted):

[cols=3*,options=header]
|===
| Name
| Proposed Value.footnote:[This will only be finalized in the RFCs later on.]
| Description

| `alpha_ledger`
| lightning-network-mainnet
| The ledger on which the Sender sells and the Receiver buys.

| `beta_ledger`
| e.g. Bitcoin
| The ledger on which the Sender buys and the Receiver sells.

| `alpha_asset`
| Bitcoin
| The asset that the Sender sells and the Receiver buys.

| `beta_asset`
| Bitcoin
| The asset that the Sender buys and the Receiver sells.

| `protocol`
| RFC00X
| The new protocol specifying LN Swaps

[cols=3*,options=header]
|===
| Name
| JSON Encoding
| Description

| `final_cltv_delta`
| `u32`
| The `final_cltv_delta` Alice will use when paying the invoice.

| `beta_expiry`
| `u32`
| The UNIX timestamp of the time-lock on the beta HTLC.

| `beta_redeem_identity`
| `β::Identity`
| The identity on beta that **B** will be transferred to when the beta-HTLC is activated with the correct secret

| `secret_hash`
| `hex-encoded-bytes`
| The output of calling `hash_function` on the secret

|===

[start=2]
2. Bob _accepts_ the request and performs the following step:
.. Create a hold invoice using `addholdinvoice` with the amount `X` and the hashed preimage `secret_hash` (https://github.com/lightningnetwork/lnd/blob/aa1cd04dbf07a9195d5ada752f383988d8d01fa7/cmd/lncli/invoicesrpc_active.go#L142[more details]).
.. Bob _subscribes_ to the invoice and waits for the payment either using
... `SubscribeSingleInvoice` - this is not available through the CLI but as RPC; or
... `LookupInvoice` - this is available trough the CLI but needs to be polled regularly.
3. Bob response to Alice's request with the following information:

[cols=3*,options=header]
|===
| Name
| JSON Encoding
| Description

| `receiving_node_identity`
| `α::Identity`
| The receiving node id which should be in the invoice paid by Alice.

| `beta_refund_identity`
| `β::Identity`
| The identity on beta that **B** will be transferred to when the beta-HTLC is activated after `beta_expiry`
|===

[start=4]
4. Alice now starts the https://github.com/comit-network/RFCs/blob/master/RFC-003-SWAP-Basic.md#1-alice-deploys-%CE%B1-htlc[execution phase] by first creating an invoice and then paying the invoice using the LND command `sendpayment`.
5. Bob gets notified about funding of alpha (i.e. the invoice has been paid but cannot be settled yet), and continues with https://github.com/comit-network/RFCs/blob/master/RFC-003-SWAP-Basic.md#2-bob-deploys-%CE%B2-htlc[deploying beta-HTLC], i.e. he deploys a HTLC on Ethereum.
6. As soon as beta has enough confirmations for Alice, she redeems the beta-HTLC using her secret.
7. Bob gets notified about this, learns the secret and can now settle the LND invoice by invoking the LND command `settleInvoice` (https://github.com/lightningnetwork/lnd/blob/aa1cd04dbf07a9195d5ada752f383988d8d01fa7/cmd/lncli/invoicesrpc_active.go#L53[more details]).

The trade is complete.

== Spike Outcome

=== Lightning Network: a new ledger
Similar to the ledger definitions for https://github.com/comit-network/RFCs/blob/master/RFC-004-Bitcoin.md[Bitcoin] and https://github.com/comit-network/RFCs/blob/master/RFC-006-Ethereum.md[Ethereum] we need to handle the Lightning Network differently.
This is required because the comit-node and btsieve need to perform different actions accordingly.
We are always talking about Ledgers and Assets, (e.g. _Bitcoin_ Asset on the _Bitcoin_ Ledger, _Ether_ Asset on the _Ethereum_ Ledger, _Erc20_ on the _Ethereum_ Ledger, ...), Hence,
if we follow this approach, for supporting LN (through LND) we will need to introduce a new pair of Ledger and Asset:

* Ledger: the **Lightning Network**. _Ledgers_ are used as _settlement layers_ for our HTLCs. In the case of LND, this layer is the Lightning Network.
Comment thread
bonomat marked this conversation as resolved.
* Asset: **Bitcoin**. Since LN is a layer-2 network on top of Bitcoin, the asset should also be Bitcoin.

=== Dealing with timeouts
As mentioned above, Alice specifies `final_cltv_delta` when paying the invoice. Bob's node must be configured in a way that it will not automatically reject this value.
Additionally, timeouts on the HTLCs in LN are absolute values expressed in https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#cltv_expiry_delta-selection[block height].


=== Responsibilities

A main goal of COMIT is to keep the autonomy to the user and let him/her decide when to deploy a HTLC, redeem or refund a HTLC, etc.
If a trade involves LN using LND we can approach these things differently:


* Action
** Create hold invoice
* Responsibility
** LND
* Invoker
** User through comit-i (or another user-facing tool)
* Description
** `addholdinvoice` is available as a RPC command or through the LND CLI. Although dealing with this is rather cumbersome, to keep the autonomy with the user, and to not introduce LND dependency into the comit-node, we this should be possible through comit-i.
* Conclusion:
** comit-i needs LND support. However, in order to do this, we will need to introduce a new action which is meant to be executed prior accepting a swap request:
Comment thread
bonomat marked this conversation as resolved.
*** Bob receives a swap request from Alice (an learns about the hashed secret)
*** *Action 1:* Bob creates a hold invoice through comit-i
*** *Action 2:* Bob accepts the swap requests by posting the newly generated invoice ID back to comit-rs
A quick research showed that LN payments can be done with the browser extension: https://lightningjoule.com/[Joule] and requests to a LND node can be done through the browser.

---


* Action
** Pay invoice
* Responsibility:
** LND or LN Wallet
* Invoker
** User through comit-i
* Description
** To keep the autonomy to the user when to initiate a trade, we should return the invoice information through our API to the user (e.g. expose it through comit-i ) and let him/her pay the invoice.
* Conclusion
** comit-i needs LND support.


---


* Action:
** Settle Invoice
* Responsibility
** LND or LN Wallet
* Invoker
** User through comit-i (or another tool)
* Description
** As soon as the secret has been learned, the HTLC on the LN should be settled using the command `settleinvoice`, this can either be done by the user (and exposed through comit-i) or done automatically through the comit-node. Since we have the extra _redeem_ step for Bitcoin and Ethereum (as well for Erc20) which needs to be performed by the user, we should leave the settlement of the invoice to the user (e.g. expose this information through comit-i).
* Conclusion
** comit-i needs LND support.


---


* Action
** Monitor LN
* Responsibility
** LND
* Invoker
** comit-rs
* Description
** Similar to other Ledgers we need to monitor LN for the payment (and later on settlement) of an invoice. To keep our current abstraction layer, this should be done through btsieve
Comment thread
bonomat marked this conversation as resolved.
* Conclusion
** btsieve needs LND support.


=== Fall-back mechanism of LN
LN allows to specify a fallback address (_fallback_addr_) in when creating calling `addholdinvoice`.
We could use this information to fall back to an on-chain HTLC trade if no route can be found between Alice and Bob.
Comment thread
bonomat marked this conversation as resolved.
Note: this should be handled with care, as someone could trick a LN node into using the fallback address automatically and issuing an on-chain transaction which does not involve a htlc.


== Appendix

=== Commands for call

The following works:

[source]
----
secret=0000000000000000000000000000000000000000000000000000000000000001
sha256=ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5
----

[source]
----
$bob: lncli --network=simnet addholdinvoice ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5 --amt 10
----



[source]
----
$alice: lncli --network=simnet payinvoice lnsb100n....
----

[source]
----
$bob: `lncli --network=simnet lookupinvoice 4146873...
{
"memo": "",
"receipt": null,
"r_preimage": null,
...
"amt_paid_msat": "10000",
"state": "ACCEPTED"
}
----

[source]
----
$bob: lncli --network=simnet settleinvoice 0000000000000000000000000000000000000000000000000000000000000001
----

[source]
----
$bob: `lncli --network=simnet lookupinvoice ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5
{
"memo": "",
"receipt": null,
"r_preimage": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE=",
"r_hash": "7EkW3Sj8TBDXjih8pdnMUe4a5zy/3gjGs3Mky/qsi8U=",
"value": "10",
"settled": true,
"creation_date": "1556272625",
"settle_date": "1556272661",
"payment_request": "lnsb100n1pwv9403pp5a3y3dhfgl3xpp4uw9p72tkwv28hp4eeuhl0q334nwvjvh74v30zsdqqcqzpgjemg8uy8y7ej0q6lmxvkfhwfrjnesv6jryk46m5kcfcd2drykskq97c2ad9lvp9d6mmyt0r6rhp26e2cmrqd9qgc88rf5l58hz6ntxgqc3azkn",
"description_hash": null,
"expiry": "3600",
"fallback_addr": "",
"cltv_expiry": "40",
"route_hints": [
],
"private": false,
"add_index": "7",
"settle_index": "1",
"amt_paid": "10000",
"amt_paid_sat": "10",
"amt_paid_msat": "10000",
"state": "SETTLED"
}
----
1 change: 1 addition & 0 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
= COMIT research outcomes
1 change: 0 additions & 1 deletion README.md

This file was deleted.

3 changes: 3 additions & 0 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ List of spike outcomes for COMIT network.

[spike-0000](0000-use-madr-like-solution-for-spike-outcomes.md) - Use MADR-like solution for spike outcomes - coblox/docs#36
[spike-0001](0001-basic-expiry-model.md) - Propose basic model to calculate expiry times - comit-network/RFCs#14
[spike-0002](0002-ether-htlc-dynamic-final-addresses.md) - Ether HTLC with dynamic final addresses
[spike-0003](0003-hodl-invoice.md) - Allow trading assets against Bitcoin on the Lightning Network.


For new spike outcomes, please use [template.md](template.md) as basis.
17 changes: 17 additions & 0 deletions template.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
= [short title describing spike]
Satoshi Nakamoto <satoshi.nakamoto@coblox.tech>;
:revdate: 2009-01-03

NOTE: Author: {authors} +
Date: {revdate} +
Tracking issue: TBA

:toc:

== Context

[Short description of the context]

== Research

[Documentation of steps followed and findings]
Loading