cardano-scaling / hydra

Implementation of the Hydra Head protocol
https://hydra.family/head-protocol/
Apache License 2.0
280 stars 84 forks source link

Only sign closable snapshots #370

Closed ch1bo closed 2 months ago

ch1bo commented 2 years ago

What & Why

We want Hydra Heads to be secure. This means that we can close & fan out the L2 state at any point throughout the life-cycle of a Hydra Head.

There are however some situations which make the Head "unclosable", because our validator would fail. For example, if assets are minted in a Hydra Head, the UTxO set including the new assets would not be closable because the L1 would require the minting policy to mint the same tokens, but that might not even make validate anymore at the point of closing the Head. Another example is the current limitation on the maximum number of UTxOs supported (#190), or the fact that Byron addresses are not visible to Plutus scripts.

Hence, the goal of this is that our hydra-node is not signing any transaction/snapshot which cannot be fanned out.

As a consequence, if a user submits a transaction leading to such an unclosable UTxO, she will not se a SnapshotConfirmed message anymore. To notify clients about this more directly we want to have a server output when a snapshot was not signed because of an unclosable UTxO.

Requirements

Implementation ideas

Tasks

abailly-iohk commented 2 years ago

Other implementation idea: We could use a specially configured ledger, with specific rules preventing application of transactions leading to unclosable UTxO. This would have the nice property of encapsulating this filtering logic inside the Ledger interface, thus not requiring any change to the core logic or interfaces. This would have the additional benefit of providing some blueprint or forcing us to provide the capability to plug specific ledgers, something that users might need.

abailly-iohk commented 2 years ago

FWIW, one use-case for Hydra Head is micro-payments which could very easily lead to UTxO that cannot be committed back on-chain. How are we supposed to handle this problem if we implement this feature?

ch1bo commented 2 years ago

How are we supposed to handle this problem if we implement this feature?

I expect these UTxOs preventing snapshots to be signed until they are aggregated again. Maybe we could generalize #358 to also exclude these outputs from signing snapshots to have more confidence on unrelated outputs?

abailly-iohk commented 2 years ago

The more I think about it, the more I view this feature as problematic for quite a large number of use cases, to the point of making the Hydra Head protocol pretty much useless but for only a small subset of the usages we envisioned initially. If we don't sign snapshots that are not "fannoutable":

More precisely, we can post one such transaction but it will never get confirmed, and because new transaction (received through NewTx or ReqTx) are checked against confirmed snapshot, and the latter will never change until we get a new snapshot, the transaction will be stuck forever. Of course, we could change the protocol to include a Seen snapshot so that users will be free to post more transactions, but then any kind of security guarantee is lost and Hydra users could as well send those transaction by email.

It seems to me we are facing a contradiction, which might or might not be a fundamental limitation of Hydra Head protocol, between broadening the use cases space and maintaining security properties of the protocol.

Given the Hydra Head nodes have to know each other in advance to form a head (they are supposed to communicate through pairwise authenticated channels as per Setup section of the paper), and there's no provision in the protocol or our implementation to protect against most malicious behaviours, Heads cannot be formed of arbitrary nodes, and thus require some form of trust between involved parties. For example, Head participants could "agree" to preserve liveness of the Head and define a mechanism to ensure snapshots can eventually be fanned out, for example by agreeing on some cleaning transaction at end of a period to remove "coin dust".

Rather than doing some filtering inside the Head, another option would be to modify the protocol to not limit the contestation period until FanOut is posted and finalised, eg. Head stays open until FanOut: Should a FanOut tx fail because it's invalid on L1, it's still possible to create a new snapshot, sign it, and "Contest" the latest one.

ch1bo commented 2 years ago

@abailly-iohk I think you are right and I shall think about this a bit more as well. One thing which struck my mind when reading your comment:

If we would be using MPTs, we could fan out the parts of the Head which are sound, even though the Head is closed.

However this would open up again "attacks" where a party says "yeah.. i'm not going to close the head while you have all your money in coin dust" .. and then they do it.

abailly-iohk commented 2 years ago

In any case, this seems a hot topic to discuss with research team.

perturbing commented 2 years ago

To add to this discussion, as @abailly-iohk mentioned, since participants know each other, there is more trust than on the layer 1. That said, if all parties commit the same amount to the head as collateral (e.g. bigger than the value that is transferred in the head), no party has the incentive to close a head that cannot fan out. This leverages the mutual assured destruction (MAD) principle.

Another additional idea, inspired by the kaleidoscope paper

Due to the fact that it is not reasonable to assume that the majority of the players are honest in a poker game, the secure poker protocol will not be able to guarantee fairness. Instead, we follow the approach of imposing a financial penalty on the party that interrupts the correct execution of the protocol, and use this money to compensate the honest parties

In that protocol, cards are shuffled using a n party public key to encrypt a deck of cards and re-randomize them. Each party holds a piece of the private key, and only together they can decrypt cards one by one. It feels like the same problem, if a party stops participating in the creation of a “valid” checkpoint, it is punished on the layer 1.

ch1bo commented 1 year ago

We realized that reference scripts make the head unclosable as well (since Babbage of course). When committing a UTxO with a reference script, the head can be opened (if it fits), but a fanout done by the hydra-node will fail. Note that this is only true for committed reference scripts, any UTxO with a reference script in the L2 would be fan-outable by the hydra-node.

We could craft a fanoutTx by hand if needed and given we have all the necessary information.. but this can be seen as a similarly unsupported feature like byron addresses or growing the UTxO set too bit on the L2.

GeorgeFlerovsky commented 3 months ago

@ch1bo @Quantumplation After today's Hydra WG discussion, I came up with another approach to this problem. Suppose that you can perfectly partition any L2 utxo set into two groups:

  1. L1-valid utxos can be fanned out individually on L1 -- they contain minADA, don't contain tokens minted on L2, etc.
  2. L1-invalid utxos cannot be fanned out individually on L1.

You can guarantee that your L2 snapshots are always closeable if your fan-out mechanism interprets snapshots as follows:

  1. L1-valid utxos get fanned out individually on L1, as before. They can be partially fanned out, too (#1468).
  2. L1-invalid utxos get fanned out as an aggregate "continuation" utxo on L1, containing the merkle sub-tree root and locked under multisig contract requiring unanimous signature from the L2 parties. These utxos cannot be partially fanned out.

The continuation utxo allows the L2 parties to insert the L1-invalid utxos in the L2 ledger of a new Hydra Head instance, if they decide to launch one, via a special kind of commit (commit merkle tree). This would allow the L2 parties to recover from any L2 consensus breakdown without losing any L2 information, if they decide to communicate/cooperate again.

Recovering the L1-invalid utxos in the new L2 ledger would allow the parties to convert some of those utxos into L1-valid utxos. Examples:

noonio commented 2 months ago

After considering this alongside other alternatives: https://github.com/cardano-scaling/hydra/issues/1468,, https://github.com/cardano-scaling/hydra/issues/190, we would rather aim for https://github.com/cardano-scaling/hydra/issues/1468.

The main reason is that only signing L1-compatible snapshots is still an all-or-nothing approach that prevents applications which require partial departure from L1 compatibility, i.e. using very small UTxO values.

Partial fanouts, on the other hand, allow individual recovery of UTxOs and would be much more flexible.

We might want to consider the re-opening of heads ( i.e. your comment @GeorgeFlerovsky ) in a seperate feature.