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