You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Hydra node represents a significant engineering asset, providing layer 1 monitoring, peer to peer consensus, durable persistence, and an isomorphic Cardano ledger. Because of this, it is being eyed as a key building block not just in Hydra based applications, but other protocols as well.
14
+
*The Hydra node represents a significant engineering asset, providing layer 1 monitoring, peer to peer consensus, durable persistence, and an isomorphic Cardano ledger. Because of this, it is being eyed as a key building block not just in Hydra based applications, but other protocols as well.
15
15
16
-
One remaining difficulty in integrating Hydra into a fully productionalized software stack is the persistence model. Currently, the Hydra node achieves durability by writing a sequence of "StateChanged" events to disk. If a node is interrupted, upon restarting, it can replay just these events, ignoring their corresponding effects, to recover the same internal state it had when it was interrupted. However, downstream consumers don't have the same luxury.
16
+
* Currently the `hydra-node` uses a very basic persistence mechanism for it's internal `HeadState`, that is saving `StateChanged` events to file on disk and reading them back to load and re-aggregate the `HeadState` upon startup.
17
+
- Some production setups would benefit from storing these events to a service like Amazon Kinesis data stream instead of local files.
17
18
18
-
We propose generalizing the persistence mechanism to open the door to a plugin based approach to extending the Hydra node.
19
+
* The `hydra-node` websocket-based API is the only available event stream right now and might not fit all purposes.
20
+
- See also ADR [3](/adr/3) and [25](/adr/25)
21
+
- Internally, this is realized as a single `Server` handle which can `sendOutput :: ServerOutput tx -> m ()`
22
+
- These `ServerOutput`s closely relate to `StateChanged` events and `ClientEffect`s are yielded by the logic layer often together with the `StateChanged`. For example:
* Users of `hydra-node` are interested to add alternative implementations for storing, loading and consuming events of the Hydra protocol.
19
30
20
31
# Decision
21
32
22
-
We propose adding a "persistence combinator", which can combine one or more "persistenceIncremental" instances.
33
+
* We create two new interfaces in the `hydra-node` architecture:
34
+
35
+
-```data EventSource e m = EventSource { getEvents :: m [e] }```
36
+
-```data EventSink e m = EventSink { putEvent :: e -> m () }```
37
+
38
+
* We realize our current `PersistenceIncremental` used for persisting `StateChanged` events is both an `EventSource` and an `EventSink`
23
39
24
-
When appending to the combinator, it will forward the append to each persistence mechanism.
40
+
* We drop the `persistence` from the main handle `HydraNode tx m`, add **one**`EventSource` and allow **many**`EventSinks`
25
41
26
-
As the node starts up, as part of recovering the node state, it will also ensure "at least once" semantics for each persistence mechanism. It will maintain a notion of a "primary" instance, from which events are loaded, and "secondary instances", which are given the opportunity to re-observe each event.
42
+
```hs
43
+
dataHydraNodetxm=HydraNode
44
+
{-- ...
45
+
, eventSource::EventSource (StateChangedtx) m
46
+
, eventSinks:: [EventSink (StateChangedtx) m]
47
+
}
48
+
```
27
49
28
-
Each persistence mechanism will be responsible for it's own durability; for example, it may maintain its own checkpoint, and only re-broadcast the event if its after the checkpoint.
50
+
*The`stepHydraNode` main loop does call `putEvent` on all`eventSinks`insequence.
51
+
52
+
-TBD: transaction semantics? what happens if one fails?
29
53
30
-
The exact implementation details of the above are left unspecified, to allow some flexibility and experimentation on the exact mechanism to realize these goals.
54
+
*Thedefault `hydra-node` main loop does use the file-based `EventSource` and a single file-based `EventSink` (using the same file).
55
+
56
+
*TBD:As the node starts up, when loading events from the `EventSource`, it will also ensure "at least once" semantics for each `EventSink`.
57
+
58
+
*We realize that the `EventSource` and `EventSink` handles, as well as their aggregation in `HydraNode` are used as an API by forks of the `hydra-node` and try to minimize changes to it.
31
59
32
60
## Consequences
33
61
34
-
Here are the consequences we forsee from this change:
35
-
- The default operation of the node remains unchanged
36
-
- Projects forking the hydra node have a natively supported mechanism to extend node persistence
37
-
- These extensions can preserve robust "at least once" semantics for each hydra event
38
-
- Sundae Labs will build a "Save transaction batches to S3" proof of concept extension
39
-
- Sundae Labs will build a "Scrolls source" proof of concept integration
40
-
- This may also enable a future ADRs for dynamically loaded plugins without having to fork the Hydra node at all
62
+
*TODO:Naming conflicts / overloaded terms -> should resolve by calling something not"Event"?
63
+
64
+
*Thedefault operation of the `hyda-node` remains unchanged
65
+
*TheAPI `Server` can be modelled and refactored as an `EventSink`
66
+
-TBD:Do `Network` and `Chain` parts qualify as `EventSink`s as well or shall those be triggered by `Effect`s still?
67
+
*Projects forking the hydra node have a natively supported mechanism to extend node persistence
68
+
*These extensions can preserve robust "at least once" semantics for each hydra event
69
+
*SundaeLabs can build a "Save transaction batches to S3" proof of concept `EventSink`
70
+
*SundaeLabs can build a "Scrolls source" `EventSink`
71
+
*SundaeLabs can build a "Amazon Kinesis" `EventSource` and `EventSink`
72
+
*Extension points like `EventSource` and `EventSink` could be dynamically loaded as plugins without having to fork `hydra-node` (maybein a future ADR)
0 commit comments