Closed ch1bo closed 1 week ago
Created a slightly more detailed transaction trace including deposits and cancellations (naming is still not 100%):
Also explored how we could use PlutusV3 (CIP-69) multi-purpose scripts:
An analogous design to the initialization phase (PlutusV2) would be that the deposit is controlled by two validators:
Besides other things, μ_deposit needs to ensure that the minted token is paid to the ν_deposit script. Hence, it's parameterized by the script hash H(ν_deposit). With PlutusV3, we could re-use the same script without losing anything here. All transactions that involve spending from the deposit output would need to burn the DT anyways and need the script included.
However, if we want to re-use the script, the output address of the deposit (purple in the image), would be parameterized too. So it's not a fixed address to "discover" and observe deposits:
But, do we need uniqueness of deposit tokens? Maybe it's enough to have it as evidence that the minting policy ran. Which would lead to this design:
Updated the #199 feature How section with this protocol design:
Idea: Deposit anything to commit into a deposit
output. Head participants then re-use the ReqSn
off-chain consensus to request inclusion of UTxO (like incremental decommit). Deposits have an asymmetric deadline, such that users need to wait longer before they can reclaim than the head participants have time to ensure the deposit is not rolled back (double spent). Deposits are recording outputs like in the commitTx
and claiming a deposit
into the head via an incrementTx
ensures the recorded UTxO matches (completely) with what was agreed off-chain. Participants only agree off-chain if they saw a matching deposit
.
Outline of one deposit being claimed in an increment and one deposit being cancelled:
flowchart LR
seed([seed])--> initTx
initTx --> open0([open v0 η0])
u1([u1]) --> depositTx1 --> deposit1(["deposit DL [u1]"])
u2([u2]) --> depositTx2 --> deposit2(["deposit DL [u2]"])
open0 -- Increment ξ3 --> incrementTx
deposit1 -- Claim --> incrementTx
incrementTx --> open1([open v1 η3])
open1 -- Close ξ1 --> closeTx
deposit2 -- Cancel --> cancelTx --> u3([u2])
Protocol transitions:
Situation: Head is open, $U_0$ locked, off-chain busy transacting
Deposit:
depositTx
hydra-node
or through a library/tool.depositTx
ensures through minting of a deposit token (DT) that anything to be committed $\phi$ is recorded correctly into the datum (isomorphic to $U_\alpha$)
depositTx
to ensure the transition to L2 is "correct"? Could mean more coupling, but simpler protocol here.Cancel:
cancelTx
after the deadline has passed
Increment:
hydra-node
) observe pending deposits using the common deposit address
depositTx
is not rolled backReqSn
message with $U_\alpha$incrementTx
, which:
incrementTx
on L1 with added $U_\alpha$ and make it available in their L2 state
Also updated #199 What with these requirements to represent better the new workflow (no L2 protocol interaction on deposit/cancel and the node just picking up pending commits):
Implement the protocol extension for more committing additional UTXOs into a Head as already briefly described in the original Hydra Head paper.
"As user, I want to add more funds to the head, such that I can spend them later in the head"
When the head is open, a hydra client can request an incremental commit:
POST /commit
. Just like with the "normal" commit, the user needs to send either a UTxO or a "blueprint transaction".depositTx
corresponding to the requested commit. (This works just the same way as the commit endpoint works so far during initialization phase)depositTx
Submitting the depositTx
transaction should have the requested UTxO
eventually added to the head
CommitRequested
(TBD: or DepositDetected
?) server output is sent to signal observation of the depositUTxO
and wait for a SnapshotConfirmed
with inclusion approval.incrementTx
, signs and submits that.CommitFinalized
server output is sent to the clients when the incrementTx
is observed.The node provides a list of pending commits (TBD: or call it deposits?) via the API using GET /commits
Each pending commit (deposit) has an id (i.e. the deposit outputs' TxIn
) and a deadline attached, after which a user can request refund of the commit
DELETE /commits/<id>
, which has the node construct and submit a cancelTx
for the user. TBD: okay to pay fees here?cancelTx
Any UTxO which can be committed, can also be incrementally committed
Changed the naming of a commit
to consist of two steps: deposit
and claim
(through an increment
or deposit
and recover
(if not claimed).
Also, we realized that we do not need unique deposit tokens (if we need them at all), so we can simplify the minting policy to be non-parameterized.
Updated transaction trace with both changes:
Further simplification of the protocol by asking more from the scripts which are committed into a head: https://github.com/cardano-scaling/hydra/issues/199#issuecomment-2309746253
Resulting in the transaction trace:
Why?
Drafted a quick example diagram of a script (a lottery) that is spent into a deposit:
It would need to check that its own (TxIn, TxOut)
is exactly contained in the list of deposited UTxO ([Commit]
in the diagram). For this, it must
cid
of which head to deposit to (could be generalized to list of participant keys)hash(ν_deposit)
to check the right outputTxOut
and search the list (a proper map would be great, but redeemer could contain an index)
Why
While working on #199 we realized that if we want to properly secure Hydra Heads against rollbacks of incrementally committed funds, having full sequencing requirements + potentially long lockup times is going to be really bad. In presence of rollbacks/pessimistic settings, this is creating a Head that is not "very live" as it would need to be forced to close in case a requested to commit UTxO is spent otherwise before the incrementTx hits the chain.
More details here: https://github.com/cardano-scaling/hydra/issues/199#issuecomment-2263319327
What
We want to revisit the deposit workflow again which should not have these issues.
This issue will be about collecting the necessary design pieces before we head into implementation.