* [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
@ 2020-06-11 8:53 Antoine Riard
2020-06-11 17:21 ` Jeremy
2020-06-12 8:39 ` ZmnSCPxj
0 siblings, 2 replies; 8+ messages in thread
From: Antoine Riard @ 2020-06-11 8:53 UTC (permalink / raw)
To: Bitcoin Protocol Discussion
[-- Attachment #1: Type: text/plain, Size: 20641 bytes --]
Hi list,
We (Gleb Naumenko + I) think that a wide range of second-layer protocols
(LN, vaults, inheritance, etc) will be used by average Bitcoin users. We
are interested in finding and addressing the privacy issues coming from the
unique fingerprints these protocols bring.
More specifically, we are interested in answering the following questions:
1. How bad are privacy leaks from on-chain txn of second-layer protocols
and how much is leaked via protocol-specific metadatas (LN domain names,
watchtowers, ...) ?
2. How to establish a list of Bitcoin fingerprints and their severity to
inform protocol designers and clarify threat models ?
3. What kind of sophisticated heuristics spies may use in the future ?
4. How to mitigate privacy leaks ? Should each protocol adopt a common
toolbox (scriptless scripts, taproot, ...) in its own way or should we
design a confidential-layer to wrap around all of them ?
5. How to make the solution usable (cheaper, easier to integrate, safer)
for a daily basis ?
We suggest CoinPool: a generic payment pool [0] as a solution to those
problems. Although the design we propose is somewhat a scaling solution, we
won't focus on this aspect. This work is rather an exploration of *how a
pool construction could serve as a TLS for Bitcoin, enhancing both on-chain
and off-chain privacy*.
### Motivation: cross-protocols privacy
It has always been a challenge to make the on-chain UTXO graph more
private. We all know the issues with cleartext amounts, the linkability of
inputs/outputs, and other metadatas. Combining with p2p-level spying
(transaction-to-IP mapping) or some other patterns leading to real-world
identities enable serious spying.
Protocols on top of Bitcoin (LN, vaults[1], complicated spending conditions
based on Miniscript, DLC [2] are even more vulnerable to spying because:
- each of them brings new unique fingerprint/metadata [3]
- known spying techniques against second-layer are currently limited to
trivial heuristics, but we can't assume spies will always this
unsophisticated
There is already a wiki list [4] attempting to cover all issues like that,
although maintaining it would be challenging considering privacy is a
moving target.
Let's consider this example: Alice is a well-known LN merchant with a node
tied to a domain name. She always directs the output of channel closing to
her vault address. If she has another vault address on-chain with the same
unique unlocking script (like a CSV timelock with a specific delta) this
can be leveraged to cluster her transactions. And since one of her
addresses is tied to a domain name, all her funds can now be linked to a
real-world identity.
In theory, one may use CoinJoin-like solutions to mask cross-protocol
on-chain transfers. Unfortunately, robust designs like CoinSwap depend on
timelocking coins, extensive use of the on-chain space, and paying fees to
provide sufficient privacy, as we explain further. These properties imply
we can't expect users to be using strong CoinSwaps by default.
That's why instead of specialized high-latency, high-chain-use
CoinJoin-style protocols, we propose CoinPool: a low-latency, generic
off-chain protocol used to be wrapped around any other protocol. CoinPool
is based on shared UTXO ownership. It may reasonably improve on-chain
privacy while avoiding latency and locked liquidity issues. CoinPool may
also reduce the on-chain use (thus, help to scale Bitcoin) if participants
cooperate sufficiently.
We do believe that CoinSwap and other CoinJoins are of interest, but we
have to consider the trade-offs and choose the best tool for a job to make
privacy usable with regards to user resources. We will compare CoinPool to
CoinSwap in more detail later in this write-up.
### Extra-motivation: on-chain scalability
Even though it's not the main focus of this proposal, we also want to
mention that since CoinPool is a payment pool, it helps with on-chain
scalability. More specifically:
1. Shared UTXO ownership allows to represent many outputs as one, reducing
the UTXO set in size.
2. The CoinPool design enables off-chain transfers within the pool, helping
to save the block space by committing fewer transactions on-chain.
3. CoinPool provides decent support for batching activities from different
users, also helping to have fewer individual transactions on-chain.
Since the CoinPool provides scalability benefits, users will be even
incentivized to join CoinPools due to the conservative chain resources
usage and such enjoy privacy as a side-effect.
### CoinPool design
A CoinPool must satisfy the following *non-interactive any-order
withdrawal* property: at any point in time and any possible sequence of
previous CoinPool events, a participant should be able to move their funds
from the CoinPool to any address the participant wants without cooperation
with other CoinPool members.
The state of a CoinPool is represented by one on-chain UTXO (a funding
multisig of all pool participants) and a set of transactions stored by the
participants along with signatures allowing to spend that UTXO. This UTXO
is a Taproot output, where the leaves in the Merkle tree represent pool
participants.
#### Transactions
A CoinPool UTXO can be spent by two types: Pool_Tx and Split_Tx.
A Pool_Tx enables cooperatives updates of the pool, e.g a participant
exiting the pool or off-chain internal transfers. This transaction is used
to spend the key branch of the Taproot tree of the CoinPool UTXO.
Signatures for a Pool_Tx should be exchanged "on-demand", the moment
parties decide to update the CoinPool state collaboratively, In practice,
this would happen upon a request of a pool participant.
A Split_Tx enables a unilateral exit from the CoinPool, in case it's not
possible to use a cooperative Pool_Tx path. This transaction spends the
UTXO via the Merkle branch into two outputs:
- a _withdraw_ output paying to the pool participant who initiated a
transaction
- a _recursive_ output paying to the new instance of a CoinPool, which
contains all the same participants except the one who just withdrew
The design of the unilateral Split_Tx depends on what can be achieved with
Bitcoin Script. The main challenge is to enforce the second output of the
Split_tx s that the participant who exists can't take all the funds
unilaterally. We will talk more about the updates to Bitcoin Script which
would allow more advanced pools later (Scaling section).
For now, we will *focus on the Script capabilities of today*, per which
spending a Split_Tx requires signatures from all pool participants. Since
Split_Tx is a unilateral exit, parties are required to exchange signatures
for *any possible state of the pool* in advance, to handle the *any-order
withdraw* requirement. The exchange should happen when a pool is created.
#### Operations
There are three types of operations against a CoinPool: create, update,
withdraw.
Per *creation*, participants agree on a pool policy and commit inputs to a
funding transaction by sending a corresponding signature, created in a
secure "atomic" way (so that their funds can't be taken if other pool
participants are unresponsive). Participants also exchange their signatures
which would allow any participant to exit at any given time via a Split_Tx.
Per *update*, participants agree on a new coin distribution within the pool
tree. They can aggregate and split leaves of the tree, or rotate a target
output of a given leaf. E.g, a participant may choose to redirect coins to
a new pool right from the old pool and ask all the parties to agree on this
update. The previous state should then be revoked either via sequence
number (Eltoo) or adding the latest state as a child transaction from any
previous Pool_tx.
Per *withdraw*, a participant may submit either a Pool_Tx (after asking all
the parties for their signatures) or a Split_Tx (unilaterally). After that,
a new UTXO of the CoinPool would consist of all the remaining participants.
As an optimization, updates and withdrawals may aggregate changes to
multiple leaves within one transaction. A CoinPool may also optionality
allow new participants to *join* a pool on-the-fly, although trade-offs
should be considered.
#### Transaction Tree illustrated
We illustrate a CoinPool transaction tree with 3 leaves below. We use an
obvious optimization: if there are only 2 leaves left, the last transaction
doesn't have to commit to a new tree [5].
Funding_Tx
|
|
[Taproot_T]
|
___________________ | ______________________________________
|
|
|
|
|
|
[leaf_A]
|
^
|
|
|
Split_TxA
___________________ |________________________
/
\
|
|
/
\
|
|
/
\
[leaf_B]
[leaf_C]
[withdraw_A]
[Taproot T']
^
^
^
|
|
|
Split_TxB
Split_TxC
Pool_Tx /
\
/ \
/ \
/
\
/ \
/ \ [withdraw_B]
[Taproot T'']
[withdraw_C] [Taproot'']
/
\
^
^
[withdraw_B]
[withdraw_C] |
|
Pool_Tx
Pool_tx
/
\
/ \
/
\
/ \
[withdraw_A]
[withdraw_C]
[withdraw_A] [withdraw_B]
### Scaling the Pool and the Any-Order problem
A conservative CoinPool indeed does not scale well: it requires generating
pruned Merkle Tree encumbering the _recursive_ output for any combination
of withdrawals at pool creation. For a tree of Alice, Bob and Carol, they'd
have to build (A,B,C), (A,C,B), (B,A,C), (B,C,A), (C,A,B), (C,B,A) trees.
Since the complexity is quasi-factorial, the conservative CoinPool design
is impractical for more than 10 leaves.
Instead of operating over every possible alternative statically (via
pre-signing *every* combination), the protocol may rely on the script
interpreter to do it dynamically, only enforcing an effective path among
alternatives.
A new primitive to enable this behavior can be implemented as an
accumulator, i.e a space-efficient cryptographic set representation
supporting testing for inclusion and element deletion.
Implementation of this delete-only accumulator can be done by introducing
or combining already-proposed primitives like a new sighash flag, using a
Taproot tree as an accumulator, a committed bitset with templated
operations, etc, ... The exact design is left for future research.
This primitive would enable re-committing the updated tree on the
_recursive_ output, that way preserving balances of other participants,
independently of order of withdrawals.
Such _recursive_ output needs to be spendable by remaining Split_txn. These
transactions are pre-signed and their inputs commit to the parent txid. To
alleviate this issue, Split_tx should be signed through SIGHASH_NOINPUT,
therefore enabling _recursive_ output. The spending Tapscript must be
present among the set of Taproot tree leaves.
### Intra-pool communication and pool policies
The CoinPool design assumes participants have to communicate regularly to
exchange transaction templates and signatures. It happens almost every time
a state of the pools is modified: pool creation, pool update, and
cooperative withdrawal. Selecting a communication channel (a mixnet,
centralized servers, publication boards, ...) should be done considering
the threat model, the cost, the expected latency.
Every instance of a CoinPool may be public (available for new participants
to join at any time), private (available to join via some out-of-band
communication), or something in the middle (based on anti-Sybil measures we
will discuss later).
### Protocol rebinding
Since the conservative CoinPool design every unilateral exit via Split_Tx
should be signed by all the parties in advance, every participant joining
the pool should define in advance which address the coins will be directed
to in a unilateral case.
However, participants may want to use their CoinPool funds to move their
pool funds to a new scriptPubkey (for example, to open a new LN channel).
To avoid using an intermediate single-address on-chain transaction for
these cases, participants should be able to rotate the Split_Tx output.
To avoid asking other participants of the CoinPool to sign a new update, a
multisig signature covering the Split_Tx and enforcing covenant semantic
may be signed with SIGHASH_SINGLE. That way, at any-time Alice can finalize
her Split_Tx by adding a new output and signing her with SIGHASH_ALL.
Since unilateral withdrawal from CoinPool is time-locked, integration
time-sensitive off-chain protocols (e.g, LN or DLC) must be done with extra
care.
Lastly, the limitations of the current mempool design should be taken into
account while using CoinPools, so that issues like mempool pinning [6] are
not critical.
### Security/Privacy model
Similarly to CoinJoins, CoinPool provides privacy by breaking payment
sender/receiver linkability for an on-chain observer.
Common-input-ownership, address reuse, change address heuristics can't be
leveraged. A spy is forced to commit/lock funds to the pool, and
potentially overcome ant-Sybil measures. Internal CoinPool transfers also
remain private for an external observer.
The exact on-chain privacy efficiency of a given CoinPool depends on two
factors: intra-pool activities and exit activities. If the parties are
cooperative, intra-pool transfers never leave a footprint on-chain. Exit
activities always hit the chain, but if output rebinding is available, the
funds can be sent right to the target receiver outside the pool (e.g, cold
storage or even another pool), making on-chain analysis much more difficult
than what happens with regular transactions today.
Since it's possible for an attacker to join a pool, we have to consider
extra Sybil-resistance (beyond just depositing coins). Extra
Sybil-resistance may include a lock on withdrawal. This lock should not
limit intra-pool updates, so that honest users are not limited.
Additionally, the solutions suggested for CoinJoins may be used (fidelity
bonds, PoDle, etc).
### User Requirements
CoinPool introduces two requirements on users: one for security, one for
pool performance.
It requires persistent storage from the user. Since a unilateral withdrawal
assumes transmitting signatures received from other participants
beforehand, these signatures, corresponding Taproot output and Merkle
branches should not be lost or corrupted, otherwise a participant won't be
able to exit the pool without cooperation.
It also requires hot access to the signing keys, i.e being online to sign
updates which introduces a higher security risk.
These requirements are similar to the requirements for LN and vault
constructions, so we believe that the burden on a CoinPool participant is
reasonable as long as we consider second-layer protocols practical.
### Comparing to CoinSwap
A CoinSwap was recently proposed as a next step for on-chain bitcoin
privacy [6]. We will compare CoinPool to CoinSwap in terms of high-level
properties, because there are no deployed CoinSwaps yet.
CoinSwap enables privacy-enhanced (in terms of on-chain footprint)
transactions, executed as a non-custodial atomic "trade" between two
parties willing to send someone else (not each other) coins at the same
time.
A CoinSwap between two parties cost at least two on-chain transactions.
However, since this minimal design leaks privacy due to the amount
correlation, more advanced CoinSwap constructions should be used, and they
would be even more costly.
The privacy-efficiency of CoinSwaps is thus defined by fees and time-value
parameters. For these reasons, the lower security requirements are likely
to be most-widely picked-up by thrift users. Participation in a CoinPool,
however, costs of a funding transaction fee (shared across all
participants), and a cost of the withdrawal (either unilateral or
cooperative). Off-chain updates within a pool are free.
With regards to linkability, CoinSwap breaks the UTXO ownership graph,
CoinPool has similar properties the moment the coins are withdrawn, but the
off-chain events inside the pool are likely to obfuscate it even further.
Every participant can make direct payments during pool lifetime, breaking
mapping between committed inputs and withdrawn outputs.
CoinPool output will be part of the broader taproot user set, therefore any
single-owned output may be confused as a pool one, hindering further
on-chain analysis even for non-CoinPool users.
With regards to linkability, CoinSwap completely breaks the link between
inputs and outputs, while CoinPool just largely obfuscates the link
(similarly to CoinJoins). CoinPool is capable of breaking the link for
those payments happening off-chain (e.g, simple transfers within the pool).
With regards to requirements, beyond requiring online keys, practical
CoinPools require new base layers primitives, namely Taproot,
SIGHASH_NOINPUT and delete-only accumulators. CoinSwap is deployable today,
although the client software should be built.
With regards to malicious participants, CoinPool provides some privacy (in
terms of on-chain analysis) if at least one other participant is honest,
which is the same assumption as CoinSwap. More specifying spying cost
analysis can be made when comparing particular configurations of a CoinSwap
and a CoinPools. We invite the community to develop a better model of
privacy adversaries, their resources and leverages to refine
privacy-enhancing protocols comparisons.
Although we claim that different properties of CoinSwaps and CoinPools make
them better for different goals, they can benefit from each other: e.g,
both of them may rely on Sybil-resistance mechanisms or federated message
boards for cooperation.
### Conclusion
We propose CoinPool: a payment pool construction to improve privacy against
on-chain data analysis. More specifically, it helps to hide the unique
footprint associated with the use of second-layer protocols.
We attempted to design CoinPools to make them usable for daily activities,
as opposed to specialized CoinJoin-style solutions. They usually don't
require paying fees and don't use the on-chain space *per-activity*. If
they are widely used, they can also help with on-chain scalability,
although we don't cover this aspect in detail.
CoinPool is a UTXO representing a Taproot tree, in which the leaves
represent the spending conditions for coins in the pool. We designed
CoinPool around the *non-interactive any-order withdrawal* requirement.
In the long-term, CoinPool appears as a good candidate for a scalable,
used-by-default privacy-enhancing technology. We emphasize there are
several challenges deploying CoinPools, the biggest one being scalability.
Making them practical requires introducing new on-chain primitives.
Thanks to the wider privacy-community and on which of their work this
depends heavily.
Thanks to the reviewers.
Cheers,
Gleb + Antoine
[0] AFAIK, payment pools have been suggested by Greg Maxwell, although I
couldn't find any written evidence. The only description I know have been
made to me by Dave Harding during a BitDevs meetup. Yes I'm old enough to
have known when meatspace Bitcoin meetup was a thing.
<https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017793.html>
[1]
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017793.html
[2] https://github.com/discreetlogcontracts/dlcspecs/
[3] On protocol usage leak at the on-chain level see
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-February/017633.html,
for an illustration see
https://b10c.me/mempool-observations/1-locktime-stairs/
[4] https://en.bitcoin.it/Privacy
[5] . A gist backup if it doesn't survive formatting :
https://gist.github.com/ariard/ab1e4c3a85e4816be21ee0e0f925e86b A common
notation to describe transactions tree and their scripts and ease reviewers
to verify their correctness would be great. Otherwise it's hard to gauge
the correctness of this kind of new protocol.
[6] https://bitcoinops.org/en/newsletters/2020/04/29/
[-- Attachment #2: Type: text/html, Size: 33674 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-11 8:53 [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy Antoine Riard
@ 2020-06-11 17:21 ` Jeremy
2020-06-12 23:45 ` Antoine Riard
2020-06-12 8:39 ` ZmnSCPxj
1 sibling, 1 reply; 8+ messages in thread
From: Jeremy @ 2020-06-11 17:21 UTC (permalink / raw)
To: Antoine Riard, Bitcoin Protocol Discussion
[-- Attachment #1: Type: text/plain, Size: 6383 bytes --]
Stellar work Antoine and Gleb! Really excited to see designs come out on
payment pools.
I've also been designing some payment pools (I have some not ready code I
can share with you guys off list), and I wanted to share what I learned
here in case it's useful.
In my design of payment pools, I don't think the following requirement: "A
CoinPool must satisfy the following *non-interactive any-order withdrawal*
property: at any point in time and any possible sequence of previous
CoinPool events, a participant should be able to move their funds from the
CoinPool to any address the participant wants without cooperation with
other CoinPool members." is desirable in O(1) space. I think it's much
better to set the requirement to O(log(n)), and this isn't just because of
wanting to use CTV, although it does help.
Let me describe a quick CTV based payment pool:
Build a payment pool for N users as N/2 channels between participants
created in a payment tree with a radix of R, where every node has a
multisig path for being used as a multi-party channel and the CTV branch
has a preset timeout. E.g., with radix 2:
Channel(a,b,c,d,e,f,g,h)
/ \
Channel(a,b,c,d)
Channel(e,f,g,h)
/
\ / \
Channel(a,b) Channel(c,d) Channel(e,f)
Channel(g,h)
All of these channels can be constructed and set up non-interatively using
CTV, and updated interactively. By default payments can happen with minimal
coordination of parties by standard lightning channel updates at the leaf
nodes, and channels can be rebalanced at higher layers with more
participation.
Now let's compare the first-person exit non cooperative scenario across
pools:
CTV-Pool:
Wait time: Log(N). At each branch, you must wait for a timeout, and you
have to go through log N to make sure there are no updated states. You can
trade off wait time/fees by picking different radixes.
TXN Size: Log(N) 1000 people with radix 4 --> 5 wait periods. 5*4 txn size.
Radix 20 --> 2 wait periods. 2*20 txn size.
Accumulator-Pool:
Wait Time: O(1)
TXN Size: Depending on accumulator: O(1), O(log N), O(N) bits. Let's be
favorable to Accumulators and assumer O(1), but keep in mind constant may
be somewhat large/operations might be expensive in validation for updates.
This *seems* like a clear win for Accumulators. But not so fast. Let's look
at the case where *everyone* exits non cooperatively from a payment pool.
What is the total work and time?
CTV Pool:
Wait time: Log(N)
Txn Size: O(N) (no worse than 2x factor overhead with radix 2, higher
radixes dramatically less overhead)
Accumulator Pool:
Wait time: O(N)
Txn Size: O(N) (bear in mind *maybe* O(N^2) or O(N log N) if we use an
sub-optimal accumulator, or validation work may be expensive depending on
the new primitive)
So in this context, CTV Pool has a clear benefit. The last recipient can
always clear in Log(N) time whereas in the accumulator pool, the last
recipient has to wait much much longer. There's no asymptotic difference in
Tx Size, but I suspect that CTV is at least as good or cheaper since it's
just one tx hash and doesn't depend on implementation.
Another property that is nice about the CTV pool style is the bisecting
property. Every time you have to do an uncooperative withdrawal, you split
the group into R groups. If your group is not cooperating because one
person is permanently offline, then Accumulator pools *guarantee* you need
to go through a full on-chain redemption. Not so with a CTV-style pool, as
if you have a single failure among [1,2,3,4,5,6,7,8,9,10] channels (let's
say channel 8 fails), then with a radix 4 setup your next steps are:
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,X,9,10]
[1,2,3,4] [5,6,7,X] [9,10]
[1,2,3,4] 5 6 7 X [9,10]
So you only need to do Log(N) chain work to exit the bad actor, but then it
amortizes! A future failure (let's say of 5) only causes 5 to have to close
their channel, and does not affect anyone else.
With an accumulator based pool, if you re-pool after one failure, a second
failure causes another O(N) work. So then total work in that case is
O(N^2). You can improve the design by making the evict in any order option
such that you can *kick out* a member in any order, that helps solve some
of this nastiness (rather than them opting to leave). But I'm unclear how
to make this safe w.r.t. updated states. You could also allow, perhaps, any
number of operators to simultaneously leave in a tx. Also not sure how to
do that.
Availability:
With CTV Pools, you can make a payment if just your immediate conterparty
is online in your channel. Opportunistically, if people above you are
online, you can make channel updates higher up in the tree which have
better timeout properties. You can also create new channels, binding
yourself to different parties if there is a planned exit.
With Accumulator pools, you need all parties online to make payments.
Cooperation Case:
CTV Pools and Accumulator pools, in a cooperative case, both just act like
a N of N multisig.
Privacy:
Because Accumulator pools always require N signers, it's possible to build
a better privacy model where N parties are essentially managing a chaumian
ecash like server for updates, giving good privacy of who initiated
payments. You *could* do this with CTV pools as well, but I expect users to
prefer making updates at the 2 party channel layer for low latency, and to
get privacy benefits out of the routability of the channels and ability to
connect to the broader lightning network.
Technical Complexity:
Both protocols require new features in Bitcoin. CTV is relatively simple, I
would posit that accumulators + sighashnoinput are relatively not simple.
The actual protocol design for CTV pools is pretty simple and can be
compatible with LN, I already have a rudimentary implementation of the
required transactions (but not servers).
Interactivity:
In both designs, the payment pool can be created non-interactively. This is
*super* important as it means third parties (e.g., an exchange) can
withdraw users funds *into* a payment pool.
Thanks for reading!
Jeremy
--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>
[-- Attachment #2: Type: text/html, Size: 16564 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-11 8:53 [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy Antoine Riard
2020-06-11 17:21 ` Jeremy
@ 2020-06-12 8:39 ` ZmnSCPxj
2020-06-13 0:28 ` Antoine Riard
1 sibling, 1 reply; 8+ messages in thread
From: ZmnSCPxj @ 2020-06-12 8:39 UTC (permalink / raw)
To: Antoine Riard, Bitcoin Protocol Discussion
Good morning Antoine and Gleb,
I have not studied the proposal in close detail yet, but anyway, my main takeaway roughly is:
* The core of CoinPool is some kind of multiparticipant (N > 2) offchain update mechanism (Decker-Wattenhofer or Decker-Russell-Osuntokun).
* The output at each state of the update mechanism is some kind of splitting construction (which I have not studied in detail).
* At each update of the state, all participants must sign off on the new state.
It seems to me that it would be possible to use a [WabiSabi protocol](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-June/017969.html) during negotiation of a new state.
Now, WabiSabi is a client-server protocol.
As all participants in the CoinPool are needed in order to ratify each new state anyway, they can simply elect one of their number by drawing lots, to act as server for a particular state update.
Then the participants can operate as WabiSabi clients.
Each participant registers the outputs they currently own in the current state, getting credentials that sum up to the correct value.
Then, during the WabiSabi run, they can exchange credentials among the participants in order to perform value transfers inside the WabiSabi construction.
Then, at output registration, they register new outputs to put in the next state of the CoinPool.
In order to hide transfers from the elected WabiSabi server, participants can maintain two coins in every state, and move coins randomly across the two coins they own at each state update, in order to hide "real" transfers from the elected server.
Then, after output registration, the participants ratify the new state by signing off on the new state and revoking the previous state, using the update mechanism.
Of course, we should note that one desired feature for CoinPool in the original proposal is that a participant can exit, and the CoinPool would still remain valid, but only for the remaining participants.
This is arguably a mild privacy leak: every other participant now knows how much that particular participant took out from the CoinPool.
Indeed, from what I can understand, in order to properly set up the splitting transactions in the first place, at each state every participant needs to know how much each other participant actually owns in the CoinPool at that point in time.
To hide how much each participant owns in the CoinPool from other participants, we would have to make unilateral closes expose all the current outputs, without trying to identify *which* participant exited the CoinPool, and thus preventing anyone else from figuring out exactly how much each *other* participant actually owns in the CoinPool on exit.
That way, output addresses can be to fresh pseudonyms of the participant, removing all linkages of participant to amount they own, and each participant can maintain multiple outputs per state for their own purposes and to mildly obscure exactly how much they own in total.
If we drop that feature (of being able to exit a participant without closing the *entire* CoinPool), of course, we need to mildly disincentivize a participant closing unilaterally for trivial reasons.
We can do this by using `SIGHASH_ANYPREVOUT` to force whoever performs a unilateral close of the CoinPool to pay the onchain fees involved, so that it would have to be a good reason indeed to perform a unilateral close.
Regards,
ZmnSCPxj
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-11 17:21 ` Jeremy
@ 2020-06-12 23:45 ` Antoine Riard
0 siblings, 0 replies; 8+ messages in thread
From: Antoine Riard @ 2020-06-12 23:45 UTC (permalink / raw)
To: Jeremy; +Cc: Bitcoin Protocol Discussion
[-- Attachment #1: Type: text/plain, Size: 14563 bytes --]
Hi Jeremy,
For the records, I didn't know between Greg and you was at the origin of
payment pools. Thanks for your pioneer work here, obviously this draws
inspiration from OP_CTV use cases and Channel Factories works, even if we
picked up different assumptions and tried to address another set of issues.
With regards to scalability, I hit it on my own while inquiring
covenanted-Bitcoin contracts for international trade. I mentioned the
any-order issue on such multi-party complex contracts in a talk last summer
(https://github.com/ariard/talk-slides/blob/master/advanced-contracts.pdf).
> All of these channels can be constructed and set up non-interatively using
> CTV, and updated interactively. By default payments can happen with
minimal
> coordination of parties by standard lightning channel updates at the leaf
> nodes, and channels can be rebalanced at higher layers with more
> participation.
Side review note on OP_CTV: I think it would be great to define
non-interactivity better, namely at least between 3 phases: establishment,
operation, closing.
Even OP_CTV protocols assume interactivity at establishment, at least 1) to
learn payees pubkeys endpoint (and internal leaves pubkeys if you want
update at operation) 2) validate transaction tree correctness between
participants.
At operation, it depends if participants want to dynamically rebalance
value across channels or not. If you desire dynamically rebalancing, assume
internal leaves scriptpubkeys are (multisig-all OR OP_CTV'ed merkle_tree).
Using OP_CTV is a saving in message rounds for every constant expression
across tree updates.
At closing, depends again if participants have committed update keys or
not. If dynamic update, you can prune the whole tree and just commit final
balances onchain, either with a O(N) fan-out transaction (N outputs) or a
O(log(N)) congestion tree (N transactions).
So I would say the originality of a hashchain covenant like OP_CTV is to
provide onchain *immutability* (unforgeability?) of the offchain
transaction tree and thus provides instant finality to payees. You can get
the same semantic with off-chain covenant, pre-signed set of transactions,
assuming more communications rounds and performance hit.
That said, IMO, immutability comes with a security trade-off, namely if any
payout key committed in your OP_CTV tree gets compromised your funds are at
stake. And you can't update the tree anymore at the root to rotate keys. I
think this should be weighted by anyone designing covenant protocols,
especially vaults.
> I don't think the following requirement: "A
> CoinPool must satisfy the following *non-interactive any-order withdrawal*
> property: at any point in time and any possible sequence of previous
> CoinPool events, a participant should be able to move their funds from the
> CoinPool to any address the participant wants without cooperation with
> other CoinPool members." is desirable in O(1) space.
With current design (Pool_tx+Split_tx) it's O(2) space. Pool_tx is similar
to a commitment tx and thus enables off-chain novation of pool distribution.
> Let's be favorable to Accumulators and assume O(1), but keep in mind
constant may
> be somewhat large/operations might be expensive in validation for updates.
Using a Merkle Tree as an accumulator should be constant-size in space, but
likely it has to be O(log(N) in computation (N set elements). This overhead
in computation should be accounted for in accumulator sigops to avoid
network validation resources free-riding, but I think it's a better
trade-off minimizing chain footprint.
> So in this context, CTV Pool has a clear benefit. The last recipient can
> always clear in Log(N) time whereas in the accumulator pool, the last
> recipient has to wait much much longer. There's no asymptotic difference
in
> Tx Size, but I suspect that CTV is at least as good or cheaper since it's
> just one tx hash and doesn't depend on implementation.
Yes I agree CTV pool performs better in the worst-case scenario. In my
opinon what we should really look on is the probability of withdrawal
scenarios. I see 2 failure cases:
* a pool participant being offline, thus halting the pool
* a pool participant with external protocol requirement to fulfill, like a
HTLC to timeout onchain
With regards to 1) we assume that watchtower infra are likely to become
ubiquitous in the future (if you want a secure LN experience), so user
uptime should be near to 100%. Of course, it's a new architecture which
comes with trade-offs, but interesting to explore.
With regards to 2) as of today channel-failure-rate (like unilateral close)
it's still quite important (30% IIRC) so it plays in favor of OP_CTV pool
but in the future I expect single-digit
therefore making CoinPool far more competitive. Do we envision protocol
more time-sensitive than LN in the future (atomic swaps...) ? Hard to gauge.
Do you see other ways to refine model, like integrating out-of-pool
liquidity needs rate ?
Note, I think for OP_CTV tree, increasing radix increases cooperation
requirement and failure, so there should be optimum somewhere.
> If your group is not cooperating because one
> person is permanently offline, then Accumulator pools *guarantee* you need
> to go through a full on-chain redemption.
That's right, that's a current shortcoming of this strawman design, I think
you can avoided by adding some timelocks, "if Alice doesn't anwser after X
days, initiate a kick-out", thus avoiding full onchain unrolling.
> But I'm unclear how
> to make this safe w.r.t. updated states. You could also allow, perhaps,
any
> number of operators to simultaneously leave in a tx. Also not sure how to
> do that.
I'm still thinking on this too, especially in LN-context, ideally you do
want the same thing to kick-out a HTLC of your HTLC-tree while preserving
the rest of them. Technically it works, if you assume CSV delay on the
commitment/pool_tx and locktime on the HTLC, which is Eltoo tradeoff.
> With Accumulator pools, you need all parties online to make payments.
I think that our shortcoming here, but technically with protocol rebinding
on any withdrawal output of Split_tx, you can have M-of-N channels between
pool participants. Also we should aim to support any kind of protocol at
the leaves.
> Because Accumulator pools always require N signers, it's possible to build
> a better privacy model where N parties are essentially managing a chaumian
> ecash like server for updates, giving good privacy of who initiated
> payments.
Yes that what I've in mind is something with blind signatures or any
obfuscation of pool tree construction as privacy optimization. Still you
will leak value weight of leaves to an in-pool observer.
> Both protocols require new features in Bitcoin. CTV is relatively simple,
I
> would posit that accumulators + sighashnoinput are relatively not simple.
I agree design, review, deployment costs are an order of magnitude higher.
That said they are more powerful primitives which would cover use cases
beyond pools. A concern with OP_CTV is if we want semantic extensions we
may realize they don't rank that well compared to more generic "base"
primitives.
> In both designs, the payment pool can be created non-interactively. This
is
> *super* important as it means third parties (e.g., an exchange) can
> withdraw users funds *into* a payment pool.
See my point above, I think we need a better definition of
non-interactivity.
Thanks for the high-quality review of CoinPool !
Antoine
Le jeu. 11 juin 2020 à 13:21, Jeremy <jlrubin@mit.edu> a écrit :
> Stellar work Antoine and Gleb! Really excited to see designs come out on
> payment pools.
>
> I've also been designing some payment pools (I have some not ready code I
> can share with you guys off list), and I wanted to share what I learned
> here in case it's useful.
>
> In my design of payment pools, I don't think the following requirement: "A
> CoinPool must satisfy the following *non-interactive any-order withdrawal*
> property: at any point in time and any possible sequence of previous
> CoinPool events, a participant should be able to move their funds from the
> CoinPool to any address the participant wants without cooperation with
> other CoinPool members." is desirable in O(1) space. I think it's much
> better to set the requirement to O(log(n)), and this isn't just because of
> wanting to use CTV, although it does help.
>
> Let me describe a quick CTV based payment pool:
>
> Build a payment pool for N users as N/2 channels between participants
> created in a payment tree with a radix of R, where every node has a
> multisig path for being used as a multi-party channel and the CTV branch
> has a preset timeout. E.g., with radix 2:
>
> Channel(a,b,c,d,e,f,g,h)
> / \
> Channel(a,b,c,d)
> Channel(e,f,g,h)
> /
> \ / \
> Channel(a,b) Channel(c,d) Channel(e,f)
> Channel(g,h)
>
>
> All of these channels can be constructed and set up non-interatively using
> CTV, and updated interactively. By default payments can happen with minimal
> coordination of parties by standard lightning channel updates at the leaf
> nodes, and channels can be rebalanced at higher layers with more
> participation.
>
>
> Now let's compare the first-person exit non cooperative scenario across
> pools:
>
> CTV-Pool:
> Wait time: Log(N). At each branch, you must wait for a timeout, and you
> have to go through log N to make sure there are no updated states. You can
> trade off wait time/fees by picking different radixes.
> TXN Size: Log(N) 1000 people with radix 4 --> 5 wait periods. 5*4 txn
> size. Radix 20 --> 2 wait periods. 2*20 txn size.
>
> Accumulator-Pool:
> Wait Time: O(1)
> TXN Size: Depending on accumulator: O(1), O(log N), O(N) bits. Let's be
> favorable to Accumulators and assumer O(1), but keep in mind constant may
> be somewhat large/operations might be expensive in validation for updates.
>
>
> This *seems* like a clear win for Accumulators. But not so fast. Let's
> look at the case where *everyone* exits non cooperatively from a payment
> pool. What is the total work and time?
>
> CTV Pool:
> Wait time: Log(N)
> Txn Size: O(N) (no worse than 2x factor overhead with radix 2, higher
> radixes dramatically less overhead)
>
> Accumulator Pool:
> Wait time: O(N)
> Txn Size: O(N) (bear in mind *maybe* O(N^2) or O(N log N) if we use an
> sub-optimal accumulator, or validation work may be expensive depending on
> the new primitive)
>
>
> So in this context, CTV Pool has a clear benefit. The last recipient can
> always clear in Log(N) time whereas in the accumulator pool, the last
> recipient has to wait much much longer. There's no asymptotic difference in
> Tx Size, but I suspect that CTV is at least as good or cheaper since it's
> just one tx hash and doesn't depend on implementation.
>
> Another property that is nice about the CTV pool style is the bisecting
> property. Every time you have to do an uncooperative withdrawal, you split
> the group into R groups. If your group is not cooperating because one
> person is permanently offline, then Accumulator pools *guarantee* you need
> to go through a full on-chain redemption. Not so with a CTV-style pool, as
> if you have a single failure among [1,2,3,4,5,6,7,8,9,10] channels (let's
> say channel 8 fails), then with a radix 4 setup your next steps are:
> [1,2,3,4,5,6,7,8,9,10]
> [1,2,3,4,5,6,7,X,9,10]
> [1,2,3,4] [5,6,7,X] [9,10]
> [1,2,3,4] 5 6 7 X [9,10]
>
> So you only need to do Log(N) chain work to exit the bad actor, but then
> it amortizes! A future failure (let's say of 5) only causes 5 to have to
> close their channel, and does not affect anyone else.
>
> With an accumulator based pool, if you re-pool after one failure, a second
> failure causes another O(N) work. So then total work in that case is
> O(N^2). You can improve the design by making the evict in any order option
> such that you can *kick out* a member in any order, that helps solve some
> of this nastiness (rather than them opting to leave). But I'm unclear how
> to make this safe w.r.t. updated states. You could also allow, perhaps, any
> number of operators to simultaneously leave in a tx. Also not sure how to
> do that.
>
>
>
> Availability:
> With CTV Pools, you can make a payment if just your immediate conterparty
> is online in your channel. Opportunistically, if people above you are
> online, you can make channel updates higher up in the tree which have
> better timeout properties. You can also create new channels, binding
> yourself to different parties if there is a planned exit.
>
> With Accumulator pools, you need all parties online to make payments.
>
>
> Cooperation Case:
> CTV Pools and Accumulator pools, in a cooperative case, both just act like
> a N of N multisig.
>
> Privacy:
> Because Accumulator pools always require N signers, it's possible to build
> a better privacy model where N parties are essentially managing a chaumian
> ecash like server for updates, giving good privacy of who initiated
> payments. You *could* do this with CTV pools as well, but I expect users to
> prefer making updates at the 2 party channel layer for low latency, and to
> get privacy benefits out of the routability of the channels and ability to
> connect to the broader lightning network.
>
>
> Technical Complexity:
> Both protocols require new features in Bitcoin. CTV is relatively simple,
> I would posit that accumulators + sighashnoinput are relatively not simple.
>
> The actual protocol design for CTV pools is pretty simple and can be
> compatible with LN, I already have a rudimentary implementation of the
> required transactions (but not servers).
>
>
> Interactivity:
>
> In both designs, the payment pool can be created non-interactively. This
> is *super* important as it means third parties (e.g., an exchange) can
> withdraw users funds *into* a payment pool.
>
>
> Thanks for reading!
>
> Jeremy
>
>
>
> --
> @JeremyRubin <https://twitter.com/JeremyRubin>
> <https://twitter.com/JeremyRubin>
>
>
[-- Attachment #2: Type: text/html, Size: 25256 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-12 8:39 ` ZmnSCPxj
@ 2020-06-13 0:28 ` Antoine Riard
2020-06-13 0:45 ` ZmnSCPxj
0 siblings, 1 reply; 8+ messages in thread
From: Antoine Riard @ 2020-06-13 0:28 UTC (permalink / raw)
To: ZmnSCPxj; +Cc: Bitcoin Protocol Discussion
[-- Attachment #1: Type: text/plain, Size: 6539 bytes --]
Hi ZmnSCPxj,
> I have not studied the proposal in close detail yet, but anyway, my main
takeaway roughly is:
>
> * The core of CoinPool is some kind of multiparticipant (N > 2) offchain
update mechanism (Decker-Wattenhofer or Decker-Russell-Osuntokun).
> * The output at each state of the update mechanism is some kind of
splitting construction (which I have not studied in detail).
> * At each update of the state, all participants must sign off on the
new state.
Overall, that's a really accurate description. I would add you can embed a
funding outpoint of any offchain protocol on the splitting construction,
modulo some timelocks shenanigans.
> In order to hide transfers from the elected WabiSabi server, participants
can maintain two coins in every state, and move coins randomly across the
two coins they own at each state update, in order to hide "real" transfers
from the elected server.
Yes I'm quite sure you can reuse WabiSabi as a communication channel
between participants, assuming you support tapscript and merkle branch
transports, and server build a tree. Generally, we tried to keep design as
flexible as we can to reuse privacy tools.
> Indeed, from what I can understand, in order to properly set up the
splitting transactions in the first place, at each state every participant
needs to know how much each other participant actually owns in the CoinPool
at that point in time.
Yes, that's part of future research, defining better *in-pool* observer.
Sadly, right now, even if you use mask construction inside, it's quite easy
to trace leaves by value weight. Of course, you can enforce equal-value
leaves, as for a regular onchain CoinJoin. I think it comes with a higher
onchain cost in case of pool breakage.
> That way, output addresses can be to fresh pseudonyms of the participant,
removing all linkages of participant to amount they own, and each
participant can maintain multiple outputs per state for their own purposes
and to mildly obscure exactly how much they own in total.
That's right that an in-pool observer may learn a link between an exit and
an onchain withdraw. There is a future optimization, if you can swap your
withdraw with an already onchain output, therefore breaking heuristics.
> We can do this by using `SIGHASH_ANYPREVOUT` to force whoever performs a
unilateral close of the CoinPool to pay the onchain fees involved, so that
it would have to be a good reason indeed to perform a unilateral close.
Absolutely, for the fee structure, as the withdraw output is at the
discretion of user, I was thinking some CPFP. There is maybe a better
solution, haven't spend that much on the exact adequate, incentives-align
mechanism beyond a "withdraw-must-pay-its-fees".
Thanks for the high-quality review, as usual ;)
Antoine
Le ven. 12 juin 2020 à 04:39, ZmnSCPxj <ZmnSCPxj@protonmail.com> a écrit :
> Good morning Antoine and Gleb,
>
> I have not studied the proposal in close detail yet, but anyway, my main
> takeaway roughly is:
>
> * The core of CoinPool is some kind of multiparticipant (N > 2) offchain
> update mechanism (Decker-Wattenhofer or Decker-Russell-Osuntokun).
> * The output at each state of the update mechanism is some kind of
> splitting construction (which I have not studied in detail).
> * At each update of the state, all participants must sign off on the new
> state.
>
> It seems to me that it would be possible to use a [WabiSabi protocol](
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-June/017969.html)
> during negotiation of a new state.
>
> Now, WabiSabi is a client-server protocol.
> As all participants in the CoinPool are needed in order to ratify each new
> state anyway, they can simply elect one of their number by drawing lots, to
> act as server for a particular state update.
>
> Then the participants can operate as WabiSabi clients.
> Each participant registers the outputs they currently own in the current
> state, getting credentials that sum up to the correct value.
> Then, during the WabiSabi run, they can exchange credentials among the
> participants in order to perform value transfers inside the WabiSabi
> construction.
> Then, at output registration, they register new outputs to put in the next
> state of the CoinPool.
>
> In order to hide transfers from the elected WabiSabi server, participants
> can maintain two coins in every state, and move coins randomly across the
> two coins they own at each state update, in order to hide "real" transfers
> from the elected server.
>
> Then, after output registration, the participants ratify the new state by
> signing off on the new state and revoking the previous state, using the
> update mechanism.
>
> Of course, we should note that one desired feature for CoinPool in the
> original proposal is that a participant can exit, and the CoinPool would
> still remain valid, but only for the remaining participants.
>
> This is arguably a mild privacy leak: every other participant now knows
> how much that particular participant took out from the CoinPool.
> Indeed, from what I can understand, in order to properly set up the
> splitting transactions in the first place, at each state every participant
> needs to know how much each other participant actually owns in the CoinPool
> at that point in time.
>
> To hide how much each participant owns in the CoinPool from other
> participants, we would have to make unilateral closes expose all the
> current outputs, without trying to identify *which* participant exited the
> CoinPool, and thus preventing anyone else from figuring out exactly how
> much each *other* participant actually owns in the CoinPool on exit.
> That way, output addresses can be to fresh pseudonyms of the participant,
> removing all linkages of participant to amount they own, and each
> participant can maintain multiple outputs per state for their own purposes
> and to mildly obscure exactly how much they own in total.
>
> If we drop that feature (of being able to exit a participant without
> closing the *entire* CoinPool), of course, we need to mildly disincentivize
> a participant closing unilaterally for trivial reasons.
> We can do this by using `SIGHASH_ANYPREVOUT` to force whoever performs a
> unilateral close of the CoinPool to pay the onchain fees involved, so that
> it would have to be a good reason indeed to perform a unilateral close.
>
>
> Regards,
> ZmnSCPxj
>
[-- Attachment #2: Type: text/html, Size: 7058 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-13 0:28 ` Antoine Riard
@ 2020-06-13 0:45 ` ZmnSCPxj
2020-06-13 1:20 ` ZmnSCPxj
0 siblings, 1 reply; 8+ messages in thread
From: ZmnSCPxj @ 2020-06-13 0:45 UTC (permalink / raw)
To: Antoine Riard; +Cc: Bitcoin Protocol Discussion
Good morning Antoine,
> Yes, that's part of future research, defining better *in-pool* observer. Sadly, right now, even if you use mask construction inside, it's quite easy to trace leaves by value weight. Of course, you can enforce equal-value leaves, as for a regular onchain CoinJoin. I think it comes with a higher onchain cost in case of pool breakage.
Perhaps not necessarily.
An advantage of WabiSabi is I can pretend to be two or more participants.
For example, I can pretend to be "Alice" and "Bob", and pretend that "Alice" owes a life debt to "Bob".
At initial state setup, I put a 1.0 BTC coin as "Alice" and a 0.5 BTC coin as "Bob".
Now, at each state update I need to sign as "Alice" and "Bob".
However, after the first initial state, I can use a new persona "Bobby" to *own* my coins, even though I still have to sign as "Alice" and "Bob" in every state update.
What the other pool participants see is that the 1.0 BTC "Alice" coin and the 0.5 BTC "Bob" coin are merged into the 1.5 BTC "Bobby" coin.
What they cannot be sure of is:
* "Alice" paid to "Bob", who is now pretending to be "Bobby".
* "Bob" paid to "Alice", who is now pretending to be "Bobby".
* "Alice" and "Bob" are the same person, and is also pretending to be "Bobby".
All the other participants know is that whoever owns the coin *now* is still part of the pool, but cannot be sure which participant *really* owns which coin, and whether participants are sockpuppets (which is why it should use n-of-n at each state update, incidentally).
In effect, it "imports" the possibility of PayJoin inside the CoinPool construction.
Regards,
ZmnSCPxj
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-13 0:45 ` ZmnSCPxj
@ 2020-06-13 1:20 ` ZmnSCPxj
2020-06-16 5:23 ` ZmnSCPxj
0 siblings, 1 reply; 8+ messages in thread
From: ZmnSCPxj @ 2020-06-13 1:20 UTC (permalink / raw)
To: ZmnSCPxj, Bitcoin Protocol Discussion
Good morning Antoine,
By dropping the requirement that a participant can seamlessly leave the CoinPool, it allows participants to split up their coins among new aliases and to use a different identity for later claiming coins.
With WabiSabi, none of the other participants can get a mapping between current-state aliases and the actual participants.
Now, in order to authorize moving coins from an output on the current state to a new output on the next state, obviously the pool needs to get a signature from its current owner.
Ideally, we would not want to have to implement SCRIPT inside the CoinPool software.
And with Taproot, a pubkey can hide one or more SCRIPTs.
If we use pubkeys as the identities of owners of coins, then it allows an alias to encode a SCRIPT.
With the combination of both features, we can instantiate HTLCs (or, with `SIGHASH_ANYPREVOUT`, PTLCs) inside a CoinPool "alias" pubkey identity, allowing for interoperation with LN.
Now suppose I have 1.0 BTC in a CoinPool.
I want to make an HTLC with you (hashlocked to you, timelocked to me), for 0.5 BTC.
I encode the HTLC SCRIPT, and put it into a Taproot whose internal pubkey is a MuSig of fresh identities of mine and yours.
Then, inside the CoinPool, I split my 1.0BTC to a 0.5BTC coin to a fresh identity of mine, and 0.5BTC to our HTLC Taproot.
If you can acquire the hash, you give it to me, and I am supposed to hand you a partial signature share to the HTLC Taproot that you can later complete and present to the CoinPool in the next update round in order to get the HTLC value.
If I do not hand you the signature share even after you hand the hash, you just drop the entire CoinPool onchain, instantiating the HTLC Taproot output onchain, and using the SCRIPT branch to claim using the hash you know.
If the timelock expires, I ask you to hand over your partial signature to the HTLC Taproot that I can later complete and present to the CoinPool in the next update round to recover the HTLC value.
If you do not hand over the signature share, I drop the CoinPool onchain, which instantiates the HTLC Taproot output onchain, and use the SCRIPT branch to claim using the timelock branch.
You can also ask to abort the HTLC "early", before the timelock expires, by handing over your partial signature to the HTLC Taproot, which I can later complete and present to the CoinPool in the next update round.
This is equivalent to `update_fail_htlc` in the current LN BOLT spec.
This allows operation of any SCRIPT, incidentally, without requiring that CoinPool software include a SCRIPT interpreter, only signature validation.
Any time an output absolutely needs a SCRIPT, we just drop the CoinPool onchain and let onchain handle the SCRIPT interpretation.
Regards,
ZmnSCPxj
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy
2020-06-13 1:20 ` ZmnSCPxj
@ 2020-06-16 5:23 ` ZmnSCPxj
0 siblings, 0 replies; 8+ messages in thread
From: ZmnSCPxj @ 2020-06-16 5:23 UTC (permalink / raw)
To: ZmnSCPxj, Bitcoin Protocol Discussion
Good morning Antoine, Gleb, and list,
In some ways, CoinPool is really part of a swarm of ideas:
* CoinPool
* Multiparticipant (N > 2) channels
* Channel factories
* Nodelets
What CoinPool and multiparticipant channels buy us is better flexibility with forwarding.
For example, if we compare a multiparty channel to a channel factory, suppose there exists three entities A, B, and C in the multiparty construction.
In a channel factory, each entity has to decide how much of its liquidity to tie up in a channel with a specific other peer in the multiparty construction.
This limits the practical payment forwarding when integrated into the Lightning Network.
In a CoinPool, any of the entities can forward to any of the other entities, without tying their liquidity to a channel specifically with those entities.
However, in a CoinPool, once any of the entities goes offline, the entire CoinPool can no longer update.
This is in contrast with channel factories, where, if entity C goes offline, the channel between A and B remains useable for forwarding.
In other words, channel factories degrade gracefully.
Further, we already have a decent solution for liquidity redistribution: JIT Routing by Rene Pickhardt.
Thus the liquidity issue with channel factories are somewhat mitigated (and if all participants are online, they also have the option of redistributing channel funds *inside* the factory as well, not just JIT routing), while gaining graceful degradation of the factory.
Another is that pathfinding algorithms work best if graph edges are edges and not in fact some kind of twisted multi-edge that connects more than two nodes together.
On the other hand, the participants of a CoinPool could create a "virtual node" that is a MuSig of their individual keys, and report that as the "real" node on LN gossip (each of them pretending to have a large channel with that virtual node), so that the rest of the network only sees edges that link two nodes (and existing pathfinding algos still work seamlessly, never realizing that this node is actually a virtual node that represents a CoinPool).
This is basically them creating a sort of Nodelet node, which other nodes cannot make channels to, and which uses channels with the Nodelet node as proxies for the CoinPool as a whole.
Regards,
ZmnSCPxj
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-06-16 5:23 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-11 8:53 [bitcoin-dev] CoinPool, exploring generic payment pools for Fun and Privacy Antoine Riard
2020-06-11 17:21 ` Jeremy
2020-06-12 23:45 ` Antoine Riard
2020-06-12 8:39 ` ZmnSCPxj
2020-06-13 0:28 ` Antoine Riard
2020-06-13 0:45 ` ZmnSCPxj
2020-06-13 1:20 ` ZmnSCPxj
2020-06-16 5:23 ` ZmnSCPxj
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox