Skip to main content

Hydra Node Architecture

This document describes the architecture of the current implementation of a hydra-node. The following picture represents the main components of a Hydra node using the C4 Component Diagram notation.

Hydra ComponentsHydra Node[Container]«component»Persistence[JSON/FS]Persistsstateoftheheadondisk«component»HeadLogicMaintainsinternalHeadstateandprocessesevents«component»APIServerHandleclientcommands&queriesandservesoutputs«component»ChainConnectiontoCardanoObservetxson-chainandposttxtochain«component»WalletEmbeddedWallettosigntransactionsandpayfees«component»NetworkManagesconnectionstopeers«component»LoggingDumpJSONtostdout«component»MonitoringExposesPrometheusmetrics«external»«component»CardanoLedgerMaintainsLayer2State«container»HydraNode(peer)[Localcardano-node]«container»CardanoNode[Localcadano-node]«container»CardanoNode(peer)[Localcardano-node]«container»HydraClient«component»HydraSmartContracts[Plutus]On-chainsmartcontractscontrollingthebehaviouroftheprotocolon-chainHydraProtocolMessagesClientInput&ServerOutputObservation&OnChainTxApplyTxSigntransactionsUse.[N2Cprotocol].[N2Nprotocol].[N2Cprotocol].[HydraNetworkprotocol].[JSON/Websocket]
info

This diagram is manually produced using PlantUML graphing tool with C4 extensions.

$ plantuml -Tsvg architecture-c4.puml

Network

Network component is responsible for all of the communications related to the off-chain part of the Hydra protocol between hydra-nodes. The current implementation is based on the Typed Protocols library which is also at the heart of the Cardano node's networking. It's asynchronous by nature and is using a push based protocol with a uniform broadcast abstraction.

Messages are exchanged between nodes on different internal transitions and are authenticated using each peer Hydra Key: Each message sent is signed by the emitter and the signature is verified by the transmitter.

Chain Interaction

Chain

The Chain component is responsible for interfacing the Hydra node with the Cardano (aka. Layer 1) chain. The current, so-called Direct, implementation uses the Node-to-Client protocol to both "follow the chain" and observe new blocks and transactions which can change the state of the head, and submit transactions in response to client's requests or as needed to advance the protocol's state. It connects to a locally spun cardano-node using the local socket_and contains the _off-chain logic, based on cardano-api, that knows how to observe and build transactions relevant to the Hydra protocol. See ADR-10 for more details.

Wallet

The Hydra node maintains an internal wallet using the Cardano signing key provided to the hydra-node. This is used to handle the payment of transaction fees and signing transactions.

Head Logic

This is the component which is the heart of the Hydra node, implementing the protocol's input-output state machine. It is structured around the concepts of Events and Effects:

  • Events are inputs to the state machine from various parts of the node that can change the state and they ...
  • ... produce Effects which are outputs from the state machine interpreted by other components to produce "side-effects".

The Head Logic of course maintains the internal state of the head and persists it when it changes. This state consists in both the content of the Head itself (eg. current Ledger, transactions pending) and the data from the Layer 1 that's needed to observe and trigger on-chain transitions.

Hydra Smart Contracts

This "component" represents all of the Hydra smart contracts needed for Head protocol operation. Currently the contracts are written using Plutus-Tx. The scripts are optimized using custom ScriptContext and error codes for now.

API

hydra-node exposes an Asynchronous API through a Websocket server. This API is available to Hydra Client to send commands and observe changes in the state of the Hydra head. Upon startup, the API server loads all historical messages from persistence layer and serves them to clients in case they are interested in observing them.

Persistence

All API server outputs and the hydra-node state is preserved on disk. The persistence layer is responsible for loading the historical messages/hydra state from disk and also storing them. For the time being there was no need to make this layer more complex or use a database.

Logging

The Hydra node logs all side-effects occurring internally as JSON-formatted messages to the standard output stream attached to its process. The format of the logs is documented as a JSON schema, and follows the principles outlined in ADR-9.

Monitoring

The Hydra node optionally exposes Prometheus-compliant metrics through an HTTP server, on the standard /metrics endpoint.