๐
Original date posted:2023-04-03
๐ Original message:
Hi Bastien,
Thanks for the update on the state of splicing.
> We've also discovered that implementing 0-conf splicing is tricky: you
> need to be very careful about scenarios where your peer force-closes
> using an *inactive* commitment that ends up double-spending what you
> think is the only *active* commitment but is unconfirmed. We'd be happy
> to discuss that in more details with other implementers to reduce the
> risk of introducing new vulnerabilities when shipping that feature.
I think halting 0-conf splicing is pretty easy for a counterparty by
abusing Bitcoin Core mempool replacement rule #5 on the maximum number of
original transactions replaced.
Let's say you have Alice with 10% of the channel capacity as a balance in
the "inactive" commitment and the 90% remaining in favor of Bob. Bob has
initiated a splice out of 70% of the channel capacity. On the interactive
transaction, Alice adds 4 unrelated confirmed inputs and then broadcasts 4
chains of 25 unconfirmed transactions from those inputs.
When Bob broadcasts the splice-out, it should be rejected by the network
mempools on the grounds of RBF rule #5, whatever the absolute fee and
feerate. So the "0-conf" splicing might be maintained under risk of
double-spend by your counterparty for a while.
It sounds like Bob's splice out funds should be segregated until the
corresponding "active commitment" is confirmed, i.e no use to fund another
channel,
with inbound/outbound HTLC flows.
Best,
Antoine
Le lun. 3 avr. 2023 ร 00:25, Bastien TEINTURIER <bastien at acinq.fr> a รฉcrit :
> Good morning list,
>
> As some of you may know, we've been hard at work experimenting with
> splicing [1]. Splicing is a complex feature with a large design space.
> It was interesting to iterate on two separate implementations (eclair
> and cln) and discover the pain points, edge cases and things that could
> be improved in the protocol specification.
>
> After a few months trying out different approaches, we'd like to share
> changes that we believe make the splicing protocol simpler and more
> robust.
>
> We call "active commitments" the set of valid commitment transactions to
> which updates must be applied. While one (or more) splices are ongoing,
> there is more than one active commitment. When signing updates, we send
> one `commitment_signed` message per active commitment. We send those
> messages in the order in which the corresponding funding transactions
> have been created, which lets the receiver implicitly match every
> `commitment_signed` to their respective funding transaction.
>
> Once we've negotiated a new splice and reached the signing steps of the
> interactive-tx protocol, we send a single `commitment_signed` for that
> new commitment. We don't revoke the previous commitment(s), as this adds
> an unnecessary step. Conceptually, we're simply adding a new commitment
> to our active commitments set.
>
> A sample flow will look like this:
>
> Alice Bob
> | stfu |
> |----------------------------->|
> | stfu |
> |<-----------------------------|
> | splice_init |
> |----------------------------->|
> | splice_ack |
> |<-----------------------------|
> | |
> | <interactive-tx> |
> |<---------------------------->|
> | |
> | tx_complete |
> |----------------------------->|
> | tx_complete |
> |<-----------------------------|
> | commit_sig | Sign the new commitment.
> |----------------------------->|
> | commit_sig | Sign the new commitment.
> |<-----------------------------|
> | tx_signatures |
> |----------------------------->|
> | tx_signatures |
> |<-----------------------------|
> | |
> | update_add_htlc | Alice and Bob use the channel while
> the splice transaction is unconfirmed.
> |----------------------------->|
> | update_add_htlc |
> |----------------------------->|
> | commit_sig | Sign the old commitment.
> |----------------------------->|
> | commit_sig | Sign the new commitment.
> |----------------------------->|
> | revoke_and_ack |
> |<-----------------------------|
> | commit_sig | Sign the old commitment.
> |<-----------------------------|
> | commit_sig | Sign the new commitment.
> |<-----------------------------|
> | revoke_and_ack |
> |----------------------------->|
> | |
> | splice_locked | The splice transaction confirms.
> |----------------------------->|
> | splice_locked |
> |<-----------------------------|
> | |
> | update_add_htlc | Alice and Bob can use the channel
> and forget the old commitment.
> |----------------------------->|
> | commit_sig | Sign the new commitment.
> |----------------------------->|
> | revoke_and_ack |
> |<-----------------------------|
> | commit_sig | Sign the new commitment.
> |<-----------------------------|
> | revoke_and_ack |
> |----------------------------->|
> | |
>
> You can find many more details and sample flows in [2].
>
> We require nodes to store data about the funding transaction as soon as
> they send their `commitment_signed` message. This lets us handle every
> disconnection scenario safely, allowing us to either resume the signing
> steps on reconnection or forget the funding attempt. This is important
> because if peers disagree on the set of active commitments, this will
> lead to a force-close. In order to achieve that, we only need to add
> the `next_funding_txid` to the `channel_reestablish` message, and fill
> it when we're missing signatures from our peer. Again, you can find more
> details and sample flows in [2].
>
> Finally, after trying various approaches, we believe that the funding
> amounts that peer exchange in `splice_init` and `splice_ack` should be
> relative amounts based on each peer's current channel balance.
>
> If Alice sends `funding_amount = 200_000 sats`, it means she will be
> adding 200 000 sats to the channel's capacity (splice-in).
>
> If she sends `funding_amount = -50_000 sats`, it means she will be
> removing 50 000 sats from the channel's capacity (splice-out).
>
> This makes it easier to compute the new channel balances (otherwise we
> have to deal with millisatoshi to satoshi truncation) and better matches
> the UX that node operators are expecting, which means there is less need
> to glue code between the RPC exposed to the node operator and the actual
> underlying protocol.
>
> We've also discovered that implementing 0-conf splicing is tricky: you
> need to be very careful about scenarios where your peer force-closes
> using an *inactive* commitment that ends up double-spending what you
> think is the only *active* commitment but is unconfirmed. We'd be happy
> to discuss that in more details with other implementers to reduce the
> risk of introducing new vulnerabilities when shipping that feature.
>
> Cheers,
> Bastien
>
> [1] https://github.com/lightning/bolts/pull/863
> [2] https://gist.github.com/t-bast/1ac31f4e27734a10c5b9847d06db8d86
> _______________________________________________
> Lightning-dev mailing list
> Lightning-dev at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20230403/ef027b9b/attachment-0001.html>