{"type":"rich","version":"1.0","author_name":"npub1za0a9afyj7um5feva0d5xmhfsah3zxm252hna2duq0numa952frqvuua2a","author_url":"https://nostr.ae/npub1za0a9afyj7um5feva0d5xmhfsah3zxm252hna2duq0numa952frqvuua2a","provider_name":"njump","provider_url":"https://nostr.ae","html":"📅 Original date posted:2018-10-19\n📝 Original message:\nGood evening all,\n\nThank you Rusty for starting us down this path :) and to ZmnSCPxj and Lisa\nfor\nyour thoughts. I think this narrows down the design space considerably!\n\nIn light of this, and if I'm following along, it seems our hand is forced in\nsplicing via a single on-chain transaction. In my book, this is preferable\nanyway. I'd much rather push complexity off-chain than having to do a\nmutli-stage splicing pipeline.\n\n\u003e To add some context to this, if you start accepting HTLC's for the new\nbalance\n\u003e after the parallel commitment is made, but before the re-anchor is buried,\n\u003e there's the potential for a race condition between a unilateral close (or\nany\n\u003e revoked commitment transaction) and the re-anchoring commitment\ntransaction,\n\u003e that spends the 'pre-committed' UTXO of splicing in funds and the original\n\u003e funding transaction\n\nIndeed, I'm not aware of any splicing mechanism that enables off-chain use\nof\nspliced-in funds before the new funding output confirms. Even in the async,\nsingle-txn case, the new funds cannot be spent until the new funding output\nconfirms sufficiently.\n\n\u003eFrom my POV, the desired properties of a splice are:\n 1. non-blocking (asynchronous) usage of the channel\n 2. single on-chain txn\n 3. ability to RBF (have multiple pending splices)\n\nOf these, it seems we've solidified 1 and 2. I understand the desire to not\ntackle RBF on the first attempt given the additional complexity.  However, I\ndo believe there are ways we can proceed in which our first attempt largely\ncoincides with supporting it in the future.\n\nWith that in mind, here are some thoughts on the proposals above.\n\n## RBF and Multiple Splices\n\n\u003e 1. type: 132 (`commitment_signed`)\n\u003e 2. data:\n\u003e    * [`32`:`channel_id`]\n\u003e    * [`64`:`signature`]\n\u003e    * [`2`:`num_htlcs`]\n\u003e    * [`num_htlcs*64`:`htlc_signature`]\n\u003e    * [`num_htlcs*64`:`htlc_splice_signature`] (`option_splice`)\n\nThis will overflow the maximum message size of 65535 bytes for num_htlcs \u003e\n511.\n\nI would propose sending a distinct message, which references the\n`active_channel_id` and a `splice_channel_id` for the pending splice:\n\n1. type: XXX (`commitment_splice_signed`) (`option_splice`)\n2. data:\n   * [`32`:`active_channel_id`]\n   * [`32`:`splice_channel_id`]\n   * [`64`:`signature`]\n   * [`2`:`num_htlcs`]\n   * [`num_htlcs*64`:`htlc_signature`]\n\nThis more directly addresses handling multiple pending splices, as well as\npreventing us from running into any size constraints. The purpose of\nincluding the `active_channel_id` would be to remote node locate the\nspliced channel, since it may not be populated indexes containing\nactive channels. If we don't want to include this, the existing message\ncan be used without modification.\n\n\u003e We shouldn't allow more than one pending splice operation anyway, as\n\u003e stated in your proposal initially. We are already critically reliant on\nour\n\u003e transaction being confirmed on-chain, so I don't see this as much of an\n\u003e added issue.\n\nIMO there's no reason to limit ourselves to one pending splice at the\nmessage\nlevel. I think it'd be an oversight to not to plan ahead with RBF in mind,\ngiven that funding transactions have gone unconfirmed precisely because of\nimproperly chosen fee rates. Arguably, funding flow should be extended to\nsupport this as well.\n\nCPFP works, though it's more wasteful than resigning and I'd prefer only to\ndo\nso out of necessity, rather than relying on it. CPFP is nice because it\ndoesn't\nrequire interaction, though we are already assuming the other party to be\nonline during the splice (unlike unilateral closes).\n\nAdding a splice-reject message/error code should be sufficient to allow\nimplementations to signal that their local tolerance for number of pending\nsplices has been reached. It's likely we'd all start with getting one splice\nworking, but then the messages won't need to modified if we want to\nimplement\nadditional pending splices via RBF.\n\nA node that wants to RBF but receives a reject can then proceed with CPFP\nas a\nlast resort.\n\nAre there any downsides I'm overlooking with this approach?\n\n\u003e | Bit Position  | Name                      | Field\n      |\n\u003e | ------------- | ------------------------- |\n-------------------------------- |\n\u003e | 0             | `option_channel_htlc_max` | `htlc_maximum_msat`\n      |\n\u003e | 1             | `option_channel_moving`   | `moving_txid\n     |\n\u003e\n\u003e The `channel_update` gains the following field:\n\u003e     * [`32`: moving_txid`] (option_channel_moving)\n\nDo we actually need to send the `moving_txid` via a channel update? I think\nit's\nenough for both parties to send `channel_update`s with the\n`option_channel_moving` bit set, and continue to keep the channel in our\nrouting\ntable.\n\nIf we receive later receive two `channel_update`s whose `short_channel_id`s\nreference the spending transaction (and the node pubkeys are the same), we\nassume the splice was successful and that this channel has been subsumed. I\nthink this works so long as the spending transaction doesn't contain\nmultiple\nfunding outputs, though I think the current proposal is fallible to this as\nwell.\n\nTo me, this proposal has the benefit of not bloating gossip bandwidth with\nan\nextra field that would need to parsed indefinitely, and gracefully\nsupporting\nRBF down the road. Otherwise we'd need to gossip and store each potential\ntxid.\n\nWith regards to forwarding, both `short_channel_id`s would be accepted by\nthe\nsplicers for up to 100 blocks (after splice confirm?), at which point they\ncan\nboth forget the prior `short_channel_id`.\n\n## Shachain\n\n\u003e I thought about restarting the revocation sequence, but it seems like\n\u003e that only saves a tiny amount since we only store log(N) entries.  We\n\u003e can drop old HTLC info post-splice though, and (after some delay for\n\u003e obscurity) tell watchtowers to drop old entries I think.\n\nI agree the additional state isn't too burdensome, and that we would still\nbe\nable to drop watchtower state after some delay as you mentioned.\n\nOn one hand, it does seem like the opportune time to remove such state if\ndesired.\n\nOTOH, it is _really_ nice from an atomicity perspective that the current\nchannel and (potentially) N pending channels can be revoked using a single\ncommitment secret and message. Doing so would mean we don't have to\nmodify the `revoke_and_ack` or `channel_reestablish` messages. The receiver\nwould just apply the commitment secrets/points to the current channel and\nany\npending splices.\n\n## Misc\n\n\u003e Any reason to now make the splicing_add_* messages allow one to add\nseveral\n\u003e inputs in a single message? Given \"acceptable\" constraints for how large\nthe\n\u003e witness and pkScripts can be, we can easily enforce an upper limit on the\n\u003e number of inputs/outputs to add.\n\nYes, I prefer this simplification.\n\n\u003e Additionally, as the size of the channel is either expanding or\ncontracting,\n\u003e both sides should be allowed to modify things like the CSV param, reserve,\n\u003e max accepted htlc's, max htlc size, etc. Many of these parameters like the\n\u003e CSV value should scale with the size of the channel, not allowing these\n\u003e parameters to be re-negotiated could result in odd scenarios like still\n\u003e maintain a 1 week CSV when the channel size has dipped from 1 BTC to 100k\n\u003e satoshis.\n\nAgreed!\n\n\u003e These all seem marginal to me.  I think if we start hitting max values,\n\u003e we should discuss increasing them.\n\nDoesn't this defeat the goal of firewalling funds against individual channel\nfailures?\n\n\u003e\u003e\u003e One thing that I think we should lift from the multiple funding output\n\u003e\u003e\u003e approach is the \"pre seating of inputs\". This is cool as it would allow\n\u003e\u003e\u003e clients to generate addresses, that others could deposit to, and then\nhave\n\u003e\u003e\u003e be spliced directly into the channel. Public derivation can be used,\nalong\n\u003e\u003e\u003e with a script template to do it non-interactively, with the clients\npicking\n\u003e\u003e\u003e up these deposits, and initiating a splice in as needed.\n\u003e\u003e\n\u003e\u003e How about this restatement?\n\u003e\u003e\n\u003e\u003e 1.  Each channel has two public-key-derivation paths (BIP32) to create\nonchain\n\u003e\u003e addresses.  One for each side of the channel.\n\u003e\u003e 2.  The base of the above is actually a combined private-public keypair\nof both\n\u003e\u003e sides (e.g. created via MuSig or some other protocol).  Thus the\naddresses\n\u003e\u003e require cooperation of both parties to spend.\n\u003e\u003e 3.  When somebody sends to one of the onchain addresses in the path,\ntheir\n\u003e\u003e client detects this.\n\u003e\u003e 4.  The client updates the current transaction state, such that the new\ncommit\n\u003e\u003e transaction has two inputs ( the original channel transaction and the\nnew UTXO).\n\u003e\u003e\n\u003e\u003e The above seems unsafe without trust in the other peer, as, the other\npeer can\n\u003e\u003e simply refuse to create the new commit transaction.  Since the address\nrequires\n\u003e\u003e both parties to spend, the money cannot be spent and there is no backoff\n\u003e\u003e transaction that can be used.  But maybe you can describe some mechanism\nto\n\u003e\u003e ensure this, if this is what is meant instead?\n\u003e\n\u003e This could easily be solved by making the destination address a Taproot\n\u003e address, which by default is just a 2-of-2, but in the uncooperative\n\u003e case it can reveal the script it commits to, which is just a timelocked\n\u003e refund that requires a single-sig. The only problem with this is that\n\u003e the refund would be non-interactive, and so the entirety of the funds,\n\u003e that may be from a third-party, need to be claimed by one endpoint,\n\u003e i.e., there is no splitting the funds in case of an uncollaborative\n\u003e refund. Not sure how important that is though, since I don't think\n\u003e third-party funds will come from unrelated parties, e.g., most of these\n\u003e funds will come from an on-chain wallet that is under the control of\n\u003e either parties so the refund should go back to that party anyway.\n\nThis can be accomplished similarly by having either (or both) party\npublishing a\nstatic address or publicly derivable address specific to the channel,\nderived\nfrom their HD seed.\n\nArguably, the address should perhaps be global, so that it can outlive the\nlifetime of the channel, i.e. as soon as the first person deposits and a\nsplice\nis initiated, is the address still valid for the new channel if new keys are\nused? Similarly, the channel could be closed and the funds locked until\nthe timeout if the peer disappears.\n\nRegardless, both approaches can be made to have equivalent amounts of\n[non-]interactivity. However, the recipient isn't burdened in spending by\n1) interaction with the channel peer, or 2) an absolute timeout if 1 fails,\ngiving the receiver more flexibility if they wish to not commit the received\nfunds to a splice. It also benefits from smaller witness sizes, a larger\nanonymity set, etc.\n\nIn general, using a 2-of-2+timeout to stage funds for splicing doesn't offer\nthat much IMO. It seems the primary purpose is to prevent the funds from\nbeing\ndouble spent during the splice, but observe that this is still possible if\nthe\ntimeout matures, perhaps because the splice doesn't confirm in a timely\nmanner.\n\nAcknowledging this, detecting double-spent inputs is still required for full\ncorrectness. By implementing it, either party is free to propose arbitrary\ninputs for a splice, which I believe reduces complexity in the long run.\n\nSplice out,\nConner\n\nOn Tue, Oct 16, 2018 at 10:00 PM ZmnSCPxj via Lightning-dev \u003c\nlightning-dev at lists.linuxfoundation.org\u003e wrote:\n\n\u003e Good morning lisa,\n\u003e\n\u003e This is a good observation.\n\u003e\n\u003e Before, I'd already considered the rationale, for why channels have a\n\u003e single 2-of-2 UTXO as funding output.  And it seems I should have\n\u003e considered this, prior to accepting the \"parallel\" construction as feasible.\n\u003e\n\u003e For sake of posterity, I leave the below writeup as a tangential to the\n\u003e design of splice (and to the design of Lightning having a single 2-of-2\n\u003e UTXOs):\n\u003e\n\u003e # 0-conf is Unsafe, Yet Lightning is Safe; Why?\n\u003e\n\u003e To accept a 0-conf transaction output, is known to be unsafe.\n\u003e Replace-by-fee is always a possibility, regardless of whether the\n\u003e transaction opts in to RBF or not: a rational miner will always accept the\n\u003e higher feerate, disregarding any \"opt-in\" flag that is set or not set on\n\u003e the transaction.  Thus we reject any advice that claims that 0-conf is\n\u003e tenable, even for tiny amounts.\n\u003e\n\u003e Yet when viewed solely in terms of transactions, Lightning protocol uses\n\u003e transactions that are not on any block (are kept offchain).  Since they are\n\u003e not in a block, they are indistinguishable from 0-conf transactions, which\n\u003e are accepted by the receiver, yet are also not on any block.  One might\n\u003e argue the distinction, that a \"real\" 0-conf transaction exists on some\n\u003e mempool somewhere, and thus has a chance to be on a block in the future,\n\u003e but mempools have no consensus, and the existence of a transaction on some\n\u003e mempool is not a safe assurance of it existing in the mempool of the next\n\u003e winning miner.\n\u003e\n\u003e So why is Lightning safe, when 0-conf transactions are in general not safe?\n\u003e\n\u003e Again, we should focus on why 0-conf transactions in general are not safe:\n\u003e transaction replacement.  Thus, 0-conf transactions can be made safe, if\n\u003e you are somehow able to ensure that replacement transactions cannot be made.\n\u003e\n\u003e For example, if you are part of an n-of-n federation that signs the\n\u003e transaction, you can always safely accept a 0-conf transaction from that\n\u003e federation paying only to you, because you can always veto any replacement\n\u003e (by simply refusing to sign) that is not in your interests.\n\u003e\n\u003e This is in fact how Lightning works: a 2-of-2 federation (the channel\n\u003e counterparties) are the signatories of the 0-conf transactions that are the\n\u003e commitment transactions of the Lightning protocol.  Replacement of the\n\u003e commitment transactions is strictly guided by the protocol; both sides have\n\u003e veto rights, since the source transaction output is 2-of-2.\n\u003e\n\u003e Thus, Lightning, though it uses 0-conf transactions, is safe, because it\n\u003e prevents the replacement of a 0-conf transaction without the receiver\n\u003e allowing it, by the simple expedient of including the receiver in the\n\u003e 2-of-2 multisig guarding its single funding TXO.\n\u003e\n\u003e ##  The Implications for Splice Proposals\n\u003e\n\u003e Some splice proposals involve creating the equivalent of multiple funding\n\u003e TXOs for a single channel.  Such constructions are unsafe-by-default on\n\u003e Poon-Dryja.\n\u003e\n\u003e In reality, every commitment transaction (or update transaction in\n\u003e Decker-Osuntokun-Russell) is replaceable by any other commitment (or\n\u003e update) transaction for that channel.  Under Poon-Dryja older transactions\n\u003e are revoked (and hence one side risks loss of their collateral) while under\n\u003e Decker-Osuntokun-Russell older transactions may be \"gainsaid\" (i.e. newer\n\u003e update transactions may be reanchored to consume the TXO of the older\n\u003e update transaction, thus preventing that update from truly being committed\n\u003e to).\n\u003e\n\u003e This is relevant since before a splice, the channel has a single funding\n\u003e TXO, while after the splice, the channel has multiple.\n\u003e\n\u003e In particular, a commitment (or update) transaction, that has multiple\n\u003e inputs (to consume the multiple funding TXOs), can be replaced with a\n\u003e commitment (or update) transaction that was created before the splice.\n\u003e Under Poon-Dryja, such a commitment transaction may be revoked, but this\n\u003e leaves the other funding TXOs unuseable.  Under Decker-Osuntokun-Russell,\n\u003e as long as the sequence number is preserved across the splice, it is\n\u003e possible for a later update transaction with multiple inputs to simply\n\u003e gainsay the old single-input update with the new multiple-input update\n\u003e transaction. (I suppose, that this is another advantage that\n\u003e Decker-Osuntokun-Russell has).\n\u003e\n\u003e Regards,\n\u003e ZmnSCPxj\n\u003e\n\u003e\n\u003e Sent with ProtonMail \u003chttps://protonmail.com\u003e Secure Email.\n\u003e\n\u003e ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐\n\u003e On Wednesday, October 17, 2018 9:09 AM, lisa neigut \u003cniftynei at gmail.com\u003e\n\u003e wrote:\n\u003e\n\u003e To add some context to this, if you start accepting HTLC's for the new\n\u003e balance after the parallel commitment is made, but before the re-anchor is\n\u003e buried, there's the potential for a race condition between a unilateral\n\u003e close (or any revoked commitment transaction) and the re-anchoring\n\u003e commitment transaction, that spends the 'pre-committed' UTXO of splicing in\n\u003e funds and the original funding transaction.\n\u003e\n\u003e You can get around this by waiting until both the pre-commitment UTXO and\n\u003e the re-anchor have cleared a minimum depth before accepting HTLC's for the\n\u003e new balance totals, but that's twice as long of a wait as the first,\n\u003e synchronized re-commitment scheme that Rusty originally proposed.\n\u003e\n\u003e It also makes leaving the original funding transaction 'exposed' (ie\n\u003e Rene's version of parallel splice) untenable, as there's always the risk of\n\u003e an old state being published to consume that input. This foobars your\n\u003e current HTLC commitments.\n\u003e\n\u003e On Tue, Oct 16, 2018 at 3:31 PM Rusty Russell \u003crusty at rustcorp.com.au\u003e\n\u003e wrote:\n\u003e\n\u003e\u003e Rusty Russell \u003crusty at rustcorp.com.au\u003e writes:\n\u003e\u003e \u003e If we're going to do side splice-in like this, I would use a very\n\u003e\u003e \u003e different protocol: the reason for this protocol was to treat splice-in\n\u003e\u003e \u003e and splice-out the same, and inline splice-in requires wait time.  Since\n\u003e\u003e \u003e splice-out doesn't, we don't need this at all.\n\u003e\u003e \u003e\n\u003e\u003e \u003e It would look much more like:\n\u003e\u003e \u003e\n\u003e\u003e \u003e 1. Prepare any output with script of specific form. eg:\n\u003e\u003e \u003e         OP_DEPTH 3 OP_EQUAL OP_IF\n\u003e\u003e \u003e                 \u003cfunding_pubkey1\u003e \u003cfunding_pubkey2\u003e OP_CHECKMULTISIG\n\u003e\u003e \u003e         OP_ELSE\n\u003e\u003e \u003e                 \u003cblockheight\u003e OP_CHECKLOCKTIMEVERIFY OP_DROP\n\u003e\u003e \u003e                 \u003cmyrescue_pubkey\u003e OP_CHECKSIG\n\u003e\u003e \u003e         OP_ENDIF\n\u003e\u003e \u003e\n\u003e\u003e \u003e 1. type: 40 (`splice_in`) (`option_splice`)\n\u003e\u003e \u003e 2. data:\n\u003e\u003e \u003e    * [`32`:`channel_id`]\n\u003e\u003e \u003e    * [`8`: `satoshis`]\n\u003e\u003e \u003e    * [`32`: `txid`]\n\u003e\u003e \u003e    * [`4`: `txoutnum`]\n\u003e\u003e \u003e    * [`4`: `blockheight`]\n\u003e\u003e \u003e    * [`33`: `myrescue_pubkey`]\n\u003e\u003e \u003e\n\u003e\u003e \u003e 1. type: 137 (`update_splice_in_accept`) (`option_splice`)\n\u003e\u003e \u003e    data:\n\u003e\u003e \u003e    * [`32`:`channel_id`]\n\u003e\u003e \u003e    * [`32`: `txid`]\n\u003e\u003e \u003e    * [`4`: `txoutnum`]\n\u003e\u003e \u003e\n\u003e\u003e \u003e 1. type: 138 (`update_splice_in_reject`) (`option_splice`)\n\u003e\u003e \u003e    data:\n\u003e\u003e \u003e    * [`32`:`channel_id`]\n\u003e\u003e \u003e    * [`32`: `txid`]\n\u003e\u003e \u003e    * [`2`:`len`]\n\u003e\u003e \u003e    * [`len`:`errorstr`]\n\u003e\u003e \u003e\n\u003e\u003e \u003e The recipient of `splice_in` checks that it's happy with the\n\u003e\u003e \u003e `blockheight` (far enough in future).  Once it sees the tx referred to\n\u003e\u003e \u003e buried to its own `minimum_depth`, it checks output is what they\n\u003e\u003e \u003e claimed, then sends `update_splice_in_accept`; it's followed up\n\u003e\u003e \u003e `commitment_signed` like normal, but from this point onwards, all\n\u003e\u003e \u003e commitment txs signatures have one extra sig.\n\u003e\u003e\n\u003e\u003e Lisa started asking pointed questions, and so I noticed that parallel\n\u003e\u003e splice doesn't work with Poon-Dryja channels.\n\u003e\u003e\n\u003e\u003e The counterparty can spend the old funding txout with a revoked spend.\n\u003e\u003e Sure, I can take all the money from that, but what about the spliced\n\u003e\u003e input?\n\u003e\u003e\n\u003e\u003e I came up with increasingly elaborate workarounds, but nothing stuck.\n\u003e\u003e\n\u003e\u003e Back to Plan A...\n\u003e\u003e Rusty.\n\u003e\u003e _______________________________________________\n\u003e\u003e Lightning-dev mailing list\n\u003e\u003e Lightning-dev at lists.linuxfoundation.org\n\u003e\u003e https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev\n\u003e\u003e\n\u003e\n\u003e _______________________________________________\n\u003e Lightning-dev mailing list\n\u003e Lightning-dev at lists.linuxfoundation.org\n\u003e https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev\n\u003e\n-------------- next part --------------\nAn HTML attachment was scrubbed...\nURL: \u003chttp://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20181018/d57ce11c/attachment-0001.html\u003e"}
