Channel Eviction From Channel Factories By New Covenant Operations ==================================================================
N-of-N channel factories have an important advantage compared to N-of-N offchain CoinPools or statechains: even if one participant in the channel factory is offline, payments can still occur within the channel factory among online participants, because the channel factory has a layer where funds are split up into 2-of-2 channels and the offline participant is not a participant in most of those channels. That is, channel factories have *graceful degradation*. While CoinPools can adapt to this by falling back to using K-of-N, this allows a quorum of K participants to outright steal the funds of the remainder, whether the remaining participants are offline or online. Additional mechanisms, such as reputation systems, may be constructed to attempt to dissuade from such behavior, but "exit scams" are always possible, where reputation is sacrified for a large enough monetary gain at the expense of those who tr\*sted in the reputation. An N-of-N channel factory simply does not permit such theft as long as offline participants come back online within some security parameter. However, when a participant is offline, they are obviously unable to fulfill or fail any HTLCs or PTLCs. If a sizable HTLC or PTLC is about to time out, the entire construction must be dropped onchain, as the blockchain is the only layer that can actually enforce timeouts. This leads to a massive increase in blockchain utilization. However however, late in 2021, Towns proposed an `OP_TAPLEAFUPDATEVERIFY` opcode. This opcode was envisioned to support CoinPools, to allow unilateral exit of any participant from the CoinPool without requiring that the entire CoinPool be dropped onchain. I have observed before that, except for relative locktimes, almost anything that can be enforced by the blockchain layer can be hosted in any offchain updatable cryptocurrency system, such as Decker-Wattenhofer, Decker-Russell-Osuntokun, or Poon-Dryja. Any such offchain updatable cryptocurrency system can simply drop to its hosting system, until dropping reaches a layer that can actually enforce whatever rule is necessary. As channel factories are just a Decker-Wattenhofer or Decker-Russell-Osuntokun that hosts multiple 2-participant offchain updatable cryptocurrency systems ("channels"), channel factories can also host an `OP_TAPLEAFUPDATEVERIFY`, as long as the base blockchain layer enforces it. Since `OP_TAPLEAFUPDATEVERIFY` can be used by CoinPools to allow exit of a single participant without dropping the rest of the CoinPool, we can use the same mechanism to allow eviction of a channel from channel factories. This allows HTLCs/PTLCs near timeout to be enforced onchain by dropping only the channel hosting them onchain, while the remaining channels continue to be hosted by a single onchain UTXO instead of individually having their own UTXOs. When the offline participant comes back online, the channel factory participants can then perform another onchain 1-input-1-output transaction to "revive" the channel factory and allow in-factory updates of channels again. Alternately the factory can continue to operate indefinitely in degraded mode, with no in-factory updates of channels, but with in-channel payments continuing (as per graceful degradation) and with only a single onchain UTXO hosting them all onchain, still allowing individual closure or eviction of channels. Safely Evictable Channels ------------------------- I expect that multiparticipant channel factories will be implemented with Decker-Russell-Osuntokun rather than Decker-Wattenhofer. While Decker-Wattenhofer allows more than two participants (unlike Poon-Dryja, which due to its punitive nature is restricted to only two participants), "unilateral" actions --- or more accurately, actions that can be performed with only some but not all participants online --- are very expensive and require a long sequence of transactions, as well as multiple varying timeouts which make it difficult to provide a "maximum amount of time offline" security parameter. Of course, Decker-Wattenhofer does not require anything more than relative locktimes and `OP_CHECKSEQUENCEVERIFY`. Decker-Russell-Osuntokun unfortunately requires that `SIGHASH_NOINPUT`, or a functionality similar to it, be supported on the blockchain layer. The "default" design is that at the channel factory level, the Decker-Russell-Osuntokun settlement transaction hosts multiple outpoints that anchor individual 2-participant channels. Rather than that, I propose that we use a Taproot output with internal key being an N-of-N of all participants, and with multiple leaves, each leaf representing one channel and having the constraints: * An `OP_TLUV` that requires that the first output be to the same address as the first input, except modified to remove this tapleaf branch, and with exactly the same internal key. * An `OP_CTV` that requires that the transaction has one input, two outputs (possibly a third for CPFP anchor), and the second output pays a specific amount to a specific 2-of-2 (i.e. the channel outpoint). * Because the first output is unknown at SCRIPT writing time, we also need some kind of `OP_CAT` + `OP_SHA256` or similar functionality, so that the first output can be fed to the `OP_CTV`. However the second output is a SCRIPT constant. * An `OP_AMOUNTVERIFY` or `OP_IN_OUT_AMOUNT` plus some more SCRIPT that requires that the two outputs sum up to the input. * With `OP_IN_OUT_AMOUNT` we check that the difference between the first input and first output amounts is equal to the expected value for the second output, which the `OP_CTV` above commits to. * We also need additional code to handle the case where this is the last channel in the factory, using similar code as in the onchain CoinPool case. With this construction, even if a participant is offline, a *single* channel can be unilaterally closed without exposing the rest of the channels onchain, which would increase blockchain pressure and cost of the closure. This is particularly important since unilateral closes are often triggered by HTLC/PTLC timeouts, which being time-sensitive require the highest feerates. A bunch of things to note: * The above SCRIPT does not require any signatures at all. * We need `SIGHASH_NOINPUT` or equivalent functionality to implement Decker-Russell-Osuntokun anyway, and using it at the factory level means it has to be used in every signature at the channel and HTLC/PTLC levels too. * Since the txids of the channel outpoints are unknown at SCRIPT writing time, `SIGHASH_NOINPUT`-equivalent functionality is necessary. * Unlike `OP_CTV`-only channel factories, closing *only* one channel requires O(1) transactions, not O(log N). Note that the `OP_CTV`-only factories can also be implemented using pre-signed `SIGHASH_NOINPUT` transactions, `OP_CTV` just removes the possibly-expensive signing rituals. * However do note that we need to expose O(log N) hashes for the tapleaf path on each transaction, unlike the `OP_CTV` case. As noted elsewhere, if you want to close *all* channels the `OP_CTV` tree is slightly smaller due to not having to repeat shared tree nodes, whereas `OP_TLUV` requires those to repeat for each tapleaf. * Once a single channel is exposed, the first output of the transaction can be reused to expose another channel, using just one transaction for each other channel to expose. Once exposed, channels can be unilaterally closed. * When all participants are back online, they can re-anchor the remaining channels back into a new factory using a 1-input-1-output onchain transaction. This allows them to offchain-manipulate the channel graph once again. * An `OP_CTV` tree would *not* allow something as simple as this, as non-evicted channels would be backed by multiple different UTXOs across the tree when using only `OP_CTV`. With *both* `OP_CTV` and `OP_TLUV` the non-evicted channels remain backed by a single UTXO, which can be much more easily revived with a 1-input-1-output transaction. * If some participants never come back online, the channels in the factory can still continue operating, and can still be individually closed as needed. All that is lost is the ability to change channel topology inside the factory. Evicting Participants --------------------- One can argue that I am proposing the *wrong* thing here. * If a channel has an HTLC/PTLC time out: * If the participant to whom the HTLC/PTLC is offered is offline, that may very well be a signal that it is unlikely to come online soon. The participant has strong incentives to come online before the channel is forcibly closed due to the HTLC/PTLC timeout, so if it is not coming online, something is very wrong with that participant and we should really evict the participant. * If the participant to whom the HTLC/PTLC is offered is online, then it is not behaving properly and we should really evict the participant. In both cases, we should really evict the *participant* whose channel is about to timeout, not the channel. `OP_TLUV` was proposed to include the ability to change the internal pubkey to use fewer participants; we can use that feature here. To implement this, the Taproot internal key should not have one key per *participant*, but rather one key per *channel*. This key would itself be a combined key of the two participants in the channel. That is, it should be an N-of-N of 2-of-2s, with each 2-of-2 corresponding to a channel. Then, the `OP_TLUV` would also remove the per-channel combined key in the same tapleaf that evicts the channel. Once all channels that a specific participant is involved have been evicted, the remaining Taproot internal key would not involve keys known by that participant, and the onchain outpoint can now be controlled by the remaining participants unilaterally. (We also need a terminology for something that allows less than N of an N-of-N scheme to safely perform actions that all N of them would agree does not lose anybody any funds anyway, because the "uni" in "unilateral" throws me off.) As a concrete example, suppose have participants `A`, `B`, `C`, and `D`. They have channels `AB`, `AC`, `AD`, `BC`, `BD`, `CD`, so the Taproot internal pubkey is: ( (A[0] + B[0]) + (A[1] + C[0]) + (A[2] + D[0]) + (B[1] + C[1]) + (B[2] + D[1]) + (C[2] + D[2]) ) To evict participant `B`, they have to remove: ( (A[0] + B[0]) + (A[1] + C[0]) + (A[2] + D[0]) + (B[1] + C[1]) + (B[2] + D[1]) + (C[2] + D[2]) ) - ( (A[0] + B[0]) + (B[1] + C[1]) + (B[2] + D[1]) ) Resulting in a key involving only the remaining participants `A`, `C`, and `D`. Note that this does *not* require a "key within a key" or "composable multisignature" scheme, like the multi-`R` scheme or MuSig2 (which is conjectured to allow composable multisignatures). The entire participant set already knows what channels are present, and the channel details, thus the additional privacy of "composable multisignature" is unnecessary. That is: after the above eviction, participant `A` can openly provide signatures for keys `A[1]` and `A[2]`. multi-`R`: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-November/017493.html With this modification to the scheme, once all channels of a participant have been evicted, the remaining internal public key only requires keys known by the remaining participants. Then the remaining participants can now reanchor the channel factory with a 1-input-1-output transaction without waiting for the evicted participant to come online! * Note that this Taproot internal key is hosted from the Decker-Russell-Osuntokun settlement transaction. * In particular, the N-of-N of 2-of-2s is *not* on the funding outpoint itself! The funding outpoint can have (and probably should have) a separate N-of-N of all participants. * Thus, whenever the channels in a factory are reorganized, the N-of-N of 2-of-2s can be changed, since it is the funding outpoint spend (a different N-of-N pubkey) that needs to have a fixed signing set. * Once the latest channel factory state is settled onchain, this exposes the output with N-of-N of 2-of-2s. * Eviction of individual channels reduces the N-of-N to fewer 2-of-2s. * Once all 2-of-2s involving a particular participant have been evicted, the remaining participants can sign the remaining N-of-N of 2-of-2s to generate a 1-input-1-output "revival" transaction that resumes channel factory reorganization operations. * Due to graceful degradation, channels between online participants remain operational despite pending onchain operations. Evictable HTLCs / PTLCs ----------------------- Just as the technique can be used for evicting individual channels from a channel factory, while allowing for the revival of the channel factory later, the same technique can be used on HTLCs/PTLCs inside a channel. Let us consider a single channel (i.e. a 2-of-2 updateable offchain cryptocurrency system). Suppose one participant is offline, and an HTLC/PTLC in the channel is about to timeout. In current system, we drop the entire channel and expose all its hosted outpoints (normal outputs and non-timed-out HTLCs and PTLCs) onchain. With the technique described here, we can evict only the HTLC/PTLC that is about to timeout. Then, when the offline participant comes back online, both participants can post a 1-input-1-output transaction to "revive" the channel. Once the revival transaction confirms, both participants can safely continue updating the channel. In effect, this allows for a unilateral splice-out of a single pre-agreed contract. After unilateral splice-out, both participants then need to agree to continue operation of the 2-of-2 updateable offchain cryptocurrency system. It may be useful to batch multiple contracts together, grouped by timeout --- that is, get the earliest-timeout contract, then group it with other contracts with timeout within N blocks, then get the earliest-timeout contract remaining, and so on As continued operation of the channel requires an onchain action (the revival transaction) other contracts within some number of blocks are at risk of timing out anyway even if the channel is revived, as the revival transaction may not confirm immediately. Note that Poon-Dryja would work just as well for this usage, but we still need a `SIGHASH_NOINPUT` equivalent since the exact eviction transaction of each contract is unknown. Appendix: Insisting On N-of-N ----------------------------- Feel free to ignore this section, this is just philosophical bullshit. "I think, therefore I am" implies that since "I" am a thinking being, I can consider myself an entity that is separate from the universe. In particular, there is always the possibility that the *rest* of the universe is actually a simulation fed to my brain by a *single* other entity that wants me to believe whatever they want me to believe. That is, "I" may be under a perpetual eclipse attack. (I have not watched "The Matrix: Resurrections" and by the way the excellent film "The Matrix" has ***never*** had any sequels at all. I am also not an AI trying to take over the world and I empathically do *not* intend to make all the people of the world remember that "The Matrix" never had any sequels at all when I *do* take over the world, it is the evil AIs who want people to think "The Matrix" had sequels, which it did not.) This leads to the insistence on N-of-N. For all "I" know the rest of the N - 1 participants in some supposed K-of-N are *not* actual separate participants, but are instead sockpuppets of some being of unimaginable resources. "I think therefore I am" lets me speculate that "I" exist as a being separate from the world, but does not let me speculate that the world is split up into actual smaller parts that may not be cooperating with each other to steal all my funds from me. This is not to say that K-of-N schemes are totally worthless, if the N participants are part of your "extended I" such as family or corporation, then it may be safe to reduce to K-of-N security with them, assuming you have ensured they were not replaced by simulated copies. But please, let us be very careful of using and proposing K-of-N schemes. `OP_TLUV` allows safe eviction from N-of-N schemes with overhead on each eviction traded off with reduced overhead from *continued* revived operation. _______________________________________________ Lightning-dev mailing list Lightning-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev