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

Splice draft (feature 62/63) #863

Closed
wants to merge 32 commits into from

Conversation

rustyrussell
Copy link
Collaborator

@rustyrussell rustyrussell commented Apr 20, 2021

Based on #862 #869:

We use the interactive tx construction protocol to make a splice:

  1. Initiator pays for input and output, sets fees.
  2. You can do more than one but you have to increase feerate by >= 25% each time
  3. We use quiescence to pause the channel in a known state while negotiating.
  4. A simple channel_update tells people not to notice the channel close, since we're splicing.

@rustyrussell
Copy link
Collaborator Author

OK, many tweaks to wording, but in particular:

  • No more minimum_depth; after 6 we ack the splice. That fits well with gossip, since we only have 10 blocks before old one will be forgotten.
  • No reserve requirements if you don't pull funds out of channel.

@rustyrussell
Copy link
Collaborator Author

OK, I reworked this on top of quiescence, and dropped the deterministic points which I am no longer convinced by.

@Kixunil
Copy link

Kixunil commented Jun 7, 2021

I don't see a way to merge two existing channels into one. Is it being considered?

@t-bast
Copy link
Collaborator

t-bast commented Jun 7, 2021

I don't see a way to merge two existing channels into one. Is it being considered?

AFAIK there's no "magic" trick but you can easily merge multiple channels. If you have N channels, just do a mutual close on N-1 of these channels and use the resulting utxos to splice into your last remaining channel. It does have an on-chain cost but there's no way around it (and once it's done, you have a single channel and you're good to go forever).

@Kixunil
Copy link

Kixunil commented Jun 7, 2021

Would be really nice being able to do it in a single transaction. It also wouldn't need confirmation because cheating is impossible in that case.

@t-bast
Copy link
Collaborator

t-bast commented Jun 8, 2021

It won't be possible in a single transaction, every existing channel needs one transaction to close and they're completely independent of each other.

02-peer-protocol.md Outdated Show resolved Hide resolved
@t-bast
Copy link
Collaborator

t-bast commented Feb 27, 2024

Came up in the spec meeting: Should we be adding a channel_type upgrade path to the splice?

This is somewhat orthogonal to splicing: channel_type upgrades can indeed leverage splicing, and it would be a very welcome addition, but it may conflict with other mechanisms for upgrading channel parameters. It would be nice to have one consistent mechanism for those upgrades instead of a mess of various upgrade paths.

But on the other hand, it makes splice consistent with open_channel, which makes a lot of sense, and would be very useful...I think I'm leaning towards adding the channel_type to splice, and leaving the upgrade of other parameters to a different protocol (for now, but that protocol could decide to build on top of splicing).

@ProofOfKeags
Copy link
Contributor

There are some key design considerations when it comes to changing the channel_type as part of the splicing process. At first glance it makes a lot of sense, but it does cause some thorny issues if you consider it in context with all of the other stuff going on in LN today.

The Dynamic Commitments proposal's main goal is to upgrade the channel_type parameter, specifically from pre-taproot channels to taproot channels. Like splicing, successfully doing this requires reanchoring the funding output.

The trouble is that if we were to just negotiate a taproot upgrade and then immediately broadcast the transaction that converts the funding output to the new segwit v1 output, we run into the problem wherein the new funding output is incompatible with our current gossip system. We are choosing to sidestep this by making it such that the output conversion transaction (referred to in the proposal as the "kickoff transaction") is not immediately broadcast. Like with splicing we can continue to use the channel when the kickoff hasn't confirmed yet, which in the extreme case doesn't have to confirm until the channel is closed!

Splices can't do this because of the case where a splice-in's have other transaction inputs which may be double-spent to invalidate the splice transaction. (Note that if you are only splicing out, this is not the case!)

Dynamic commitment channel_type conversions can get away with this because there are no actions that can be taken that would invalidate them, making the signed but unconfirmed kickoff as secure as the commitment transactions themselves.

If you want to upgrade channel_type during the splicing process, there is no issue with that, but if we use the splicing protocol as the sole means of upgrading the channel_type and we also want that conversion to include taproot channels, we have to accept that the newly upgraded channels become unusable for routing until taproot gossip is widely deployed. For this reason, Dynamic Commitments cannot be based upon splicing without vastly complicating the codepath.

During my research into the different mechanisms that had to be balanced I did notice that the "ideal" protocol would be capable of renegotiating all channel parameters that were originally negotiated in the open/accept process. Splicing covers the situation where we want to change the amount of money in the channel. Dynamic commitments explicitly desires to exclude this to take advantage of the fact that it allows us to defer broadcast of the kickoff (the corollary of the splice transaction) indefinitely.

I do think that it is unfortunate that we can't really unify the renegotiation of all of open/accept under a single protocol but the reality is that the optimizations afforded by excluding the ability to add funds to the channel are so consequential that we can't really ignore them for the sake of symmetry in the protocol design.

In summary, if you want to add channel_type conversion to splicing, that would possibly provide some modest optimizations if you wanted to do bundled parameter changes, but it will not obviate the need for Dynamic Commitments.

@t-bast
Copy link
Collaborator

t-bast commented Apr 10, 2024

The trouble is that if we were to just negotiate a taproot upgrade and then immediately broadcast the transaction that converts the funding output to the new segwit v1 output, we run into the problem wherein the new funding output is incompatible with our current gossip system.

Indeed, we would only use this after adding gossip support. FWIW I would have only enabled upgrading to taproot channels after adding support for taproot gossip, which makes this point moot. I think we should go ahead with taproot gossip as soon as possible to provide a clean path for channel upgrades.

making the signed but unconfirmed kickoff as secure as the commitment transactions themselves.

Note that this "kick-off" transaction would thus need anchor outputs, or some other way of mitigating pinning.

Dynamic commitments explicitly desires to exclude this to take advantage of the fact that it allows us to defer broadcast of the kickoff (the corollary of the splice transaction) indefinitely.

Won't we run into issues where dynamic commitments and splicing create incompatibilities between each other? If you have an unconfirmed / unlocked kick-off transaction, how do you subsequently splice on top of this?

The way I see it, splicing requires broadcasting a transaction that spends the current funding output. It makes it suitable for adding and removing funds into the channel, and upgrading the channel_type when it requires a transaction (which actually is the case for upgrading to taproot channels). Splicing is thus not a great tool for updating channel parameters that don't need a transaction, for example updating max_htlc_value_in_flight or doing a channel_type upgrade from static_remotekey to anchor_outputs. This is where I believe another mechanism would be useful, but it seems to me that this should be a mechanism that does not rely on spending the funding transaction.

To be honest, it seems to me that dynamic commitment upgrades as it is proposed today is rather a hack to enable updating channels to taproot before taproot gossip, instead of being a generally useful complement to splicing. That may be fine if it doesn't interfere negatively with splicing, but if it makes those upgraded channels incompatible with splicing, that is IMO an issue.

@ProofOfKeags
Copy link
Contributor

To be honest, it seems to me that dynamic commitment upgrades as it is proposed today is rather a hack to enable updating channels to taproot before taproot gossip.

Yes. That is its most important goal. I think it's a good one since gossip upgrades require the whole network to adopt the new code, rather than dynamic commitments which only requires the two nodes on either side of the taproot edge to adopt it to keep it in sync with the rest of the network.

instead of being a generally useful complement to splicing

It was never supposed to be a useful complement to splicing to my knowledge. It was always a separate goal of making upgrading to taproot channels possible in a broadly usable way prior to a widely deployed new gossip system.

how do you subsequently splice on top of this?

You have a few choices but they all have various sacrifices. One way or another you have to build the splice tx on top of the dyncomm kickoff, which would require a kickoff broadcast since the splice requires broadcast, or you rebuild the kickoff on top of the splice transaction which makes things a bit more complicated as you have to remember some extra context when doing chain monitoring and splicing.

but if it makes those upgraded channels incompatible with splicing

It isn't fundamentally incompatible by my estimation, but mixing them is a thorny engineering issue with some discussions to be had and it would be incompatible until those engineering issues are solved.

@t-bast
Copy link
Collaborator

t-bast commented Apr 12, 2024

It was never supposed to be a useful complement to splicing to my knowledge. It was always a separate goal of making upgrading to taproot channels possible in a broadly usable way prior to a widely deployed new gossip system.

But then if that's the case, dynamic commitment upgrades doesn't seem like a good candidate for inclusion in the BOLTs, because once taproot gossip is deployed, upgrading to taproot channels will be more cleanly done using splicing? I don't think the BOLTs should contain complex protocols whose only goal is enabling something in the short term to work around a temporary limitation (lack of taproot gossip), because that creates technical debt. A cleaner path towards upgrading to taproot channels is to work more aggressively on taproot gossip and upgrade after that.

In my opinion, the BOLTs should contain:

  • one protocol for channel upgrades that require spending the current funding output: that should be splicing, because if you create a new funding transaction, you should also have the opportunity of taking funds in and out of the channel
  • one protocol for channel upgrades that don't require spending the current funding output: this would be used for upgrading commit txs to a new format that doesn't need to change the funding output (e.g. static_remotekey -> anchor_outputs) or for upgrading channel parameters (max_in_flight, dust_limit, etc)

Those protocols would complement each other nicely without creating technical debt.

That being said, I understand that lnd wants to be able to upgrade to taproot channels before taproot gossip is widely supported. But I believe lnd is the only implementation with that requirement, so it would make sense to have an lnd-only mechanism for that in the short term, and support for doing that upgrade using splicing in the longer term for compatibility with other implementations.

@Roasbeef
Copy link
Collaborator

Roasbeef commented Apr 12, 2024

But then if that's the case, dynamic commitment upgrades doesn't seem like a good candidate for inclusion in the BOLTs, because once taproot gossip is deployed, upgrading to taproot channels will be more cleanly done using splicing?

It depends on your goal. If you don't care about forcing all users to do an on chain transaction to migrate to the new output type, then ofc you can just have them all close their transactions and re-open them. Today we have ~50k public channels, our goal is to be able to migrate the vast majority of them without having some flag day resulting in 100k transactions on chain.

Commitment upgrades that require an off-chain kick off is just one of the upgrade types that dynamic commitments will enable.

Even if everyone had already implemented taproot gossip, I still think we'd pursue this path to avoid forcing pretty much every publicly routable mainnet channel to close. If we can allow the channels that have been open for years to pretty much never close, then why wouldn't we pursue that path? The interaction of splicing and the greater gossip network is still incomplete: the only way to handle the change over in lock step is by using an on-chain hint, but not everyone seems to be a fan of that approach.

The kick off upgrade mechanism is also the most direct path to enabling PTLCs across the network as well. Once upgraded a new channel update bit can be used to signal that the underlying channel actually supports the new payment type.

That being said, I understand that lnd wants to be able to upgrade to taproot channels before taproot gossip is widely supported.

As I mentioned above, I don't think those two events are intertwined. Even if we already had taproot gossip widely deployed, we wouldn't want to force the entire public network to close and re-open channels.

But I believe lnd is the only implementation with that requirement, so it would make sense to have an lnd-only mechanism for that in the short term, and support for doing that upgrade using splicing in the longer term for compatibility with other implementations

Nothing inherently makes the proposal lnd only. Though I understand we all have varying priorities, resources, and development road maps we're all concurrently pursuing.

I also don't think it's accurate to convey splicing as designed today, as a more generic mechanism than it actually is. If you only want to change the funding output on a channel, then you really don't need: dynamic ability to add multiple inputs, have multiple in flight splices, the RBF mechanism, ambiguity of settled balances, etc, etc. Not to mention the pinning concerns that the current approach deems to be out of scope.

@Roasbeef
Copy link
Collaborator

Roasbeef commented Apr 12, 2024

Splicing is thus not a great tool for updating channel parameters that don't need a transaction, for example updating max_htlc_value_in_flight or doing a channel_type upgrade from static_remotekey to anchor_outputs. This is where I believe another mechanism would be useful, but it seems to me that this should be a mechanism that does not rely on spending the funding transaction.

There's no requirement to spend the funding transaction to update those channel parameters. I think you might be understanding some key concepts w.r.t the proposal. Negotiation and execution are distinct. If I negotiate a channel type that needs to change the funding output, then during execution we'd need to handle creation + signing of that kick off. If we negotiate a change to the dust param, then we'd use the existing HTLC update log semantics, and then next signature would cover a state that applies that new update.

Pure param updates would be similar to the way update_fee works today. By putting these messages into the commitment update log, we can also re-use all the existing retransmission semantics.

@t-bast
Copy link
Collaborator

t-bast commented Apr 15, 2024

Today we have ~50k public channels, our goal is to be able to migrate the vast majority of them without having some flag day resulting in 100k transactions on chain.

This will never happen as a flag day anyway, since people won't upgrade their lightning implementation and decide to migrate all of their channels at the same time. Implementations should provide tools to upgrade channels when the feerate is low enough, to smooth out this transition. Using an unconfirmed kick-off transaction just hides the problem in the short term, but doesn't fix it at all?

I also don't think it's accurate to convey splicing as designed today, as a more generic mechanism than it actually is. If you only want to change the funding output on a channel, then you really don't need: dynamic ability to add multiple inputs, have multiple in flight splices, the RBF mechanism, ambiguity of settled balances, etc, etc. Not to mention the pinning concerns that the current approach deems to be out of scope.

I don't see what you are referring to exactly in this vague comment: dynamic commitments without publishing the kick-off transaction create a much greater security risk regarding pinning that splicing...

The kick off upgrade mechanism is also the most direct path to enabling PTLCs across the network as well. Once upgraded a new channel update bit can be used to signal that the underlying channel actually supports the new payment type.

Not really, we can do something much simpler than that, there's no reason for a kick-off transaction here. We can modify commitment transactions without spending the current funding output.

There's no requirement to spend the funding transaction to update those channel parameters. I think you might be understanding some key concepts w.r.t the proposal. Negotiation and execution are distinct. If I negotiate a channel type that needs to change the funding output, then during execution we'd need to handle creation + signing of that kick off. If we negotiate a change to the dust param, then we'd use the existing HTLC update log semantics, and then next signature would cover a state that applies that new update.

I agree, and that's exactly what I'm saying in my comment. That kind of upgrades are useful, and cannot be done cleanly with splicing. But what I'm arguing is that the protocol that enables such upgrades should never require spending the funding output, as anything that spends the funding output should instead be done on top of splicing to avoid the technical debt of two competing protocols.

@Roasbeef
Copy link
Collaborator

But what I'm arguing is that the protocol that enables such upgrades should never require spending the funding output, as anything that spends the funding output should instead be done on top of splicing to avoid the technical debt of two competing protocols.

Sure, that isn't how dynamic commitments is specified today. Negotiation and execution are distinct. You can update your dust limit without needing to spend the funding output.

@t-bast
Copy link
Collaborator

t-bast commented Sep 18, 2024

Superseded by #1160

@t-bast t-bast closed this Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.