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

Reply via email to