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

Implementing the LN-DLC node #34

Closed
7 of 10 tasks
bonomat opened this issue Jan 23, 2023 · 13 comments
Closed
7 of 10 tasks

Implementing the LN-DLC node #34

bonomat opened this issue Jan 23, 2023 · 13 comments

Comments

@bonomat
Copy link
Contributor

bonomat commented Jan 23, 2023

This epic assumes that we have chosen to follow the approach outlined in this blog post to build a node that supports Lightning and DLC channels side-by-side.

This decision to use this protocol will be documented in:

The early development of this node will be carried out in a separate ln-dlc-node crate within this workspace, but ultimately the goal is to use the node as a long running process within the coordinator and mobile app binaries.

Notes on rust-dlc + rust-lightning

Forks

For the moment we focus on working on our own forks to speed up development, but eventually we are aiming to use a stable release of rust-dlc and even rust-lightning.

  1. rust-dlc: https://github.com/get10101/rust-dlc/tree/feature/split-tx-manager-2

  2. rust-lightning: https://github.com/get10101/rust-lightning/tree/split-tx-experiment

    • Changes are minimal but Tibo said that he would do it differently with more time.
    • It might be possible to rebase onto latest main if we need new features.

Observations

  1. DLC channel does not yet support multiple outputs

    1. Multiple DLCs

      Not needed until StableSats or multiple contract symbols.

    2. DLC + regular output

      Needed to be able to open and close positions without affecting Lightning channel. This may affect ergonomics, because we don't know how long it takes to remake the split transaction and how smoothly it works.

      Theoretically it's not necessary though.

  2. rust-dlc doesn't support Olivia

    1. Different attestation scheme

      Olivia uses a simpler, bespoke attestation scheme, whereas rust-dlc conforms to dlcspecs.

    2. Different API

      • Olivia uses bespoke messages, whereas rust-dlc conforms to dlcspecs.
      • We might be able to overcome this by transforming the responses from Olivia.

General

Tasks to prepare the codebase for the introduction of the ln-dlc-node crate:

Features

Receive and send payments via Lightning (must)

This should be a given if we use rust-lightning and we don't mess with the commitment_transaction. In the 10101 PoC we did mess with the commitment_transaction and we broke it when the DLC was present.

Deposit into Lightning wallet using Lightning (must)

This is effectively the same as receiving a payment without having a channel with the coordinator beforehand.

  1. Options

    We figured out that routing the payment all the way to the coordinator first was best and also feasible. We list the other option in case we missed something and we end up needing a backup plan.

    1. Route payment all the way to the coordinator first

      1. Flow

        1. User tries to create invoice.
        2. App generates an invoice to the coordinator with a payment preimage that only the app knows.
        3. App shares payment hash with coordinator.
        4. Payer pays the invoice, which eventually reaches the coordinator as a HTLC.
        5. Coordinator matches the received HTLC to the one registered by the app.
        6. Coordinator opens channel with user, including HTLC with amount minus flat routing fee and liquidity-based routing fee.
        7. App claims payment.
    2. Open channel between coordinator and user first

      1. Flow

        1. User tries to create invoice.
        2. Coordinator opens channel with user with desired invoice amount as inbound liquidity for user (plus whatever inbound liquidity they would want).
        3. Invoice then generated, including route hint for final hop between coordinator and user.
      2. Drawbacks

        • Coordinator is at risk of opening the channel for no reason.
        • Slower process than the usual speedy generation of an invoice.

Receive and send on-chain (must)

In 10101-poc we achieved this by involving bdk via a fork of the bdk-ldk crate. Soon after we started using that code, the maintainer noted that the project was no longer maintained and suggested ldk-node as an alternative.

Transfer between DLC channel and Lightning wallet (must)

  • Is the split_transaction always present even if only one of the channels is active?
  • This is achieved by reconstructing split_transaction and children.
  • Tibo said this is possible and doesn't immediately break the Lightning channel.

Send on-chain from the Lightning wallet (could)

Using submarine swaps. We may not need to implement this service ourselves.

Create a CFD based on a price event from an oracle (must)

Use the APIs already provided by rust-dlc.

  1. Oracle options

    1. Use Olivia

      Will require code changes:

      • Custom implementation of rust_dlc::Oracle trait.
      • Modify rust-dlc to support Olivia's attestation scheme.
    2. Use a p2pderivatives oracle instance hosted by us.

    3. Use a dlcspecs-compliant oracle, such as the ones listed by Suredbits.

Create multiple CFDs at once (could)

This might only be needed when we support multiple contract symbols.

Punish publication of revoked DLC channel buffer transaction (should)

  • We already left this till much later in ItchySats, hence the should label.
  • One downside of Tibo's approach is that we have to handle revocation of the DLC channel separate from the Lightning channel.

Settling a DLC (must)

  1. Non-collaboratively (must)

    • This doesn't close the Lightning channel! Only the DLC channel. Theoretically, the vanilla Lightning channel could once again be "upgraded" to one where there is a sibling DLC channel, but the overall pool of funds would be smaller.
    • buffer_transaction, CETs and refund_transaction must work, but this is already done by rust-dlc.
    • split_transaction is the experimental component introduced by Tibo's recent rust-dlc branch. We should verify that it is properly tested and add tests if necessary.
  2. Collaboratively (must)

    1. Options

      1. DLC into DLC channel "party" outputs

        • These are spendable after the buffer_transaction's revocation timeout.
        • rust-dlc does not yet support "party" outputs. We would need to extend the library for that.
      2. DLC into Lightning channel "party" outputs

        • Remove the DLC channel output from the split_transaction, moving the coins to the Lightning channel.
        • Essentially this automatically moves funds from the trading wallet to the Lightning wallet when the DLC is settled.
        • Could be needlessly expensive in terms of cryptographic work and communication between coordinator and app, as the split_transaction would need to change, affecting all the other Lightning-related transactions.
@holzeis
Copy link
Contributor

holzeis commented Jan 24, 2023

remove DLC: it should be possible to remove the DLC and settle into the DLC channel

what do you mean by "settle into the DLC channel"?

update DLC: it should be possible to extend the DLC in size or reduce in size

Is that possible without closing and reopening the DLC? This could be very handy in case parts of the position will get closed.

@holzeis
Copy link
Contributor

holzeis commented Jan 24, 2023

Should we add "create lightning channel on an incoming payment"? Its related to the open a lightning channel, but a bit more complex imho.

@luckysori
Copy link
Contributor

luckysori commented Jan 25, 2023

what do you mean by "settle into the DLC channel"?

It might help to compare this feature with what was possible in ItchySats.

In ItchySats we could: rollover, by rebuilding the commit transaction and subsequent transactions (off-chain); settle collaboratively, by publishing a new transaction spending from the fund transaction (on-chain); settle non-collaboratively, by publishing a previously signed commitment transaction and a CET or refund transaction later (on-chain).

In 10101 we want to be able to collaboratively settle without going on-chain. This necessitates the introduction of a DLC channel where you can have outputs other than DLCs. In practice, I think it's as simple as expanding the commitment transaction to support both DLCs and outputs that pay directly to either party. Interestingly, those outputs also need to be timelocked since commitment transactions can be revoked.

But rust-dlc doesn't support this currently. Their buffer_transaction (what we've been calling commitment transaction) assumes a single output that holds all the collateral i.e. the DLC. So we will need to implement this.

@luckysori
Copy link
Contributor

update DLC: it should be possible to extend the DLC in size or reduce in size

Is that possible without closing and reopening the DLC? This could be very handy in case parts of the position will get closed.

With the DLC channel I described above, we can increase and reduce the size of the DLC without going on-chain. It's like rolling over, but a bit more versatile. But in that case, if you're looking to increase the size of the DLC, you are limited to the funds pre-allocated to the DLC channel's buffer transaction.

If you want to have access to more funds, then you need to consider moving funds using the split transaction. That's a bit more involved as it affects the Lightning channel too, but it's off-chain.

And beyond that, you can consider splicing into the split transaction, but that's an on-chain procedure.

@luckysori luckysori changed the title Implement DLC-channel Sibling DLC and Lightning channels Jan 25, 2023
@luckysori luckysori self-assigned this Jan 26, 2023
@luckysori
Copy link
Contributor

luckysori commented Jan 27, 2023

I've modified the issue description to take into account recent discussions. Particularly the ones pertaining to the scope of the MVP. Each entry in the features section corresponds to a feature that we expect to see in 10101 that is related to the LN-DLC node. They're labelled with "could", "should" or "must" to indicate their importance.

Here's Philipp's original description for this issue. There is nothing wrong with it and there might still be useful information here, but I wanted to rework it based on the MVP scope discussions.

This is an epic-styled issue covering the implementation of a DLC-channel protocol based on cryptogarage's dlc-channels.

Below is a (incomplete) list of features we want to have. Note: we don't have to implement all of them from the get-go.

  • open a lightning channel: it should be possible to open a lightning channel which can send and receive payments
  • open DLC channel: it should be possible to open a DLC channel from either side of the channel
  • close DLC channel: it should be possible to close the DLC channel from either side of the channel
    • collaborative close: both parties collaborate on closing the DLC channel. The channel is closed into the lightning channel
    • force-close: the channel is closed on-chain and the transactions are being spent accordingly
  • update DLC channel: it should be possible to move funds from the lightning channel to the dlc channel and vice versa
  • add DLC (CFD): it should be possible to add a DLC (e.g. a CFD) to the DLC channel from either side of the channel
  • remove DLC: it should be possible to remove the DLC and settle into the DLC channel
  • update DLC: it should be possible to extend the DLC in size or reduce in size

The outcome of this should be two-fold

@luckysori luckysori changed the title Sibling DLC and Lightning channels Sibling DLC-Lightning channels Jan 27, 2023
@luckysori luckysori added the epic label Jan 29, 2023
luckysori added a commit that referenced this issue Jan 30, 2023
@Tibo-lg
Copy link

Tibo-lg commented Jan 31, 2023

Hi all, was notified of this by Philipp, excited that you’re considering using rust-dlc! Just some comments:

• Changes are minimal but Tibo said that he would do it differently with more time.

It’s not really a question of time. I’d incorporate more code within rust-lightning if I knew that they’d merge it. The main reason to keep things minimal is to make rebasing easier. What I’d mainly do is move the channel splitting logic there to avoid the awkward API to update the fund tx output.

◦ It might be possible to rebase onto latest main if we need new features.

I just rebased the branch on 0.113 I hope it didn’t break things for you, I didn’t realized you were already working on that!

ii. DLC + regular output
Needed to be able to open and close positions without affecting Lightning channel. This may affect ergonomics, because we don't know how long it takes to remake the split transaction and how smoothly it works.

Not sure what you’re referring to here?

• Tibo said this is possible and doesn't immediately break the Lightning channel.

At the moment the way to do it is to close the DLC channel and reopen it with a different amount. I think it’s possible to directly reconstruct a new split transaction (without having an intermediary commitment transaction) but it’s not currently implemented.

i Use a dlcspecs-compliant oracle, such as the ones listed by Suredbits.

If you go with this option there is code somewhere for interacting with Surebits oracle, I can dig it out.

• One downside of Tibo's approach is that we have to handle revocation of the DLC channel separate from the Lightning channel.

I guess even if you use the extra output on commitment tx you’d still have to keep track of DLC related revocation. The extra thing you need to track here is the split transaction.

• This doesn't close the Lightning channel! Only the DLC channel. Theoretically, the vanilla Lightning channel could once again be "upgraded" to one where there is a sibling DLC channel, but the overall pool of funds would be smaller.

There is no api for that at the moment, but I think it should be feasible.

• rust-dlc does not yet support "party" outputs. We would need to extend the library for that.

But rust-dlc doesn't support this currently. Their buffer_transaction (what we've been calling commitment transaction) assumes a single output that holds all the collateral i.e. the DLC. So we will need to implement this.

What do you call “party” outputs? At the moment there is support for settling the DLC off chain, keeping the DLC channel open so that you can make a new one within the same channel. Instead of a buffer tx it uses a settle tx which is also revokable.

Also I'm in the process of cleaning up the code. I'm considering moving the sub-channel thing into the DLC manager as at the end it doesn't feel really useful to have them separate, but let me know if you have an opinion on that.
I also assume that if you end up using rust-dlc you might want to avoid (too) breaking changes at some point, but just so you know there are still changes that will happen on the oracle messaging to match with the updated specs, and the segmentation of messages might also change.

@Tibo-lg
Copy link

Tibo-lg commented Jan 31, 2023

Regarding testing what is really missing at the moment are tests with 3 or 4 nodes, trying to make payment at the same time/ in the middle of the channel splitting process. I think some issues will probably appear.
I setup some issues regarding DLC/LN things, if I think of some other things I'll use the same tag.
p2pderivatives/rust-dlc#94
p2pderivatives/rust-dlc#93

@luckysori luckysori changed the title Sibling DLC-Lightning channels Implementing the LN-DLC node Jan 31, 2023
@luckysori
Copy link
Contributor

Hey, @Tibo-lg! Thanks for having a look at what we are doing ;D

• Changes are minimal but Tibo said that he would do it differently with more time.

It’s not really a question of time. I’d incorporate more code within rust-lightning if I knew that they’d merge it. The main reason to keep things minimal is to make rebasing easier. What I’d mainly do is move the channel splitting logic there to avoid the awkward API to update the fund tx output.

Optimising for ease of rebasing makes a lot of sense since it's hard to anticipate if/when the changes will be upstreamed.

◦ It might be possible to rebase onto latest main if we need new features.

I just rebased the branch on 0.113 I hope it didn’t break things for you, I didn’t realized you were already working on that!

Good to know! At this stage we've opted for forking these two repos including your branches in case we need to make quick changes, but I do expect us to stay in sync with any changes you introduce as soon as possible.

I did have to make some very minor changes to both rust-lightning and rust-dlc to make it build locally for me, in case you're curious: https://github.com/get10101/rust-dlc/commits/feature/split-tx-manager-2 and https://github.com/get10101/rust-lightning/commits/split-tx-experiment.

ii. DLC + regular output
Needed to be able to open and close positions without affecting Lightning channel. This may affect ergonomics, because we don't know how long it takes to remake the split transaction and how smoothly it works.

Not sure what you’re referring to here?

Yeah, sorry, this is not very clear. I ties in with another part of your message so I'll respond to it all together.

But rust-dlc doesn't support this currently. Their buffer_transaction (what we've been calling commitment transaction) assumes a single output that holds all the collateral i.e. the DLC. So we will need to implement this.

What do you call “party” outputs? At the moment there is support for settling the DLC off chain, keeping the DLC channel open so that you can make a new one within the same channel. Instead of a buffer tx it uses a settle tx which is also revokable.

What I was expecting or wanting from the buffer transaction was support for (1) DLC(s) and (2) outputs that pay directly to one of the two parties (the "party" outputs). The purpose of this would be to increase and reduce the value of a DLC without having to redirect the funds to the Lightning side of the split transaction, because I don't want to recompute signatures for that side of things if I can help it.

What I'm hearing from you is that you can instead replace the entire DLC in the buffer transaction with a new type of transaction which only holds the settlement outputs. That's cool and I completely overlooked the fact that you can actually revoke and replace that settle transaction with a new buffer transaction.

It is slightly different than what I had in mind, but what I had in mind might not even be necessary for our use case at the moment.

• Tibo said this is possible and doesn't immediately break the Lightning channel.

At the moment the way to do it is to close the DLC channel and reopen it with a different amount. I think it’s possible to directly reconstruct a new split transaction (without having an intermediary commitment transaction) but it’s not currently implemented.

What actually happens when you close the DLC channel? My guesses would be either:

  • the split transaction only has one output, so all the funds are diverted to Lightning so the glue and commitment transactions must be reconstructed; or
  • the split transaction is just eliminated (together with the glue transaction). The Lightning channel points to the fund transaction now and the funding TXO is the one with all the funds in the funding transaction.

It would certainly be more convenient if we could just remake the split transaction with different amounts and recompute the children based on that. But it shouldn't be a deal breaker at this stage.

i Use a dlcspecs-compliant oracle, such as the ones listed by Suredbits.

If you go with this option there is code somewhere for interacting with Surebits oracle, I can dig it out.

That would be very helpful. I reckon rolling with Suredbits is best for us atm.

• One downside of Tibo's approach is that we have to handle revocation of the DLC channel separate from the Lightning channel.

I guess even if you use the extra output on commitment tx you’d still have to keep track of DLC related revocation. The extra thing you need to track here is the split transaction.

My understanding was that by embedding the DLC directly into the commitment transaction, any update to the channel, be it payments-related or DLC-related, would just result in a new commitment transaction, so revocation of old DLCs would come for free.

I suppose it depends how the DLC is embedded. If you embed the DLC directly as an output that reuses the revocation key of the current commitment transaction, I think it would work. If you embed an output that is spent by a buffer transaction containing the DLC, then you do have to introduce your own revocation scheme independent of Lightning.

• This doesn't close the Lightning channel! Only the DLC channel. Theoretically, the vanilla Lightning channel could once again be "upgraded" to one where there is a sibling DLC channel, but the overall pool of funds would be smaller.

There is no api for that at the moment, but I think it should be feasible.

I see. So at the moment you can't go back from a published split transaction. That's only a little bit limiting, because I think the ideal mode of operation very rarely leads to this happening anyway. I suppose in theory you should be able to reinterpret the published split transaction as a funding transaction, and then you could start over.

Also I'm in the process of cleaning up the code. I'm considering moving the sub-channel thing into the DLC manager as at the end it doesn't feel really useful to have them separate, but let me know if you have an opinion on that. I also assume that if you end up using rust-dlc you might want to avoid (too) breaking changes at some point, but just so you know there are still changes that will happen on the oracle messaging to match with the updated specs, and the segmentation of messages might also change.

Thanks for the heads-up! At this stage we do expect breaking changes because we know we are depending on a feature branch haha.

It's a bit early for us to have formed an opinion on these APIs, but we're gonna start to use them over the next few days, so we'll let you know. For what it's worth, it was a bit surprising to find a dedicated SubChannelManager, as I would have expected it to be part of the DlcManager.

@luckysori
Copy link
Contributor

Regarding testing what is really missing at the moment are tests with 3 or 4 nodes, trying to make payment at the same time/ in the middle of the channel splitting process. I think some issues will probably appear. I setup some issues regarding DLC/LN things, if I think of some other things I'll use the same tag. p2pderivatives/rust-dlc#94 p2pderivatives/rust-dlc#93

This reminds me that the testing that we are intending to do in this repository might be a bit redundant in the long run and we may just want to help you write some of these (if they don't exist already) in rust-dlc.

The overall purpose of writing these tests here at the moment is to familiarise ourselves with the APIs and attempt to figure out if there is a common interface involving rust-dlc, rust-lightning and bdk to cater to the two systems that we have in mind for 10101: coordinator and mobile app.

@Tibo-lg
Copy link

Tibo-lg commented Jan 31, 2023

I did have to make some very minor changes to both rust-lightning and rust-dlc to make it build locally for me, in case you're curious

Yeah looks like the update to 0.0.113 did break things sorry! Also if you have some Clippy rules that you require as long as they’re not too annoying I’m ok with applying them in the root repo.

 The purpose of this would be to increase and reduce the value of a DLC without having to redirect the funds to the Lightning side of the split transaction, because I don't want to recompute signatures for that side of things if I can help it.

Ok I see what you mean, and I think it’s definitely doable, but I’m a bit unsure what you gain from it rather than just adjusting the output amounts of the DLC? I guess the user can access the funds a bit more quickly in case of unilateral close, but is there anything else?

What actually happens when you close the DLC channel?

The second. Indeed it’d be better to renew the split tx, I’ll let you know when I end up implemented it (or let me know if you want to have a go at it).

That would be very helpful. I reckon rolling with Suredbits is best for us atm.

Just realized it’s actually part of the ln/dlc branch. It’s this commit.

My understanding was that by embedding the DLC directly into the commitment transaction, any update to the channel, be it payments-related or DLC-related, would just result in a new commitment transaction, so revocation of old DLCs would come for free.

You’re right hadn’t considered that you could just revoke the commit tx.

I suppose in theory you should be able to reinterpret the published split transaction as a funding transaction, and then you could start over.

Yeah tbh it’s quite a small change to enable this, there is internally two separate calls being made to close the DLC channel and the LN channel, so you’d just need to split them at the API level.

This reminds me that the testing that we are intending to do in this repository might be a bit redundant in the long run and we may just want to help you write some of these (if they don't exist already) in rust-dlc.

The overall purpose of writing these tests here at the moment is to familiarise ourselves with the APIs and attempt to figure out if there is a common interface involving rust-dlc, rust-lightning and bdk to cater to the two systems that we have in mind for 10101: coordinator and mobile app.

It’d definitely be helpful if you add more test and push them back to the rust-dlc repo! I’ve also looked at bdk recently but couldn’t find a very good way of integrating it (haven’t spent that much time), so would be glad to see what you figure out!

luckysori added a commit that referenced this issue Jan 31, 2023
luckysori added a commit that referenced this issue Jan 31, 2023
luckysori added a commit that referenced this issue Jan 31, 2023
luckysori added a commit that referenced this issue Jan 31, 2023
@Tibo-lg
Copy link

Tibo-lg commented Jan 31, 2023

For what it's worth, it was a bit surprising to find a dedicated SubChannelManager, as I would have expected it to be part of the DlcManager.

Once I fix the issue with using 0.0.113 I'll refactor things and put everything under the DlcManager. I don't recall exactly why I wanted to separate things originally but I also feel like it was not a good choice.

@luckysori luckysori removed their assignment Jun 14, 2023
@github-actions
Copy link

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the Stale label Jul 17, 2023
@luckysori
Copy link
Contributor

I guess we did it! (The missing tasks are not priorities right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants