Hydra Team Update
· 6 min read
What did the team achieve?
- Released 2.3.0, headlined by the
reapplyTxsnapshot-processing speedup, node configuration via YAML file, nativePaymentExtendedKey(HD wallet) key support #2583, and the batch of rotation, Blockfrost and network-layer resilience fixes from the last two updates. Note that all the subsequently listed work has not yet been released - Merged the performance stack
#2776-#2780,
in five reviewable pieces:
- accumulator commitments are now computed through the
rust-accumulatorFFI (bit-identical, pinned by equivalence and golden tests) and updated incrementally from the previous confirmed snapshot, taking the 4k-UTxO commitment from 2.13s to 25ms #2780 - BREAKING: broadcast messages are batched into a single etcd value, one Raft commit per batch over a reused gRPC connection. This bumps the network protocol version to 2, so all members of a head must upgrade together #2778
maxTxsPerSnapshotraised from 100 to 1000, leader-side only so no coordinated upgrade is needed #2777- SQLite event encoding moved onto the write-behind thread, keeping
serialisation of large
SnapshotRequestedevents off the node loop between processing aReqSnand broadcasting theAckSn#2779 - plus the measurement and benchmark infrastructure the whole stack was driven from #2776
- accumulator commitments are now computed through the
- Implemented selective partial fanout: a new
PartialFanoutclient input lets you distribute a chosen subset of the closed head's UTxO, with aHeadPartiallyFannedOutserver output telling clients whether the node keeps draining or awaits the next selection, aFanningOuthead status, and a matching TUI flow. Only the node that issued the command drives the step, so observers can't steamroll UTxO another party deliberately left behind #2750, #2333, with a docs page to go with it #2794 - BREAKING:
--deposit-periodis now embedded in the on-chainOpenDatumatInittime, so all nodes in a head must agree on it; a mismatch emitsIgnoredHeadInitializingand the node ignores the head, the same way contestation period mismatches already worked #2734 - Added
--deposit-activationto decouple activation from the deadline calculation: it controls only theInactive -> Activetransition while--deposit-periodkeeps its deadline and expiry role, giving three independent windows (maturity, active, recovery). The default of3600sreproduces the old behaviour exactly #2802, #2744 POST /commitnow rejects deposits that could never be claimed. A dry-run increment is checked against the L1 maximum transaction and serialized value sizes, returning a newDepositTooLargeerror. Previously the deposit would land on-chain and the increment claiming it could never be submitted, wedging further incremental commits and locking the funds until recovery after the deadline #2807- Fixed long-running nodes rejecting every layer 2 Plutus transaction carrying
a validity bound: the era history queried at startup has a forecast horizon
(36 hours on mainnet), and once past it those transactions failed with
PastHorizonuntil restart. The last era is now unbounded for L2 ledger time conversions #2803, #2798 - BREAKING (WebSocket API): removed the
SyncedStatusReportserver output, which the node pushed on every block. Sync status is now edge-triggered viaNodeUnsynced/NodeSyncedandGreetings.chainSyncedStatus, and the continuous drift value became ahydra_chain_drift_secondsmetric alongside a newhydra_chain_last_block_timestamp_secondsso a stalled chain backend is detectable even while drift is frozen #2769, #2749 - Made
hydra-chain-observerversion-aware: it detects which protocol version an observed transaction belongs to by matching head and deposit script hashes against a registry innetworks.jsoncovering 0.13.0 through 2.2.0, removing the compile-time coupling to a single version and thehydra-plutusdependency altogether #2740 - Fixed pasting into
hydra-tuitext fields (bracketed paste mode, so a paste arrives as one event and typingcinto an address no longer cancels the dialog) and stopped it submitting stale form values when the entered address or amount was invalid #2770 - Made the mac release binaries runnable without nix: they were hard-linking
libraries out of
/nix/storeand simply wouldn't launch on a plain machine #2795, #2461 - Bumped Mithril to 2630.0 and switched to the v2 database backend, since the aggregator no longer certifies v1 #2808
- Docs fixes: the
transaction-costbenchmark page is now generated by the docs build instead of being dropped in as raw markdown afterwards, so it renders with the current theme and stops listing removed transactions #2799, and the fanout cost table now sweeps party counts #2796
What's next?
- Complete the typst + Agda specification work, split into a reviewable stack: a
protocol fix forbidding a commit and a decommit in flight simultaneously
#2784, the prose
migration from LaTeX to Typst
#2785, the Agda
formalisation itself
#2786, a
hydra-agdapackage extracted via MAlonzo with a CI gate #2787, and differential tests checking the node and validator against that reference #2788 - Switch the event store to CBOR #2767 and offer an opt-in binary encoding on the client API #2762
- Iterate on ADR 34, covering the separation of
hydra-chain-observerinto a service shared by several nodes #2771 - Make
rejectLowDepositsa single pass rather than quadratic #2805 - Get a release out with the performance stack and selective partial fanout
