33. Directly open head: removal of initialization phase
Status
Accepted
Context
-
The Hydra Head protocol, as described in the original paper, specifies an initialization phase before a head can be opened. This phase consists of multiple on-chain transactions:
- Init - Creates the head on-chain in an
Initialstate, minting head tokens (one state thread token + one participation token per party). - Commit - Each participant locks UTxO they want to bring into the head (one transaction per party).
- CollectCom - Once all parties have committed, collects all committed UTxO and transitions the head to
Open. - Abort - An alternative path allowing any party to cancel initialization and reimburse all committed UTxO.
- Init - Creates the head on-chain in an
-
This initialization phase introduced significant complexity:
- Two additional on-chain validators (
vInitial,vCommit) beyond the head validator itself. - An
Initialoff-chain state tracking pending commits and committed UTxO per party. - Multiple API events (
HeadIsInitializing,Committed,HeadIsAborted) and a client command (Abort).
- Two additional on-chain validators (
-
The "unabortable heads" problem: If a participant committed a large UTxO set, the resulting Abort transaction could exceed Cardano transaction size limits, making it impossible to abort the head. This effectively locked funds with no recourse.
-
The Commit mechanism was limited in how much UTxO could be committed per party due to on-chain transaction size constraints, while the later-added deposit/increment mechanism does not have these per-party limitations.
-
The overall lifecycle cost of opening a head was high: Init + N Commit transactions + CollectCom, each requiring on-chain fees.
Decision
Remove the initialization phase entirely. The Init transaction directly opens the head:
- Init creates an
Openhead: The Init transaction mints the head tokens and creates the head output inOpenstate with an empty UTxO set (utxoHash = hash(∅)). - Funds are added post-opening: Participants use the existing deposit/increment mechanism to add funds to the head after it is opened.
- No Commit, CollectCom, or Abort transactions: These transaction types and their associated on-chain validators are removed.
The head lifecycle simplifies from:
Idle → Init → Initial → Commit* → CollectCom → Open → ... → Final
↓
Abort → Idle
to:
Idle → Init → Open → ... → Final
Consequences
-
The
vInitialandvCommiton-chain validators are removed, reducing the on-chain script surface and audit scope. -
The head validator state machine simplifies from
Initial → Open → Closed → FinaltoOpen → Closed → Final. -
Off-chain complexity is reduced: the
InitialStateand its associated event handlers (commit tracking, abort logic) are removed fromHeadLogic. -
The API surface shrinks:
HeadIsInitializing,Committed,HeadIsAbortedserver outputs and theAbortclient input are removed.HeadIsOpenno longer carries autxofield since heads always open empty. -
Opening a head requires fewer on-chain transactions (single Init vs. Init + N Commits + CollectCom), reducing costs for most use cases.
-
The unabortable heads problem is eliminated since there is no abort transaction.
-
Adding funds to a head is unified under a single mechanism (deposit/increment) regardless of whether it happens at the start or later during the head's lifetime.
-
The overloaded "commit" term is dropped in favor of "deposit". Previously, the
/commitHTTP endpoint served double duty (committing during initialization and depositing into an open head). With initialization removed, this endpoint can be replaced by a more REST-like/depositsresource, and server outputs renamed fromCommitXXXtoDepositXXX, resulting in a cleaner and more consistent API. -
A future enhancement could allow the initiator to include initial funds directly in the Init transaction, avoiding the need for a separate deposit.


