20. Handling time
Status
Accepted
Context
-
The Hydra Head protocol is expected to be isomorphic to the ledger it runs on. That means, it should support the same transaction formats and (if desired) use the same ledger rules as the layer 1.
-
Cardano is our layer 1 and its consensus layer separates time into discrete steps, where each step is called a
Slot. The network is expected to evolve strictly monotonically on this time scale and so slot numbers (SlotNo) are always increasing. -
The Cardano mainnet has a block scheduled every 20 seconds, although it may take longer.
- This is because
slotLength = 1.0and every 20th slot is "active" withf = 0.05. - The consensus protocol requires
kblocks to be produced within3k/fslots, wherek = 2160on mainnet.
- This is because
-
Transactions on Cardano may have a validity range with a lower and upper bound given as
SlotNo. -
Wall-clock time can be converted to slots (and back) using an
EraHistoryorEpochInterpreterprovided by the consensus layer of the cardano node. This is required as the slot lengths could change over time.- All past points in time since the
SystemStartcan be converted. - Future points in time can only be converted in the "safe zone", practically being at least
3k/fslots (TODO: cross check). Refer to chapter 17 Time on the consensus spec for more details.
- All past points in time since the
-
The Hydra Head protocol allows
closeandcontesttransactions only up before a deadlineT_final, andfanouttransactions after the deadline.- In the current implementation the deadline is upper validity of
closedplus the contestation period. - We also consider protocol variants which push out the deadline by the contestation period on each
contest. - Contestation periods may very well be longer than the stability window of the protocol. For example: 7 days, while the mainnet stability window is more like 36 hours.
- In the current implementation the deadline is upper validity of
-
We have encountered two problems with handling time in the past
- Trying to convert wall-clock time to slots of the Head protocol deadline led to
PastHorizonException(when using very low security parameterk) - Trying to
fanoutafter the deadline, but before another block has been seen by the L1 ledger led toOutsideValidityIntervalUTxO.
- Trying to convert wall-clock time to slots of the Head protocol deadline led to
-
The second problem scenario and solution ideas are roughly visible on this whiteboard:

Decision
-
The head logic uses wall-clock time to track time and only convert to/from slots when constructing/observing transactions in the chain layer.
- This ensures that transactions we post or see on the chain can be converted to/from slots.
- The head logic would use
UTCTimefor points in time andNominalDiffTimefor durations. - The chain layer converts these using the
SystemStartandEraHistoryintoSlotNo.
-
The chain layer informs the logic layer whenever time passed (on the chain) using a new
Tickevent.- For the direct chain implementation, this is whenever we see a block in the chain sync protocol.
- Per above decision, the
Tickshall contain aUTCTimecorresponding to the new "now" as seen through the block chain.
Consequences
-
Conversion from
UTCTime -> SlotNoand vice versa stays local to the chain layer. -
The
HeadLogiccan track chain time in its state and conditionReadyToFanoutupon seeing it pass the deadline.- Ensures clients only see
ReadyToFanoutwhen a followingFanoutwould be really possible. - Makes the
Delayeffect redundant and we can remove it (only delay via reenqueue on theWaitoutcome)
- Ensures clients only see
-
By introducing
Tickevents,IOSimwill not be able to detect non-progress (deadlocks).- This means we cannot rely on early exit of simulations anymore and need to determine meaningful simulation endings instead of
waitUntilTheEndOfTime.
- This means we cannot rely on early exit of simulations anymore and need to determine meaningful simulation endings instead of
-
We get a first, rough notion of time for free in our L2 and can support "timed transactions" with same resolution as the L1.
- Tracking time in the state makes it trivial to provide it to the ledger when we
applyTransaction. - Of course we could extend the fidelity of this feature using the system clock for "dead reckoning" between blocks. The conversion of wall clock to slot could even be configurable using an L2
slotLengthanalogous to L1 (although we might not want/need this).
- Tracking time in the state makes it trivial to provide it to the ledger when we

