-
Notifications
You must be signed in to change notification settings - Fork 488
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
Channel Splicing (feature 62/63) #1160
base: master
Are you sure you want to change the base?
Conversation
Splicing allows spending the current funding transaction to replace it with a new one that changes the capacity of the channel, allowing both peers to add or remove funds to/from their channel balance. Splicing takes place while a channel is quiescent, to ensure that both peers have the same view of the current commitments. We don't want channels to be unusable while waiting for transactions to confirm, so channel operation returns to normal once the splice tx has been signed and we're waiting for it to confirm. The channel can then be used for payments, as long as those payments are valid for every pending splice transactions. Splice transactions can be RBF-ed to speed up confirmation. Once one of the pending splice transactions confirms and reaches acceptable depth, peers exchange `splice_locked` to discard the other pending splice transactions and the previous funding transaction. The confirmed splice transaction becomes the channel funding transaction. Nodes then advertize this spliced channel to the network, so that nodes keep routing payments through it without any downtime.
Can I suggest we do this as an extension BOLT rather than layering it in with the existing BOLT2 text? It makes it easier to implement when all of the requirements deltas are in a single document than when it is inlined into the original spec. Otherwise, the PR/branch-diff itself is the only way to see the diff and that can get very messy during the review process as people's commentary comes in. While there are other ways to get at this diff without the commentary, it would make the UX of getting at this diff rather straightforward. Given that the change is gated behind a feature bit anyway it also makes it easier for a new implementation to bootstrap itself without the splice feature by just reading the main BOLTs as is. At some point in the future when splicing support becomes standard across the network we can consolidate the extension BOLT into the main BOLTs if people still prefer. |
Why not, if others also feel that it would be better as an extension bolt. I prefer it directly in Bolt 2, because of the following reasons:
But if I'm the only one thinking this is better, I'll move it to a separate document! One thing to note is that we already have two implementations ( |
|
||
On reconnection: | ||
- MUST retransmit its last `splice_locked` if the `commitment_number` | ||
is the same as before sending `splice_locked`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be sent if we receive a next_funding_txid
matches our current channel funding txid (ie we have splice_locked
but our peer hasn't).
Probably we should drop this clause as the reestablish splice_locked
clause already covers this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No? I think we're not on the same page here regarding splice_locked
or the inclusion of the next_funding_txid
field, it's important to clarify this. If we've correctly exchanged signatures, we won't include next_funding_txid
in channel_reestablish
at all. But we may not have exchanged splice_locked
at that point.
If I then send splice_locked
but we disconnect, I'll need to retransmit it on reconnection. The only stage at which I know I don't need to retransmit it is if we signed a new commitment after locking.
|
||
On reconnection: | ||
- If `next_funding_txid` matches the splice transaction: | ||
- MUST retransmit `tx_signatures`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless the splice has already splice_locked
locally.
I suggest we drop this clause and articulate this just in the reestablish clause so we don't have duplicate rules for the same thing around the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless the splice has already splice_locked locally.
No, that doesn't work, if your peer sets next_funding_txid
, you must retransmit tx_signatures
. You may have sent tx_signatures
and splice_locked
, but a disconnection dropped them and your peer didn't receive any of them. In that case you cannot skip sending tx_signatures
, otherwise they would never receive it.
Or maybe I'm misunderstanding what you mean by "has already splice_locked
locally"?
One thing I've been thinking about is with large splices across many nodes, if some node fails to send signatures (likely because two nodes in the cluster demand to sign last) than splice will hang one I believe we need two things to address this:
Currently CLN fails the channel in this case as taking signatures and not responding is rather rude but this is bad because it could lead to clusters of splice channels being closed. The unfortunate side effect of this is we have to be comfortable sending out signatures with no recourse for not getting any back. I believe long term the solution is to maintain a signature-sending reputation for each peer and eventually blacklist peers from doing splices and / or fail your channels with that peer. A reputation system may be beyond the needs of the spec but what to do with hanging |
This is already covered at the quiescence level: quiescence will timeout if the splice doesn't complete (e.g. because we haven't received
I don't think this is necessary, and I think we should really require people to send
It seems like we've discussed this many times already: this simply cannot happen because ordering based on contributed amount fixes this? Can you detail a concrete scenario where |
If both nodes set `next_funding_txid` in their `channel_reestablish` message, but to a different value, one of them is very buggy. There is no way to correctly resolve this and the channel must be closed. Suggested by @ddustin
- SHOULD use a different `funding_pubkey` than the one used for the | ||
previous funding transaction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the "funding_pubkey
-should-be-different" requirement also hold for the splice_init
message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, I don't know why I only added that to splice_ack
, and not to splice_init
as well. Thanks, I'll add it.
Splicing allows spending the current funding transaction to replace it with a new one that changes the capacity of the channel, allowing both peers to add or remove funds to/from their channel balance.
Splicing takes place while a channel is quiescent, to ensure that both peers have the same view of the current commitments.
We don't want channels to be unusable while waiting for transactions to confirm, so channel operation returns to normal once the splice transaction has been signed and we're waiting for it to confirm. The channel can then be used for payments, as long as those payments are valid for every pending splice transactions. Splice transactions can be RBF-ed to speed up confirmation.
Once one of the pending splice transactions confirms and reaches acceptable depth, peers exchange
splice_locked
to discard the other pending splice transactions and the previous funding transaction. The confirmed splice transaction becomes the channel funding transaction.Nodes then advertise this spliced channel to the network, so that nodes keep routing payments through it without any downtime.
This PR replaces #863 which contains a lot of legacy mechanisms for early versions of splicing, which didn't work in some edge cases (detailed in the test vectors provided in this PR). It can be very helpful to read the protocol flows described in the test vector: they give a better intuition of how splicing works, and how it deals with message concurrency and disconnections.
This PR requires the quiescence feature (#869) to start negotiating a splice.
Credits to @rustyrussell and @ddustin will be added in the commit messages once we're ready to merge this PR.