Skip to main content

April 2023

· 9 min read
Sebastian Nagel
Arnaud Bailly
Sasha Bogicevic
Pascal Grange

This report summarizes the work on Hydra since March 2023. It serves as preparation for the monthly review meeting (see slides and the recording), where the team updates major project stakeholders on recent developments to gather their feedback on proposed plans.

Roadmap

The project roadmap was only slightly updated this month:

The latest roadmap with features and ideas

Notable roadmap updates

  • There are still many 💭 idea items on the roadmap, however, not on the current and next planned release columns. The process involves clarifying and refining each idea item into a 💬 feature before starting work on it. This includes giving equal consideration to new user 💭 ideas and requests.

  • Temporarily postponed the Hydra heads explorer #696 item until there is more clarity. While there aren't any major blockers,the explorer just requires further detailing, especially since we're currently in talks with existing Cardano explorer platforms.

  • Converted the aggregated multi-signature #193 from the concrete roadmap into an idea discussion #787. This is based on feedback from the community, and we believe that discussing it there would be more beneficial.

  • The main focus for the 0.10.0 release is implementing mainnet compatibility. This is mostly done and only requires some documentation and disclaimer updates. We're about to release 0.10.0, which will be the first mainnet-compatible version.

  • Meanwhile, work on the configurable API #380 was completed, which gave rise to new ideas and follow-up feature requests from users. One of them (Add HeadState/Snapshot to Greetings #823) was fairly straightforward and necessary to deliver a consistent, usable increment on the API with the upcoming release.

  • Prioritized Support timed transactions #196 higher as yet another use case would benefit from this.

The roadmap without idea items

Development

Issues and pull requests closed since last report

This month, the team worked on the following:

Configurable API

The API evolved a bit, driven by the issues our users reported #823 #813 #800 #789. Related changes were added to the API server so now our clients can:

  • Control the historical messages output. History messages can be displayed upon re/connection or not depending on client needs.
  • Snapshot UTXOs can optionally be disabled.
  • Transactions can be displayed in CBOR or JSON format.

Our clients can also have a nice insight into the current Hydra node state and head UTXOs that are now displayed as part of a Greetings message.

Next steps on the API level are to further fulfill user needs by grooming and implementing needed changes related to filtering, pagination etc.

Versioned docs and specification

Over the last couple of months the Hydra specification became an important artifact to use in discussion, review and potential audit of the Hydra Head protocol implementation. The document was now moved from overleaf into the Hydra repository, where it is properly versioned and built on each CI run. Changes can be proposed using our regular pull request worfklow and the final PDF is built and published to the website automatically.

Note that the above link points to the new /unstable version of the documentation, which holds the bleeding edge user manual, specification and API reference (which got a new sidebar) built directly from master. The normal, non-unstable version of the website is always referring to the last released version.

Specification on the Hydra website

Fixed scripts, Plutonomy and custom script contexts

As we made the specification use a more direct way to represent transactions (instead of the constraint emitting machine formalism), we realized that our scripts are not correctly ensuring script continuity. We identified these 'gaps' as red sections (see above) in the specification and worked on fixing them.

While the actual fix #777 was fairly straightforward and could easily be covered by our mutation-based contract tests, the script size increased and we could not publish all three Hydra scripts in a single publish transaction (which allows for a single --hydra-scripts-tx-id parameter on the hydra-node).

To mitigate this, we looked into the UPLC optimizer Plutonomy. Applying it was fairly simple, our tests did also pass, script sizes and costs also became lower. But, script size does not matter so much as we are using reference scripts and using a (not really maintained?) optimizer which introduces yet another question mark after compilation from plutus-tx to uplc was not our cup of tea right now at least (and we might pull this out of the drawer later).

There is an alternative: decoding ScriptContext involves quite some code, but we don't need everything in all validators. So we introduced a customscript context that only decodes the fields we need.

scripts@0.9.0fixesfixes + plutonomyfixes + custom ScriptContext
νInitial4621472736724300
νCommit2422251318162068
νHead8954949275799456 (no custom SC)
μHead4458453734684104

As part of this process, we also updated dependencies #826 to the latest cardano-node master. Although it didn't have an impact on script sizes, it's a crucial step towards preparing for upcoming hard-forks.

Rollback bug hunt

Opening our first head on mainnet failed. We didn't lose any funds, except for some fees, but the head just did not open. Exploring the logs, we figured out that a rollback happened while opening the head and there was a bug.

This is our test pyramid. It already contained some tests about the rollback but we decided to enrich our model-based tests to simulate rollbacks (before that, it used to run on a perfect blockchain). You can find more about our model-based test strategy in Model-Based Testing with QuickCheck.

test pyramid

Testing pyramide

The new property headOpensIfAllPartiesCommit helped prove the issue. At the end of the day, the problem came from a concurrency issue introduced while implementing ADR 18.

In the figure below, the DirectChain processes a new block, updating the chainState stored inside the headState. This also leads to an event being published to some event queue. Later, the HeadLogic (called Node in the picture) will process this event, updating the headState.

At the end of the process, we can see that the new headState points to a previousRecoverableState which contains the same chainState, chainState 1 instead of chainState 0. If a rollback then happens, the headState will be reverted to this previousRecoverableState and the fact that it contains chainState 1 instead of chainState 0 makes some on-chain observations impossible.

Race condition

Race condition

This explains the issue we had when opening our head:

  1. a commit A is observed on-chain;
  2. a rollback happens so that the headState forgets about this commit but not the chainState (remember, it's the wrong chainState);
  3. the commit is observed again on the chain but ignored by the chainState (because it has already seen it, it just ignores it);
  4. the headState will never hear about this commit again and so will never open the head, waiting forever for the missing commit.

We decided to implement the following solution:

  • A local chain state is re-introduced in the chain component, not shared with the head logic.
  • A copy of the chain state is kept in the head state to keep the benefits of ADR 18 regarding persistence.
  • The rollback event is removed from the API until #185.

possible solution

Possible solution

Rollback management is quite a tricky business. It might be the case that we've tried to be a bit too smart. So we're doing a rollback in our way of handling rollbacks until we focus on this topic again when dealing with this roadmap item: Handle rollbacks II.

Community

Hydra for Voting

The project is advancing and a basic vote tallying scenario in the Catalyst use case was demonstrated in the review meeting. The project is driving the API discussions as it is not using any Haskell tooling, but an application in Java with Aiken as the validator scripting language. Besides the catalyst use case, other scenarios like the ballot voting for the summit are also explored now.

Hydra for Auctions

A new demo was recorded in the wake of an upcoming Twitter space discussing auctions and NFT marketplaces with the community. The feature set currently includes starting the auction on L1, bidding on L1 or (and this is the novel thing!) transferring the auction from L1 to L2, such that it can be bid on L2.

Kupo x Hydra

In a good old pairing session between IOG and CF engineers, the integration of Kupo with Hydra was explored. This seems to be promising and work started here kupo#117. This will make it possible to run kupo natively connected to a hydra-node, very much it would run with cardano-node or ogmios. Kupo is a lightweight indexer of chain data like unspent transaction outputs and allows its clients to query information on-demand. 🐹

CBIA meetings

Hydra Team is now a regular participant to Cardano Blockchain Infrastructure Alliance meetings which happen more or less on a monthly basis. Hydra was featured during the meetup that happened while the team was on a workshop in Feldkirch and through this participation we hope to contribute to growth of the Cardano eco-system and position Hydra as a key infrastructure for builders.

Twitter space on scaling Cardano

This month we took part in a Twitter space about scaling Cardano and how Hydra can contribute to this. Thanks for conducting this @thepizzaknight_ 🙏

Conclusion

The monthly review meeting for April was held on 2023-04-26 via Google Meet with these slides and here is the recording.

Although it has been a busy month we could not cut a release, unfortunately.

We've experienced several setbacks due to the commits vs. rollbacks bug and oversized script sizes, which have slowed down our progress. Additionally, the back and forth on the API, which at times required creative and unconventional solutions, has also been time-intensive. However, we view this feedback as incredibly valuable, as it will ultimately make hydra-node more user-friendly and capable, albeit through a step-by-step process.

Associated projects in the greater Hydra community are moving ahead nicely due to the collaborative approach and tight loops of interaction between the individual teams.

All things considered, the project can be considered on track. We are very close to cutting our first mainnet-compatible release and the rising number of user requests and interested developers are good indicators that Hydra adoption is increasing.