Skip to content

Commit d437acc

Browse files
committed
add helper to init node state
> also rename DraftHydraNode and HydraNode nodeState field no nodeStateHandler to avoid confusion
1 parent ecfa150 commit d437acc

File tree

8 files changed

+43
-58
lines changed

8 files changed

+43
-58
lines changed

hydra-node/src/Hydra/API/Server.hs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ import Hydra.API.ServerOutputFilter (
3030
import Hydra.API.WSServer (wsApp)
3131
import Hydra.Cardano.Api (LedgerEra)
3232
import Hydra.Chain (Chain (..))
33-
import Hydra.Chain.ChainState (IsChainState, chainStateSlot)
33+
import Hydra.Chain.ChainState (IsChainState)
3434
import Hydra.Chain.Direct.State ()
3535
import Hydra.Events (EventSink (..), EventSource (..))
3636
import Hydra.HeadLogic (
3737
Deposit (..),
3838
HeadState (..),
39-
IdleState (..),
4039
InitialState (..),
4140
NodeState (..),
4241
OpenState (..),
4342
aggregateNodeState,
4443
)
4544
import Hydra.HeadLogic.Outcome qualified as StateChanged
45+
import Hydra.HeadLogic.State (initNodeState)
4646
import Hydra.HeadLogic.StateEvent (StateEvent (..))
4747
import Hydra.Logging (Tracer, traceWith)
4848
import Hydra.Network (IP, PortNumber)
@@ -100,16 +100,7 @@ withAPIServer config env party eventSource tracer chain pparams serverOutputFilt
100100
responseChannel <- newBroadcastTChanIO
101101
-- Initialize our read models from stored events
102102
-- NOTE: we do not keep the stored events around in memory
103-
nodeStateP <-
104-
mkProjection
105-
"nodeStateP"
106-
( NodeState
107-
{ headState = Idle $ IdleState mkChainState
108-
, pendingDeposits = mempty
109-
, currentSlot = chainStateSlot mkChainState
110-
}
111-
)
112-
aggregateNodeState
103+
nodeStateP <- mkProjection "nodeStateP" (initNodeState mkChainState) aggregateNodeState
113104
-- XXX: We never subscribe to changes of commitInfoP et al directly so a
114105
-- single read model and normal functions mapping from HeadState ->
115106
-- CommitInfo etc. would suffice and are less fragile

hydra-node/src/Hydra/HeadLogic/State.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module Hydra.HeadLogic.State where
77
import Hydra.Prelude
88

99
import Data.Map qualified as Map
10-
import Hydra.Chain.ChainState (ChainSlot, ChainStateType)
10+
import Hydra.Chain.ChainState (ChainSlot, IsChainState (..))
1111
import Hydra.Tx (
1212
HeadId,
1313
HeadParameters,
@@ -33,7 +33,7 @@ data NodeState tx = NodeState
3333
, pendingDeposits :: PendingDeposits tx
3434
-- ^ Pending deposits as observed on chain.
3535
-- TODO: could even move the chain state here (also see todo below)
36-
-- , chainState :: ChaiStateType tx
36+
-- , chainState :: ChainStateType tx
3737
, currentSlot :: ChainSlot
3838
}
3939
deriving stock (Generic)
@@ -46,6 +46,14 @@ deriving stock instance (IsTx tx, Show (ChainStateType tx)) => Show (NodeState t
4646
deriving anyclass instance (IsTx tx, ToJSON (ChainStateType tx)) => ToJSON (NodeState tx)
4747
deriving anyclass instance (IsTx tx, FromJSON (ChainStateType tx)) => FromJSON (NodeState tx)
4848

49+
initNodeState :: IsChainState tx => ChainStateType tx -> NodeState tx
50+
initNodeState chainState =
51+
NodeState
52+
{ headState = Idle IdleState{chainState}
53+
, pendingDeposits = mempty
54+
, currentSlot = chainStateSlot chainState
55+
}
56+
4957
-- | The main state of the Hydra protocol state machine. It holds both, the
5058
-- overall protocol state, but also the off-chain 'CoordinatedHeadState'.
5159
--

hydra-node/src/Hydra/Node.hs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ import Hydra.Chain (
2929
PostTxError,
3030
initHistory,
3131
)
32-
import Hydra.Chain.ChainState (ChainStateType, IsChainState, chainStateSlot)
32+
import Hydra.Chain.ChainState (ChainStateType, IsChainState)
3333
import Hydra.Events (EventId, EventSink (..), EventSource (..), getEventId, putEventsToSinks)
3434
import Hydra.Events.Rotation (EventStore (..))
3535
import Hydra.HeadLogic (
3636
Effect (..),
3737
HeadState (..),
38-
IdleState (..),
3938
Input (..),
4039
NodeState (..),
4140
Outcome (..),
@@ -46,7 +45,7 @@ import Hydra.HeadLogic (
4645
)
4746
import Hydra.HeadLogic qualified as HeadLogic
4847
import Hydra.HeadLogic.Outcome (StateChanged (..))
49-
import Hydra.HeadLogic.State (getHeadParameters)
48+
import Hydra.HeadLogic.State (getHeadParameters, initNodeState)
5049
import Hydra.HeadLogic.StateEvent (StateEvent (..))
5150
import Hydra.Ledger (Ledger)
5251
import Hydra.Logging (Tracer, traceWith)
@@ -160,7 +159,7 @@ data DraftHydraNode tx m = DraftHydraNode
160159
{ tracer :: Tracer m (HydraNodeLog tx)
161160
, env :: Environment
162161
, ledger :: Ledger tx
163-
, nodeState :: NodeStateHandler tx m
162+
, nodeStateHandler :: NodeStateHandler tx m
164163
, inputQueue :: InputQueue m (Input tx)
165164
, eventSource :: EventSource (StateEvent tx) m
166165
, eventSinks :: [EventSink (StateEvent tx) m]
@@ -209,19 +208,14 @@ hydrate tracer env ledger initialChainState EventStore{eventSource, eventSink} e
209208
{ tracer
210209
, env
211210
, ledger
212-
, nodeState = nodeStateHandler
211+
, nodeStateHandler
213212
, inputQueue
214213
, eventSource
215214
, eventSinks = eventSink : eventSinks
216215
, chainStateHistory
217216
}
218217
where
219-
initialState =
220-
NodeState
221-
{ headState = Idle IdleState{chainState = initialChainState}
222-
, pendingDeposits = mempty
223-
, currentSlot = chainStateSlot initialChainState
224-
}
218+
initialState = initNodeState initialChainState
225219

226220
recoverNodeStateC =
227221
mapC stateChanged
@@ -270,16 +264,16 @@ connect ::
270264
DraftHydraNode tx m ->
271265
m (HydraNode tx m)
272266
connect chain network server node =
273-
pure HydraNode{tracer, env, ledger, nodeState, inputQueue, eventSource, eventSinks, oc = chain, hn = network, server}
267+
pure HydraNode{tracer, env, ledger, nodeStateHandler, inputQueue, eventSource, eventSinks, oc = chain, hn = network, server}
274268
where
275-
DraftHydraNode{tracer, env, ledger, nodeState, inputQueue, eventSource, eventSinks} = node
269+
DraftHydraNode{tracer, env, ledger, nodeStateHandler, inputQueue, eventSource, eventSinks} = node
276270

277271
-- | Fully connected hydra node with everything wired in.
278272
data HydraNode tx m = HydraNode
279273
{ tracer :: Tracer m (HydraNodeLog tx)
280274
, env :: Environment
281275
, ledger :: Ledger tx
282-
, nodeState :: NodeStateHandler tx m
276+
, nodeStateHandler :: NodeStateHandler tx m
283277
, inputQueue :: InputQueue m (Input tx)
284278
, eventSource :: EventSource (StateEvent tx) m
285279
, eventSinks :: [EventSink (StateEvent tx) m]
@@ -354,12 +348,12 @@ processNextInput ::
354348
HydraNode tx m ->
355349
Input tx ->
356350
STM m (Outcome tx)
357-
processNextInput HydraNode{nodeState, ledger, env} e =
351+
processNextInput HydraNode{nodeStateHandler, ledger, env} e =
358352
modifyNodeState $ \s ->
359353
let outcome = computeOutcome s e
360354
in (outcome, aggregateState s outcome)
361355
where
362-
NodeStateHandler{modifyNodeState} = nodeState
356+
NodeStateHandler{modifyNodeState} = nodeStateHandler
363357

364358
computeOutcome = HeadLogic.update env ledger
365359

@@ -373,7 +367,7 @@ processStateChanges node stateChanges = do
373367
where
374368
HydraNode
375369
{ eventSinks
376-
, nodeState = NodeStateHandler{getNextEventId}
370+
, nodeStateHandler = NodeStateHandler{getNextEventId}
377371
} = node
378372

379373
processEffects ::

hydra-node/src/Hydra/Node/Run.hs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ import Hydra.Chain (ChainComponent, ChainStateHistory, maximumNumberOfParties)
2222
import Hydra.Chain.Backend (ChainBackend (queryGenesisParameters))
2323
import Hydra.Chain.Blockfrost (BlockfrostBackend (..))
2424
import Hydra.Chain.Cardano (withCardanoChain)
25-
import Hydra.Chain.ChainState (IsChainState (..), chainStateSlot)
25+
import Hydra.Chain.ChainState (IsChainState (..))
2626
import Hydra.Chain.Direct (DirectBackend (..))
2727
import Hydra.Chain.Direct.State (initialChainState)
2828
import Hydra.Chain.Offline (loadGenesisFile, withOfflineChain)
2929
import Hydra.Events (EventSink)
3030
import Hydra.Events.FileBased (mkFileBasedEventStore)
3131
import Hydra.Events.Rotation (EventStore (..), RotationConfig (..), newRotatedEventStore)
3232
import Hydra.HeadLogic (aggregateNodeState)
33-
import Hydra.HeadLogic.State (HeadState (..), IdleState (..), NodeState (..))
33+
import Hydra.HeadLogic.State (NodeState (..), initNodeState)
3434
import Hydra.HeadLogic.StateEvent (StateEvent (StateEvent, stateChanged), mkCheckpoint)
3535
import Hydra.Ledger (Ledger)
3636
import Hydra.Ledger.Cardano (cardanoLedger, newLedgerEnv)
@@ -150,12 +150,7 @@ run opts = do
150150
Nothing ->
151151
pure eventStore
152152
Just rotationConfig -> do
153-
let initialState =
154-
NodeState
155-
{ headState = Idle IdleState{chainState = initialChainState}
156-
, pendingDeposits = mempty
157-
, currentSlot = chainStateSlot initialChainState
158-
}
153+
let initialState = initNodeState initialChainState
159154
let aggregator :: IsChainState tx => NodeState tx -> StateEvent tx -> NodeState tx
160155
aggregator s StateEvent{stateChanged} = aggregateNodeState s stateChanged
161156
newRotatedEventStore rotationConfig initialState aggregator mkCheckpoint eventStore

hydra-node/test/Hydra/BehaviorSpec.hs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ import Hydra.Chain.ChainState (ChainSlot (ChainSlot), ChainStateType, IsChainSta
3333
import Hydra.Chain.Direct.Handlers (LocalChainState, getLatest, newLocalChainState, pushNew, rollback)
3434
import Hydra.Events (EventSink (..))
3535
import Hydra.Events.Rotation (EventStore (..))
36-
import Hydra.HeadLogic (CoordinatedHeadState (..), Effect (..), HeadState (..), IdleState (..), InitialState (..), Input (..), NodeState (..), OpenState (..))
36+
import Hydra.HeadLogic (CoordinatedHeadState (..), Effect (..), HeadState (..), InitialState (..), Input (..), NodeState (..), OpenState (..))
37+
import Hydra.HeadLogic.State (initNodeState)
3738
import Hydra.HeadLogicSpec (testSnapshot)
3839
import Hydra.Ledger (Ledger, nextChainSlot)
3940
import Hydra.Ledger.Simple (SimpleChainState (..), SimpleTx (..), aValidTx, simpleLedger, utxoRef, utxoRefs)
@@ -1288,14 +1289,14 @@ createTestHydraClient ::
12881289
TVar m [ServerOutput tx] ->
12891290
HydraNode tx m ->
12901291
TestHydraClient tx m
1291-
createTestHydraClient outputs messages outputHistory HydraNode{inputQueue, nodeState} =
1292+
createTestHydraClient outputs messages outputHistory HydraNode{inputQueue, nodeStateHandler} =
12921293
TestHydraClient
12931294
{ send = enqueue inputQueue . ClientInput
12941295
, waitForNext = atomically (readTQueue outputs)
12951296
, waitForNextMessage = atomically (readTQueue messages)
12961297
, injectChainEvent = enqueue inputQueue . ChainInput
12971298
, serverOutputs = reverse <$> readTVarIO outputHistory
1298-
, queryState = atomically (queryNodeState nodeState)
1299+
, queryState = atomically (queryNodeState nodeStateHandler)
12991300
}
13001301

13011302
createHydraNode ::
@@ -1324,7 +1325,7 @@ createHydraNode tracer ledger chainState signingKey otherParties outputs message
13241325
modifyTVar' outputHistory (output :)
13251326
}
13261327
-- NOTE: Not using 'hydrate' as we don't want to run the event source conduit.
1327-
let nodeState = NodeState{headState = Idle IdleState{chainState}, pendingDeposits = mempty, currentSlot = ChainSlot 0}
1328+
let nodeState = initNodeState chainState
13281329
let chainStateHistory = initHistory chainState
13291330
nodeStateHandler <- createNodeStateHandler Nothing nodeState
13301331
inputQueue <- createInputQueue
@@ -1335,7 +1336,7 @@ createHydraNode tracer ledger chainState signingKey otherParties outputs message
13351336
{ tracer
13361337
, env
13371338
, ledger
1338-
, nodeState = nodeStateHandler
1339+
, nodeStateHandler
13391340
, inputQueue
13401341
, eventSource
13411342
, eventSinks = [apiSink, eventSink]

hydra-node/test/Hydra/Events/RotationSpec.hs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import Hydra.Chain (OnChainTx (..))
99
import Hydra.Chain.ChainState (ChainSlot (..), IsChainState)
1010
import Hydra.Events (EventId, EventSink (..), HasEventId (..), getEvents)
1111
import Hydra.Events.Rotation (EventStore (..), RotationConfig (..), newRotatedEventStore)
12-
import Hydra.HeadLogic (HeadState (..), IdleState (..), NodeState (..), StateChanged (..), aggregateNodeState)
12+
import Hydra.HeadLogic (HeadState (..), NodeState (..), StateChanged (..), aggregateNodeState)
13+
import Hydra.HeadLogic.State (initNodeState)
1314
import Hydra.HeadLogic.StateEvent (StateEvent (..), mkCheckpoint)
1415
import Hydra.Ledger.Simple (SimpleChainState (..), SimpleTx, simpleLedger)
1516
import Hydra.Logging (showLogsOnFailure)
@@ -44,7 +45,7 @@ spec = parallel $ do
4445
-- NOTE: because there will be 5 inputs processed in total,
4546
-- this is hardcoded to ensure we get a checkpoint + a single event at the end
4647
let rotationConfig = RotateAfter (Positive 3)
47-
let s0 = NodeState{headState = Idle IdleState{chainState = SimpleChainState{slot = ChainSlot 0}}, pendingDeposits = mempty, currentSlot = ChainSlot 0}
48+
let s0 = initNodeState SimpleChainState{slot = ChainSlot 0}
4849
rotatingEventStore <- newRotatedEventStore rotationConfig s0 mkAggregator mkCheckpoint eventStore
4950
testHydrate rotatingEventStore []
5051
>>= notConnect
@@ -58,7 +59,7 @@ spec = parallel $ do
5859
-- NOTE: because there will be 6 inputs processed in total,
5960
-- this is hardcoded to ensure we get a single checkpoint event at the end
6061
let rotationConfig = RotateAfter (Positive 1)
61-
let s0 = NodeState{headState = Idle IdleState{chainState = SimpleChainState{slot = ChainSlot 0}}, pendingDeposits = mempty, currentSlot = ChainSlot 0}
62+
let s0 = initNodeState SimpleChainState{slot = ChainSlot 0}
6263
rotatingEventStore <- newRotatedEventStore rotationConfig s0 mkAggregator mkCheckpoint eventStore
6364
testHydrate rotatingEventStore []
6465
>>= notConnect
@@ -87,7 +88,7 @@ spec = parallel $ do
8788
-- this is hardcoded to ensure we get a single checkpoint event at the end
8889
let rotationConfig = RotateAfter (Positive 1)
8990
-- run rotated event store with prepared inputs
90-
let s0 = NodeState{headState = Idle IdleState{chainState = SimpleChainState{slot = ChainSlot 0}}, pendingDeposits = mempty, currentSlot = ChainSlot 0}
91+
let s0 = initNodeState SimpleChainState{slot = ChainSlot 0}
9192
rotatingEventStore <- newRotatedEventStore rotationConfig s0 mkAggregator mkCheckpoint eventStore
9293
testHydrate rotatingEventStore []
9394
>>= notConnect
@@ -113,7 +114,7 @@ spec = parallel $ do
113114
let inputs1 = take 3 inputs
114115
let inputs2 = drop 3 inputs
115116
failAfter 1 $ do
116-
let s0 = NodeState{headState = Idle IdleState{chainState = SimpleChainState{slot = ChainSlot 0}}, pendingDeposits = mempty, currentSlot = ChainSlot 0}
117+
let s0 = initNodeState SimpleChainState{slot = ChainSlot 0}
117118
-- NOTE: because there will be 6 inputs processed in total,
118119
-- this is hardcoded to ensure we get a single checkpoint event at the end
119120
let rotationConfig = RotateAfter (Positive 1)

hydra-node/test/Hydra/HeadLogicSpec.hs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import Hydra.Chain (
2828
)
2929
import Hydra.Chain.ChainState (ChainSlot (..), IsChainState)
3030
import Hydra.Chain.Direct.State ()
31-
import Hydra.HeadLogic (ClosedState (..), CoordinatedHeadState (..), Effect (..), HeadState (..), IdleState (..), InitialState (..), Input (..), LogicError (..), NodeState (..), OpenState (..), Outcome (..), RequirementFailure (..), SideLoadRequirementFailure (..), StateChanged (..), TTL, WaitReason (..), aggregateState, cause, noop, update)
32-
import Hydra.HeadLogic.State (SeenSnapshot (..), getHeadParameters)
31+
import Hydra.HeadLogic (ClosedState (..), CoordinatedHeadState (..), Effect (..), HeadState (..), InitialState (..), Input (..), LogicError (..), NodeState (..), OpenState (..), Outcome (..), RequirementFailure (..), SideLoadRequirementFailure (..), StateChanged (..), TTL, WaitReason (..), aggregateState, cause, noop, update)
32+
import Hydra.HeadLogic.State (SeenSnapshot (..), getHeadParameters, initNodeState)
3333
import Hydra.Ledger (Ledger (..), ValidationError (..))
3434
import Hydra.Ledger.Cardano (cardanoLedger, mkRangedTx)
3535
import Hydra.Ledger.Cardano.TimeSpec (genUTCTime)
@@ -1072,12 +1072,7 @@ connectivityChanged ttl connectivityMessage =
10721072
}
10731073

10741074
inIdleState :: NodeState SimpleTx
1075-
inIdleState =
1076-
NodeState
1077-
{ headState = Idle IdleState{chainState = SimpleChainState{slot = ChainSlot 0}}
1078-
, pendingDeposits = mempty
1079-
, currentSlot = ChainSlot 0
1080-
}
1075+
inIdleState = initNodeState SimpleChainState{slot = ChainSlot 0}
10811076

10821077
-- XXX: This is always called with threeParties and simpleLedger
10831078
inInitialState :: [Party] -> NodeState SimpleTx

hydra-node/test/Hydra/Model/MockChain.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ mockChainAndNetwork tr seedKeys commits = do
224224
Nothing -> error "closeWithInitialSnapshot: Could not find matching HydraNode"
225225
Just
226226
MockHydraNode
227-
{ node = HydraNode{oc = Chain{postTx}, nodeState = NodeStateHandler{queryNodeState}}
227+
{ node = HydraNode{oc = Chain{postTx}, nodeStateHandler = NodeStateHandler{queryNodeState}}
228228
} -> do
229229
NodeState{headState = hs} <- atomically queryNodeState
230230
case hs of

0 commit comments

Comments
 (0)