1
1
module Statebox.Protocol where
2
2
3
3
import Prelude
4
- import Data.Either (Either (..))
4
+ import Data.Either (Either (..), either )
5
5
import Data.Either.Nested (type (\/))
6
6
import Data.Lens ((^?))
7
7
import Data.Maybe (Maybe (..), maybe )
8
8
9
+ import Data.Petrinet.Representation.Marking (emptyMarking )
9
10
import Statebox.Core.Lenses (_firingExecution )
10
-
11
11
import Statebox.Core.Transaction (FiringTx , HashStr , HashTx , InitialTx , TxId , TxSum (..), WiringTx , evalTxSum , isInitialTx , isUberRootHash )
12
- -- import Statebox.Protocol.Fire (fire)
12
+ import Statebox.Protocol.Fire (fire )
13
13
import Statebox.Protocol.Store (getTransaction , putTransaction , getExecutionState , updateExecutionState ) as Store
14
14
import Statebox.Protocol.Store (StoreActions )
15
15
@@ -20,25 +20,37 @@ data ProcessError
20
20
= NoUberRoot
21
21
22
22
-- | The previous transaction of a root (initial) transaction should be an über-root.
23
- | InitialPreviousShouldBeUberRoot TxId
23
+ | InitialPreviousShouldBeUberRoot TxId
24
24
25
25
-- | The previous transaction of a `Wiring` transaction should be a root (initial) transaction.
26
- | WiringPreviousShouldBeInitial TxId
26
+ | WiringPreviousShouldBeInitial TxId
27
27
28
28
-- | If an execution already exists, we cannot store it again.
29
- | FiringInitialShouldBeCreatedOnlyOnce TxId
29
+ | FiringInitialShouldBeCreatedOnlyOnce TxId
30
30
31
31
-- | The previous transaction of an initial transaction ('execution transaction') should exist.
32
- | FiringInitialShouldHavePrevious TxId
32
+ | FiringInitialShouldHavePrevious TxId
33
33
34
34
-- | The previous transaction of an initial transaction ('execution transaction') should be a `Wiring`.
35
- | FiringInitialPreviousShouldBeWiring TxId
35
+ | FiringInitialPreviousShouldBeWiring TxId
36
+
37
+ -- | The first transition fired should be initial.
38
+ | FiringInitialTransitionShouldBeInitial TxId
36
39
37
40
-- | A normal firing should refer to an existing execution.
38
- | FiringNormalShouldHaveExistingExecution TxId ExecutionId
41
+ | FiringNormalShouldHaveExistingExecution TxId ExecutionId
39
42
40
43
-- | The previous transaction of a normal firing should match the current execution state.
41
- | FiringNormalPreviousShouldMatchCurrentState TxId ExecutionId
44
+ | FiringNormalPreviousShouldMatchCurrentState TxId ExecutionId
45
+
46
+ -- | The execution of a firing should refer to an existing wiring.
47
+ | FiringNormalExecutionShouldPointToExistingWiring TxId ExecutionId
48
+
49
+ -- | The wiring of the execution of a normal firing should be a `Wiring`.
50
+ | FiringNormalExecutionWiringShouldBeAWiring TxId ExecutionId
51
+
52
+ -- | The fired transition should be enabled.
53
+ | FiringNormalTransitionShouldBeEnabled TxId ExecutionId
42
54
43
55
processTxSum :: HashTx -> StoreActions (ProcessError \/ Unit )
44
56
processTxSum hashTx = case hashTx.tx of
@@ -95,16 +107,19 @@ processInitialFiringTx hash firingTx = do
95
107
-- previous not found
96
108
Nothing -> pure $ Left $ FiringInitialShouldHavePrevious hash
97
109
-- previous found
98
- Just previous -> do
110
+ Just previous ->
99
111
evalTxSum
100
112
(const $ pure $ Left $ FiringInitialPreviousShouldBeWiring hash)
101
113
(const $ pure $ Left $ FiringInitialPreviousShouldBeWiring hash)
102
- (\wiringTx -> map Right $ do
103
- -- let firedTransition = fire firingTx
104
- Store .putTransaction hash $ FiringTxInj firingTx
105
- Store .updateExecutionState hash $ { lastFiring: hash
106
- , wiring: firingTx.previous
107
- }
114
+ (\wiringTx -> either
115
+ (const $ pure $ Left $ FiringInitialTransitionShouldBeInitial hash)
116
+ (\newMarking -> map Right $ do
117
+ Store .putTransaction hash $ FiringTxInj firingTx
118
+ Store .updateExecutionState hash $ { lastFiring: hash
119
+ , wiring: firingTx.previous
120
+ , marking: newMarking
121
+ })
122
+ (fire wiringTx.wiring firingTx.firing emptyMarking)
108
123
)
109
124
(const $ pure $ Left $ FiringInitialPreviousShouldBeWiring hash)
110
125
previous
@@ -119,10 +134,23 @@ processNormalFiringTx hash firingTx executionHash = do
119
134
Just execution -> do
120
135
-- check if the previous transaction corresponds to the current state of the execution
121
136
if firingTx.previous == execution.lastFiring
122
- then map Right $ do
123
- -- fire transition
124
- Store .putTransaction hash $ FiringTxInj firingTx
125
- Store .updateExecutionState executionHash { lastFiring: hash
126
- , wiring: execution.wiring
127
- }
137
+ then do
138
+ maybeWiring <- Store .getTransaction execution.wiring
139
+ case maybeWiring of
140
+ Nothing -> pure $ Left $ FiringNormalExecutionShouldPointToExistingWiring hash executionHash
141
+ Just transaction ->
142
+ evalTxSum
143
+ (const $ pure $ Left $ FiringNormalExecutionWiringShouldBeAWiring hash executionHash)
144
+ (const $ pure $ Left $ FiringNormalExecutionWiringShouldBeAWiring hash executionHash)
145
+ (\wiringTx -> either
146
+ (const $ pure $ Left $ FiringNormalTransitionShouldBeEnabled hash executionHash)
147
+ (\newMarking -> map Right $ do
148
+ Store .putTransaction hash $ FiringTxInj firingTx
149
+ Store .updateExecutionState executionHash { lastFiring: hash
150
+ , wiring: execution.wiring
151
+ , marking: newMarking
152
+ })
153
+ (fire wiringTx.wiring firingTx.firing execution.marking))
154
+ (const $ pure $ Left $ FiringNormalExecutionWiringShouldBeAWiring hash executionHash)
155
+ transaction
128
156
else pure $ Left $ FiringNormalPreviousShouldMatchCurrentState hash executionHash
0 commit comments