Hi Antoine,

Very interesting exploration. I think you're right that there are issues with the kind of partitioning you're talking about. Lightning works because all participants sign all offchain states (barring data loss). If a participant can be excluded from needing to agree to a new state, there must be an additional mechanism to ensure the relevant state for that participant isn't changed to their detriment. 

To summarize my below email, the two techniques I can think for solving this problem are:

A. Create sub-pools when the whole group is live that can be used by the sub- pool participants later without the whole group's involvement. The whole group is needed to change the whole group's state (eg close or open sub-pools), but sub-pool states don't need to involve the whole group.
B. Have an always-online system empowered to sign only for group updates that *do not* change the owner's balance in the group. This could be done with a hardware-wallet like device, or could be done with some kind of new set of opcodes that can be used to verify that a particular transaction isn't to the owner's detriment.

I had some thoughts that I think don't pan out, but here they are anyway:

What if the pool state transaction (that returns everyone's money) has each participant sign the input + their personal output (eg with sighash flags)? That way the transaction could have outputs swapped out by a subset of participants as needed. Some kind of eltoo mechanism could then ensure that the latest transaction can override earlier transactions. As far as the non-participating members are concerned, they don't care whether the newest state is published or whether the newest state they participated in is published - because their output is identical either way. However, I can see that there might be problems related to separate groups of participants creating conflicting transactions, ie A B & C create a partition like this, and so do D E & F, but they don't know about each other's state. If they have some always-online coordination mechanism, this could be solved as long as the participants aren't malicious. But it still leaves open the possibility that some participants could intentionally grief others by intentionally creating conflicting state transactions. Theoretically it could be structured so that no funds could be directly stolen, but it seems unavoidable that some group of members could create a secret transaction that when published makes the most recent honest state not minable. 

Come to think of it tho, this doesn't actually solve the double spending problem. The fundamental issue is that if you have a subset of participants creating partitions like this, without the involvement of the whole group, its impossible for any subset of participants to know for sure that there isn't a double-spending partition amongst another set of members of the group.

On-chain bitcoin transactions prevent double spending by ensuring that everyone knows what outputs have been spent. Payment channels prevent double spending by ensuring that everyone that's part of the channel knows what the current channel state is. Any 3rd layer probably needs this exact property: everyone involved must know the state. So you should be able to create a partition when the whole group is live, and thereafter the members of that partition can use that partition without involving the rest of the group. I think that pattern can work to any level of depth. After thinking about this, I conjecture it might be a fundamental property of the double spending problem. All participants must be aware of the whole state otherwise the double spending problem exists for those who aren't aware of the whole state.

> this is forcing the pool/factory user to share their key materials with potentially lower trusted entities, if they don't self-host the tower instances.

I had a conceptual idea a while back (that I can't find at the moment) about offline lightning receiving. The concept is that each lightning node in a channel has two separate keys: a spending-key and a receiving-key. The spending-key must be used manually by the node owner to send payments, however the receiving-key can be given to an always-online service that can use that key only to either receive funds (ie update the state to a more favorable state). 

Right now with just a single-hot-key setup you need to trust your online system to only sign receiving transactions and would refuse to sign any proposed channel update not in the owner's favor. However, if the node was compromised all bets are off - the entire channel balance could be stolen. 

You could do this logic inside a hardware-wallet-like device that checks the proposed updates and verifies the new state is favorable before signing. This could go a long way to hardening lightning nodes against potential compromise. 

But if we go a step further, what if we enable that logic of ensuring the state is more favorable with an on-chain mechanism? This was where my idea got a bit hand wavy, but I think it could theoretically be done. The receiving-key would be able to sign receiving transactions that would only be valid when the most recent state signed by the spending-key is also included in the script sig in some way. Some Script would then validate that the receiving-key state being published is more favorable than the spending-key state in that transaction's outputs. You'd have a couple guarantees:

1. The usual guarantee that if the presented last spending-key state is actually out of date, the transaction could be overridden by the newer state in some way (eg eltoo style or punishment).
2. The state being published can be no worse than the presented spending-key state. Yes, your channel partner could compromise your receiving/routing node and then publish an out of date receiving-key channel state that's based on the most-recent spending-key state, but it would limit your losses to at most the amount of money you've received since the last time you manually signed a channel state with your spending-key. Because the always-online system empowered to receive does *not* have the spending-key, anyone that compromises that node can't spend and the damage is limited.

While less straight-forward than for receiving, in principle it seems like something similar could be done for routing (which would require presenting the state of multiple channels, and so has some additional complexities there I haven't worked out). 

This kind of thing might be a way of working around interactivity requirements of payment pools and the like. All participants still have to be aware of the whole state (eg of the payment pool), but this awareness can be delegated to a system you have limited trust in. Payment pool participants could delegate an always-online system empowered with a separate key to sign payment pool updates that user's state isn't changed for, allowing the payment pool to do its thing without exposing the user to hot-key vulnerabilities in that always-online system. Double spending is prevented because the user can access their always-online system to get the full payment pool state.

So in short, while I think there may be no way to fundamentally not require interactivity, there are workarounds that can limit how often full interactivity is needed as well as ways to make it easier to provide that full interactivity without compromising other aspects of each participant's security. 

On Thu, Apr 28, 2022 at 8:20 AM Antoine Riard via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote:
Hi,

This post recalls the noticeable interactivity issue encumbering payment pools and channel factories in the context of a high number of participants, describes how the problem can be understood and proposes few solutions with diverse trust-minizations and efficiency assumptions. It is intended to capture the theoretical bounds of the "interactivity issue", where technical completeness of the solutions is exposed in future works.

The post assumes a familiarity with the CoinPool paper concepts and terminology [0].

# The interactivity requirement grieving payment pools/channel factories

Payment pools and channel factories are multi-party constructions enabling to share the ownership of a single on-chain UTXO among many off-chain/promised balances. Payment pool improves on the channel factory construction fault-tolerance by reducing the number of balance outputs disclosed  on-chain to a single one in case of unilateral user exits.

However, those constructions require all the users to be online and exchange rounds of signatures to update the balance distribution. Those liveliness/interactivity requirements are increasing with the number of users, as there are higher odds of *one* lazzy/buggy/offline user stalling the pool/factory updates.

In echo, the design of LN was envisioned for a network of always-online/self-hosted participants, the early deployment of LN showed the resort to delegated channel hosting solutions, relieving users from the liveliness requirement. While the trust trade-offs of those solutions are significant, they answer the reality of a world made of unreliable networks and mobile devices.

Minding that observation, the attractiveness of pools/factories might be questioned.

# The interactivity requirement palliatives and their limits

Relatively straightforward solutions to lower the interactivity requirement, or its encumbered costs, can be drawn out. Pools/factories users could own (absolute) timelocked kick-out abilities to evict offline users who are not present before expiration.

E.g, let's say you have Alice, Bob, Caroll and Dave as pool participants. Each of them owns a Withdraw transaction to exit their individual balances at any time. Each user should have received the pre-signed components from the others guaranteeing the unilateral ability to publish the Withdraw.

A kick-out ability playable by any pool user could be provided by generating a second set of Withdraw transactions, with the difference of the nLocktime field setup to an absolute height T + X, where T is the height at which the corresponding Update transaction is generated and X the kick-out delay.  For this set of kick-out transactions, the complete witnesses should be fully shared among Alice, Bob, Caroll and Dave. That way, if Caroll is unresponsive to move the pool state forward after X, any one of Alice, Bob or Dave can publish the Caroll kick-out Withdraw transaction, and pursue operations without that unresponsive party.

While decreasing the interactivity requirement to the timelock delay, this solution is constraining the kicked user to fallback on-chain encumbering the UTXO set with one more entry.

Another solution could be to assume the widespread usage of node towers among the pool participants. Those towers would host the full logic and key state necessary to receive an update request and produce a user's approval of it. As long as one tower instance is online per-user, the pool/factory can move forward. Yet this is forcing the pool/factory user to share their key materials with potentially lower trusted entities, if they don't self-host the tower instances.

Ideally, I think we would like a trust-minimized solution enabling non-interactive, off-chain updates of the pool/factory, with no or minimal consumption of blockspace.

For the remainder of this post, only the pool use-case will be mentioned. Though, I think the observations/implications can be extended to factories as well.

# Non-interactive Off-chain Pool Partitions

If a pool update fails because of lack of online unanimity, a partition request could be exchanged among the online subset of users ("the actives"). They decide to partition the pool by introducing a new layer of transactions gathering the promised/off-chain outputs of the actives. The set of outputs belonging to the passive users remains unchanged.

The actives spend their Withdraw transactions `user_balance` outputs back to a new intermediate Update transaction. This "intermediate" Update transaction is free to re-distribute the pool balances among the active users. To guarantee the unilateral withdraw ability of a partitioned-up balance, the private components of the partitioned Withdraw transactions should be revealed among the set of active users.

E.g, let's say you have Alice, Bob, Caroll and Dave as pool participants. Pool is at state N, Bob and Dave are offline. Alice and Caroll agree to partition the pool, each of them owns a Withdraw transaction ready-to-be-attached on the Update transaction N. They generate a new partitioning Update transaction with two inputs spending respectively Alice's Withdraw transaction `user_balance` output and Caroll's Withdraw transaction `user-balance` output. From this partitioning Update transaction, two new second-layer Withdraw ones are issued.

Alice and Caroll reveal to each other the private components of their first-layer Withdraw transactions, allowing to publish the full branch : first-layer Update transaction, first-layer Withdraw transactions, second-layer partitioning Update transaction, second-layer partitioned Withdraw transaction. At that step, I think the partitioning should be complete.

Quickly, a safety issue arises with pool partitioning. A participant of the active set A could equivocate the partition state by signing another spend of her Withdraw transaction allocating her balance to an Update transaction of a "covert" set of active users B.

This equivocation exists because there is no ordering of the off-chain spend of the Withdraw transactions and any Withdraw transaction can be freely spent by its owner. This issue appears as similar to solving the double-spend problem.

Equivocation is a different case than multiple *parallel* partitions, where there is no intersection between the partitioned balances. The parallel partitions are still rooting from the same Update transaction N. I think the safety of parallel partitions is yet to be explored.

# Current solutions to the double-spend problem : Bitcoin base-layer & Lightning Network

Of course, the double-spend issue is already addressed on the Bitcoin base-layer due to nodes consensus convergence on the most-proof-of-work accumulated valid chain of blocks. While reorg can happen, a UTXO cannot be spent twice on the same chain. This security model can be said to be prophylactic, i.e an invalid block cannot be applied to a node's state and should be rejected.

The double-spend issue is also solved in its own way in payment channels. If a transaction is published, of which the correctness has been revoked w.r.t negotiated, private channel state, the wronged channel users must react in consequence. This security model can be said to be corrective, states updates are applied first on the global ledger then eventually corrected.

A solution to the pool partition equivocation issue appears as either based on a prophylactic one or a corrective security model.

Let's examine first, a reactive security model similar to LN-Penalty. At pool partition proposals, the owners of the partitioned-up Withdraw transactions could reveal a revocation secret enabling correction in case of wrongdoing (e.g single-show signatures). However, such off-chain revocation can be committed towards multiple sets of honest "active" users. Only one equivocating balance spend can succeed, letting the remaining set of honest users still be deprived of their expected partitioned balances.

E.g, let's say you have Alice, Bob, Caroll and Dave as pool participants. Alice contacts Bob to form a first partition, then Caroll to form a second one, then Dave to form a last one. If she is successful in that equivocation trick, she can *triple*-spend her balance against any goods or out-of-pool payments.

Assuming the equivocation is discovered once realized, Bob, Caroll and Dave are all left with a branch of transactions all including Alice's Withdraw one. However only one branch can be fully published, as a Withdraw transaction can be played only once following the pool semantic. Game-theory-wise, Bob, Caroll and Dave have an interest to enter in a fee race to be the first to confirm and earn the Alice balance spend.
 
The equivocation is only bounded by the maximal number of equivocating sets one can form, namely the number of pool users. However, correction can only be limited to the equivocated balance. Therefore, it appears that corrective security models in the context of multi-party are always producing an economic disequilibrium.

An extension of this corrective model could be to require off-pool collaterals locked-up, against which the revocation secret would be revealed at partition generation. However, this fix is limited to the collateral liquidity available. One collateral balance should be guaranteed for each potential victim, thus the collateral liquidity should be equal to the number of pool users multiplied by the equivocatable balance amount.

It sounds like a more economic-efficient security model of the pool partitioning can be established with a prophylactic technique.

# Trusted coordinator

A genuine solution could be to rely on a coordinator collecting the partition declaration and order them canonically. The pool partition candidates can then fetch them and decide their partitions acceptance decisions on that. Of course, the coordinator is trusted and can drop or dissimulate any partition, thus enabling partitioned balance equivocation.

# Trust-minimized : Partition Statements

A pool partition invalidity can be defined by the existence of two second-layer Update transactions at the same state number spending the same Withdraw transaction balance output. Each Update transaction signature can be considered as a "partition statement". A user wishing to join a partition should ensure there is no conflicting partition statement before applying the partition to her local state.

The open question is from where the conflict should be observed. A partition statement log could be envisioned and monitored by pool users before to accept any partition.

I think multiple partition statement publication spaces can be drawn out, with different trust-minization trade-offs.

# Publication space : Distributed Bulletin Boards

The set of "active" pool users could host their own boards of partition statements. They would coordinate on the statement order through a consensus algorithm (e.g Raft). For redundancy, a user can have multiple board instances. If a user falls offline, they can fetch the statement order from the other users boards.

However, while this solution distributes the trust across all the other users, it's not safe in case of malicious user coalitions agreeing among themselves to drop a partition statement. Therefore, a user catching up online can be feeded with an incorrect view of the existing partitions, and thus enter into an equivocated partition.

# Publication space : On-chain Authoritative Board

Another solution could be to designate an authoritative UTXO at pool setup. This UTXO could be spent by any user of the pool set (1-of-N) to a covenanted transaction sending back to a Taproot output with the same internal key. The Merkelized tree tweaked could be modified by the spender to stamp the partition statements as leaves hashes. The statement data is not committed in the leaves itself and the storage can be delegated to out-of-band archive servers.

E.g, let's say you have Alice, Bob, Caroll and Dave as pool participants. Alice and Bob decide to start a partition, they commit a hash of the partitioning Update transaction as a Taproot tree leaf and they spend the pool authoritative UTXO. They also send a copy of the Update transaction to an archive server.

At a later time, Alice proposes to Caroll to start a partition. Caroll follows the chain of transactions forming the on-chain authoritative board, she fetches the merkle branches and leaves data payload from an archive server, verifying the authenticity of the branches and payload. As Alice has already published a partition statement spending her Withdraw, Caroll should refuse the partition proposal.

Even if a pool user goes offline, she can recover the correct partition statement logs, as it has been committed in the chain from the authoritative UTXO. If the statement data is not available from servers, the pool user should not engage in partitions.

Assuming the spend confirms in every block, this solution enables partitions every 10min. The cost can be shared across pool instances, if the authoritative signers set is made of multiple pool instances signers sets. A threshold signature scheme could be used to avoid interactivity beyond the aggregated key setup. However, batching across pool instances increases the set of data to verify by the partition candidate users, which could be a grievance for bandwidth-constrained clients.

# Fiability of the Publication of Partition Statements

Whatever ends up being used as a partition statement log, there is still the question of the incentives of pool users to publish the partition statements. A malicious user could act in coalition with the equivocating entity to retain the publication of her partition statement. Thus, an honest user would only be aware of her own partition statement and accept the partition proposal from the will-be equivocating entity.

I think that leveraging covenants a revocation mechanism could be attached on any equivocating branch of transactions, allowing in the above case a single honest user to punish the publication. While a revocation mechanism does not work in case of multiple defrauded users, I believe the existence of a revocation mechanism makes the formation of malicious coalitions unsafe for their conjurers.

Indeed, any user entering in the coalition is not guaranteed to be blinded to other equivocating branches generated by the partition initiator. Therefore, the publication of a partition statement by everyone is holistically optimal to discover any equivocating candidate among the pool users.

Further research should establish the soundness of the partition statement publication game-theory.

# Writing the Partition Statements to a new Consensus Data Structure

To avoid a solution relying on game-theory, a new consensus data structure could be introduced to register and order the partition statements. This off-chain contract register could be a Merkle tree, where every leaf is a pool balance identified by a key. This register would be established on-chain at the same time the pool is set up.

Every time the pool is partitioned, the tree leaves would be updated with the partition statement committed to. Only one partition could be registered per user by state number. The publication branch would be invalid if it doesn't point back to the corresponding contract register tree entries. When the first-layer pool Update transaction is replaced, the tree should transition to a blank state too.

Beyond the high cost of yet-another softfork to introduce such consensus data structure, the size of the witness to write into the contract register could be so significant that the economic attractiveness of pool partitioning is decreased in consequence.

If you have read so far, thank you. And curious if anyone has more ideas or thoughts on  the high interactivity issue ?

Thanks Gleb for the review.

Cheers,
Antoine

[0] https://coinpool.dev/
_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev