Home /
Input Output /
hydra-poc
Mar 23, 12-1 PM (1)
Mar 23, 1-2 PM (2)
Mar 23, 2-3 PM (0)
Mar 23, 3-4 PM (0)
Mar 23, 4-5 PM (0)
Mar 23, 5-6 PM (0)
Mar 23, 6-7 PM (0)
Mar 23, 7-8 PM (0)
Mar 23, 8-9 PM (0)
Mar 23, 9-10 PM (0)
Mar 23, 10-11 PM (0)
Mar 23, 11-12 AM (0)
Mar 24, 12-1 AM (0)
Mar 24, 1-2 AM (0)
Mar 24, 2-3 AM (0)
Mar 24, 3-4 AM (0)
Mar 24, 4-5 AM (0)
Mar 24, 5-6 AM (0)
Mar 24, 6-7 AM (0)
Mar 24, 7-8 AM (0)
Mar 24, 8-9 AM (0)
Mar 24, 9-10 AM (1)
Mar 24, 10-11 AM (0)
Mar 24, 11-12 PM (0)
Mar 24, 12-1 PM (2)
Mar 24, 1-2 PM (0)
Mar 24, 2-3 PM (0)
Mar 24, 3-4 PM (0)
Mar 24, 4-5 PM (0)
Mar 24, 5-6 PM (0)
Mar 24, 6-7 PM (0)
Mar 24, 7-8 PM (0)
Mar 24, 8-9 PM (0)
Mar 24, 9-10 PM (0)
Mar 24, 10-11 PM (0)
Mar 24, 11-12 AM (0)
Mar 25, 12-1 AM (0)
Mar 25, 1-2 AM (0)
Mar 25, 2-3 AM (0)
Mar 25, 3-4 AM (0)
Mar 25, 4-5 AM (0)
Mar 25, 5-6 AM (0)
Mar 25, 6-7 AM (0)
Mar 25, 7-8 AM (0)
Mar 25, 8-9 AM (0)
Mar 25, 9-10 AM (0)
Mar 25, 10-11 AM (0)
Mar 25, 11-12 PM (0)
Mar 25, 12-1 PM (0)
Mar 25, 1-2 PM (1)
Mar 25, 2-3 PM (0)
Mar 25, 3-4 PM (0)
Mar 25, 4-5 PM (0)
Mar 25, 5-6 PM (0)
Mar 25, 6-7 PM (1)
Mar 25, 7-8 PM (0)
Mar 25, 8-9 PM (0)
Mar 25, 9-10 PM (0)
Mar 25, 10-11 PM (0)
Mar 25, 11-12 AM (0)
Mar 26, 12-1 AM (0)
Mar 26, 1-2 AM (0)
Mar 26, 2-3 AM (0)
Mar 26, 3-4 AM (0)
Mar 26, 4-5 AM (0)
Mar 26, 5-6 AM (0)
Mar 26, 6-7 AM (0)
Mar 26, 7-8 AM (0)
Mar 26, 8-9 AM (0)
Mar 26, 9-10 AM (1)
Mar 26, 10-11 AM (0)
Mar 26, 11-12 PM (0)
Mar 26, 12-1 PM (0)
Mar 26, 1-2 PM (0)
Mar 26, 2-3 PM (0)
Mar 26, 3-4 PM (0)
Mar 26, 4-5 PM (0)
Mar 26, 5-6 PM (0)
Mar 26, 6-7 PM (0)
Mar 26, 7-8 PM (0)
Mar 26, 8-9 PM (0)
Mar 26, 9-10 PM (0)
Mar 26, 10-11 PM (0)
Mar 26, 11-12 AM (0)
Mar 27, 12-1 AM (0)
Mar 27, 1-2 AM (0)
Mar 27, 2-3 AM (0)
Mar 27, 3-4 AM (0)
Mar 27, 4-5 AM (0)
Mar 27, 5-6 AM (0)
Mar 27, 6-7 AM (0)
Mar 27, 7-8 AM (0)
Mar 27, 8-9 AM (0)
Mar 27, 9-10 AM (0)
Mar 27, 10-11 AM (0)
Mar 27, 11-12 PM (0)
Mar 27, 12-1 PM (0)
Mar 27, 1-2 PM (1)
Mar 27, 2-3 PM (0)
Mar 27, 3-4 PM (2)
Mar 27, 4-5 PM (0)
Mar 27, 5-6 PM (0)
Mar 27, 6-7 PM (0)
Mar 27, 7-8 PM (0)
Mar 27, 8-9 PM (0)
Mar 27, 9-10 PM (0)
Mar 27, 10-11 PM (0)
Mar 27, 11-12 AM (0)
Mar 28, 12-1 AM (0)
Mar 28, 1-2 AM (0)
Mar 28, 2-3 AM (0)
Mar 28, 3-4 AM (0)
Mar 28, 4-5 AM (0)
Mar 28, 5-6 AM (0)
Mar 28, 6-7 AM (0)
Mar 28, 7-8 AM (0)
Mar 28, 8-9 AM (0)
Mar 28, 9-10 AM (0)
Mar 28, 10-11 AM (0)
Mar 28, 11-12 PM (0)
Mar 28, 12-1 PM (0)
Mar 28, 1-2 PM (0)
Mar 28, 2-3 PM (0)
Mar 28, 3-4 PM (0)
Mar 28, 4-5 PM (0)
Mar 28, 5-6 PM (0)
Mar 28, 6-7 PM (0)
Mar 28, 7-8 PM (0)
Mar 28, 8-9 PM (0)
Mar 28, 9-10 PM (0)
Mar 28, 10-11 PM (0)
Mar 28, 11-12 AM (0)
Mar 29, 12-1 AM (0)
Mar 29, 1-2 AM (0)
Mar 29, 2-3 AM (0)
Mar 29, 3-4 AM (0)
Mar 29, 4-5 AM (0)
Mar 29, 5-6 AM (0)
Mar 29, 6-7 AM (0)
Mar 29, 7-8 AM (0)
Mar 29, 8-9 AM (0)
Mar 29, 9-10 AM (0)
Mar 29, 10-11 AM (0)
Mar 29, 11-12 PM (0)
Mar 29, 12-1 PM (0)
Mar 29, 1-2 PM (0)
Mar 29, 2-3 PM (0)
Mar 29, 3-4 PM (0)
Mar 29, 4-5 PM (0)
Mar 29, 5-6 PM (0)
Mar 29, 6-7 PM (0)
Mar 29, 7-8 PM (0)
Mar 29, 8-9 PM (0)
Mar 29, 9-10 PM (0)
Mar 29, 10-11 PM (0)
Mar 29, 11-12 AM (0)
Mar 30, 12-1 AM (0)
Mar 30, 1-2 AM (0)
Mar 30, 2-3 AM (0)
Mar 30, 3-4 AM (0)
Mar 30, 4-5 AM (0)
Mar 30, 5-6 AM (1)
Mar 30, 6-7 AM (0)
Mar 30, 7-8 AM (1)
Mar 30, 8-9 AM (0)
Mar 30, 9-10 AM (0)
Mar 30, 10-11 AM (0)
Mar 30, 11-12 PM (1)
Mar 30, 12-1 PM (3)
17 commits this week
Mar 23, 2026
-
Mar 30, 2026
Remove head-initialization endpoint
Signed-off-by: Sasha Bogicevic <[email protected]>
Fix Plutus script evaluation using era-aware EpochInfo on mainnet/testnet
On multi-era chains, Byron slots are 20s each while Shelley+ slots are 1s. Using fixedEpochInfo for L2 Globals produces wrong POSIXTime values in the Plutus ScriptContext, which can cause time-sensitive scripts (Close, Contest, Fanout) to fail. For online (Cardano) mode, query the chain's EraHistory and use it to build an era-aware EpochInfo via newGlobalsWithEraHistory. Offline mode keeps fixedEpochInfo since it runs a single-era devnet. Signed-off-by: Sasha Bogicevic <[email protected]>
HeadV1 -> HeadV2; no more mainnet limit on deposits
Filter pending deposits by HeadId when processing ReqTx (#2559)
## Summary - Fix `RequestedDepositNotFoundLocally` error when submitting L2 transactions while deposits from other heads exist - Apply `depositsForHead` filter to `pendingDeposits` in ReqTx handler, consistent with ReqSn and AckSn handlers - Prevents `selectNextDeposit` from picking deposits belonging to other heads ## Problem When processing a `ReqTx` (new L2 transaction), `onOpenNetworkReqTx` received unfiltered `pendingDeposits`. This allowed `selectNextDeposit` to pick a deposit from another head, include it in the `ReqSn`, and cause `RequestedDepositNotFoundLocally` errors when peers couldn't find the deposit in their filtered list. ## Test plan - [ ] Verify existing deposit-related tests pass - [ ] Test L2 transaction submission while deposits from other heads are observed on chain
Filter pending deposits by HeadId in all head-level handlers
The following handlers were passing unfiltered pendingDeposits, causing them to potentially pick deposits from other heads: 1. ReqTx handler (line 1739): Could select wrong deposit for ReqSn, causing RequestedDepositNotFoundLocally errors on peers. 2. OnDecrementTx handler (line 1666): Could include wrong deposit in subsequent ReqSn via setExistingDeposit. 3. Rollback handler (line 1707): maybeRepostIncrementTx could find and repost for wrong head's deposit. Other handlers (ReqSn, AckSn, onOpenChainTick) already correctly used depositsForHead to filter deposits by the current head's ID. Note: onChainTick intentionally processes ALL deposits as it handles node-level deposit status tracking (DepositActivated/DepositExpired), not head-specific logic. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Deploying to gh-pages from @ cardano-scaling/hydra@b7ad7a8b26991fab350a7403745cc07503ba9a9c 🚀
Directly open heads (#2536)
Resolves #1329 Fix https://github.com/cardano-scaling/hydra/issues/2534 Fix https://github.com/cardano-scaling/hydra/issues/2557 This is a monumental list of changes .. but what a pleasant one (removing code = :lotus_position:) Implements ADR-33 (new `docs/adr/2026-03-10_033-directly-open-head.md`): the Hydra head initialization phase is removed. Init now opens the head directly with an empty UTxO set, eliminating the old Commit → CollectCom → Open flow entirely. - :lotus_position: Remove the initialization phase: Init creates the head in Open state immediately — no more Commit, CollectCom, or Abort transactions: **Greatly reduces cost and simplifies coordination** to open a head - :lotus_position: This gets rid of most known issues around abort and only #1468 remains - :lotus_position: Remove vInitial and vCommit on-chain validators, reducing the script surface and may allow a single publishing txs again? These were also the bottle necks and we _could_ **support ~50 party heads** now - Not done in this PR, should I change it? - :lotus_position: Remove Initial off-chain state and all associated HeadLogic event handlers (HeadIsInitializing, Committed, HeadIsAborted, Abort client input) - :lotus_position: Unify fund ingestion under the existing deposit/increment mechanism — POST /commit now always drafts a deposit tx into an open head - :lotus_position: Fix snapshot sideloading of deposit snapshots: LocalStateCleared now correctly includes utxoToCommit in localUTxO when the corresponding on-chain increment has been finalized - :lotus_position: More behavior tests where possible - :lotus_position: Consolidate and simplify E2E deposit tests: single-party integrations for plain UTxO and script blueprint, multi-party concurrent deposits with mkTestTiming' N for correct deposit period sizing - :lotus_position: Check deposits for Byron addresses and mainnet ADA limit in draftDepositTx (previously only checked for commits) This is so radically different that this will be HydraV2, hence I bumped versions accordingly. We should use the chance to clean up the API (in follow-up PRs). TODO: - [x] Scripts in `hydra-plutus` - [x] L1 tx construction, observation and mutation tests in `hydra-tx` - [x] L2 protocol types - [x] `tx-cost` benchmark - [x] Cost diffences github workflow - [x] L2 protocol logic - [x] E2E tests in `hydra-cluster` - [x] `hydra-tui` - [x] Formal spec updated https://github.com/cardano-scaling/hydra-formal-specification/pull/24 - [x] ADR for this change written --- <!-- Consider each and tick it off one way or the other --> * [x] CHANGELOG updated * [x] Documentation updated * [x] Haddocks updated * [ ] ~~No new TODOs introduced~~ All follow-ups: - Rename `/commit` -> `/deposits` + rename everything - Drop `/head-initialization` - Unify `HeadSeed`/`HeadId` - Make deposits / increment not require `==` but `>=` on the value (to allow smaller than minUTxO deposits) - Use script reference on v_deposit in increment tx
Fix some tests that needed to see messages and _not_ wait until seeing the Sync message
Add deposit/decommit to full life cycle test and fix historical message replay
singlePartyHeadFullLifeCycle now exercises the deposit (commit) flow using timing-derived deposit period instead of a hardcoded value, so the deposit activates within the test timeout on both devnet and real networks. waitForNodesSynced now waits for the Greetings message before declaring the node ready. Greetings is always sent after the full historical event replay, making it a reliable separator between replayed and live messages. This prevents tests from matching on historical HeadIsOpen or NodeSynced events from a previous run's persisted state — which caused the smoke test to proceed with a stale headId and then fail with "Head is not open" when posting to /commit. Signed-off-by: Sasha Bogicevic <[email protected]>
Rename canDeposit2 to canDepositConcurrently
Signed-off-by: Sasha Bogicevic <[email protected]>
Minor spec changes for assumptions about number of events
Fix stuck snapshot when CommitFinalized races with RequestedSnapshot
When CommitFinalized (or DecommitFinalized) arrives while a snapshot is in RequestedSnapshot state, the in-flight ReqSn carries the old version and will be rejected with ReqSvNumberInvalid once the version bumps. Since nothing re-triggers a fresh request, the head gets permanently stuck with pending localTxs. The guard added in ef0762bd5 used snapshotInFlight which returns True for both RequestedSnapshot and SeenSnapshot. This was correct for SeenSnapshot (AckSns in-flight, snapshot will complete naturally) but too broad for RequestedSnapshot (stale echo will be rejected). Replace the guard with isCollectingAcks which only blocks SeenSnapshot, allowing CommitFinalized/DecommitFinalized to immediately re-request with the new version when in RequestedSnapshot state. Signed-off-by: Sasha Bogicevic <[email protected]>
Write IOSim trace to file instead of stdout on test failure
The old dumpTrace used say which in IO context dumps the entire IOSim trace (potentially thousands of JSON lines) to stdout on test failure. With slow-network tests generating much larger traces, this was very noisy. Now the trace is written to a temp file and only the path is printed. Signed-off-by: Sasha Bogicevic <[email protected]>
Pick up active deposits in chained snapshots when currentDepositTxId is unset
When a deposit activates while a snapshot is in-flight, the tick cannot request a snapshot (blocked by snapshotInFlight). After the in-flight snapshot confirms, LocalStateCleared resets currentDepositTxId to Nothing, so setExistingDeposit returns Nothing and the deposit is never included in subsequent chained snapshots — eventually expiring unused. Fix by introducing selectNextDeposit which falls back to scanning pendingDeposits for the oldest active deposit when currentDepositTxId is unset, guarded by: no pending decommit and the last confirmed snapshot did not already include a deposit (to avoid double-posting IncrementTx before CommitFinalized removes the deposit). This fallback is used in both maybeRequestNextSnapshot and maybeRequestSnapshot in onOpenNetworkReqTx. Signed-off-by: Sasha Bogicevic <[email protected]>
Pick up active deposits in chained snapshots when currentDepositTxId is unset
When a deposit activates while a snapshot is in-flight, the tick cannot request a snapshot (blocked by snapshotInFlight). After the in-flight snapshot confirms, LocalStateCleared resets currentDepositTxId to Nothing, so setExistingDeposit returns Nothing and the deposit is never included in subsequent chained snapshots — eventually expiring unused. Fix by introducing selectNextDeposit which falls back to scanning pendingDeposits for the oldest active deposit when currentDepositTxId is unset, guarded by: no pending decommit and the last confirmed snapshot did not already include a deposit (to avoid double-posting IncrementTx before CommitFinalized removes the deposit). This fallback is used in both maybeRequestNextSnapshot and maybeRequestSnapshot in onOpenNetworkReqTx. Signed-off-by: Sasha Bogicevic <[email protected]>