Skip to content

Commit b4fd0c7

Browse files
committed
Replace mutating status with query
1 parent b08d073 commit b4fd0c7

6 files changed

Lines changed: 77 additions & 54 deletions

File tree

lib/PSR/Events/Interface.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Data.Maybe (isNothing)
1414
import Data.Text (Text)
1515
import Data.Time.Clock (UTCTime)
1616
import GHC.Generics (Generic)
17+
import PSR.Types (BlockStatus)
1718
import PlutusLedgerApi.Common (Data, MajorProtocolVersion, PlutusLedgerLanguage)
1819

1920
data EventType
@@ -34,6 +35,7 @@ data Event = Event
3435
, slotNo :: C.SlotNo
3536
, createdAt :: UTCTime
3637
, payload :: EventPayload
38+
, blockStatus :: BlockStatus
3739
}
3840
deriving (Generic)
3941

lib/PSR/Storage/SQLite.hs

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import PSR.Storage.SQLite.GetEvents qualified as GetEvents
1919
import PSR.Storage.SQLite.Instances ()
2020
import PSR.Storage.SQLite.Metrics (SqliteMetrics (..), initialiseMetrics)
2121
import PSR.Storage.SQLite.Utils
22-
import PSR.Types (BlockStatus (..))
2322
import PlutusLedgerApi.Common (MajorProtocolVersion (..))
2423

2524
withSqliteStorage :: FilePath -> Int -> (Storage -> IO ()) -> IO ()
@@ -34,7 +33,7 @@ mkStorage confirmationDepth metrics pool = do
3433
withResource pool initSchema
3534
pure $ Storage{..}
3635
where
37-
getEvents = GetEvents.getEvents metrics.getEvents_select pool
36+
getEvents = GetEvents.getEvents metrics.getEvents_select pool confirmationDepth
3837

3938
-- NOTE: The block may not always exist in our database. And it may not be
4039
-- possible to get the proper BlockHeader on a rollback event.
@@ -44,7 +43,6 @@ mkStorage confirmationDepth metrics pool = do
4443
let colsKnown =
4544
[ col "slot_no" slotNo
4645
, col "hash" hash
47-
, col "status" BSUnknown
4846
]
4947
cols =
5048
case mBlockNo of
@@ -61,24 +59,6 @@ mkStorage confirmationDepth metrics pool = do
6159
createBlockIfNotExists conn (BlockHeader slotNo hash blockNo) =
6260
createBlockIfNotExistsUtil conn slotNo hash (Just blockNo)
6361

64-
commitBlock :: Connection -> BlockNo -> IO ()
65-
commitBlock conn blockNoToCommit = do
66-
let q = "UPDATE block SET status = :set_status WHERE block_no = :block_no AND status = :prev_status;"
67-
executeNamed metrics.setBlockStatus_update conn q $
68-
[ ":set_status" := BSCommitted
69-
, ":prev_status" := BSUnknown
70-
, ":block_no" := blockNoToCommit
71-
]
72-
73-
cancelBlocksAfterSlot :: Connection -> SlotNo -> IO [Hash BlockHeader]
74-
cancelBlocksAfterSlot conn slotNo = do
75-
let q = "UPDATE block SET status = :set_status WHERE slot_no > :slot_no RETURNING hash;"
76-
fmap (fmap fromOnly) $
77-
queryNamed metrics.setBlockStatus_update conn q $
78-
[ ":set_status" := BSCancelled
79-
, ":slot_no" := slotNo
80-
]
81-
8262
getOrCreateCostModelParamsId :: Connection -> MajorProtocolVersion -> CostModel -> IO Integer
8363
getOrCreateCostModelParamsId conn (MajorProtocolVersion v) costModel = do
8464
version <- mkVersion64 $ fromIntegral v
@@ -157,20 +137,28 @@ mkStorage confirmationDepth metrics pool = do
157137
addRollbackEvent slotNo hash =
158138
withResource pool $ \conn -> withTransaction conn $ do
159139
createPartialBlockIfNotExists conn slotNo hash
160-
blocksCancelled <- cancelBlocksAfterSlot conn slotNo
161-
let params =
162-
[ col "block_hash" hash
163-
, col "blocks_cancelled" blocksCancelled
140+
[Only event_id] <-
141+
sqlInsertReturning
142+
metrics.addRollbackEvent_insert
143+
conn
144+
"rollback_event"
145+
[col "block_hash" hash]
146+
["event_id"]
147+
let q' =
148+
"INSERT INTO rollback_block (event_id, block_hash) \
149+
\SELECT :event_id, hash FROM block WHERE slot_no > :slot_no \
150+
\RETURNING block_hash;"
151+
fmap fromOnly
152+
<$> queryNamed
153+
metrics.addRollbackBlock_insert
154+
conn
155+
q'
156+
[ ":event_id" := (event_id :: Integer)
157+
, ":slot_no" := slotNo
164158
]
165-
sqlInsert
166-
metrics.addRollbackEvent_insert
167-
conn
168-
"rollback_event"
169-
params
170-
pure blocksCancelled
171159

172160
addSelectionEvent :: BlockHeader -> IO ()
173-
addSelectionEvent blockHeader@(BlockHeader _ hash blockNo) =
161+
addSelectionEvent blockHeader@(BlockHeader _ hash _) =
174162
withResource pool $ \conn -> withTransaction conn $ do
175163
void $ createBlockIfNotExists conn blockHeader
176164
let params = [col "block_hash" hash]
@@ -179,7 +167,6 @@ mkStorage confirmationDepth metrics pool = do
179167
conn
180168
"selection_event"
181169
params
182-
commitBlock conn (blockNo - fromIntegral confirmationDepth)
183170

184171
getExecutionContexts :: [FilterBy] -> IO [(BlockHeader, ExecutionContextId, ExecutionContext)]
185172
getExecutionContexts filters =

lib/PSR/Storage/SQLite/GetEvents.hs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ import PSR.Events.Interface (
2626
import PSR.Metrics qualified as Metrics
2727
import PSR.Storage.SQLite.Instances ()
2828
import PSR.Storage.SQLite.Utils
29+
import PSR.Types (BlockStatus)
2930

30-
getEvents :: Metrics.Summary -> Pool Connection -> EventFilterParams -> IO [Event]
31-
getEvents getEvents_select pool EventFilterParams{..} =
31+
getEvents :: Metrics.Summary -> Pool Connection -> Int -> EventFilterParams -> IO [Event]
32+
getEvents getEvents_select pool confirmationDepth EventFilterParams{..} =
3233
withResource pool $ \conn -> withTransaction conn $ do
3334
let
3435
-- see `docs/specification.md` for default values
@@ -80,15 +81,20 @@ getEvents getEvents_select pool EventFilterParams{..} =
8081
"SELECT b.slot_no, b.hash, b.block_no, \
8182
\ CASE \
8283
\ WHEN ec.block_hash IS NOT NULL THEN 'execution' \
83-
\ WHEN c.block_hash IS NOT NULL THEN 'rollback' \
84+
\ WHEN re.block_hash IS NOT NULL THEN 'rollback' \
8485
\ WHEN s.block_hash IS NOT NULL THEN 'selection' \
8586
\ END, \
86-
\ COALESCE(ee.created_at, c.created_at, s.created_at), \
87+
\ COALESCE(ee.created_at, re.created_at, s.created_at), \
8788
\ json(ee.trace_logs), \
88-
\ c.blocks_cancelled, \
89+
\ rb.block_hashes, \
8990
\ ee.eval_error, \
9091
\ ee.exec_budget_cpu, \
9192
\ ee.exec_budget_mem, \
93+
\ CASE \
94+
\ WHEN rb.block_hashes IS NOT NULL THEN 'cancelled' \
95+
\ WHEN b_max.max_slot_no IS NOT NULL AND (b_max.max_slot_no - :confirmation_depth) > b.slot_no THEN 'committed' \
96+
\ ELSE 'unknown'\
97+
\ END,\
9298
\ ec.transaction_hash, \
9399
\ ec.target_script_hash, \
94100
\ ec.target_script_name, \
@@ -103,20 +109,28 @@ getEvents getEvents_select pool EventFilterParams{..} =
103109
\ ec.exec_budget_max_mem, \
104110
\ cmp.params \
105111
\ FROM block b \
106-
\ LEFT JOIN execution_context ec ON ec.block_hash = b.hash \
107-
\ LEFT JOIN execution_event ee ON ee.context_id = ec.context_id \
112+
\ LEFT JOIN execution_context ec ON ec.block_hash = b.hash \
113+
\ LEFT JOIN execution_event ee ON ee.context_id = ec.context_id \
108114
\ LEFT JOIN cost_model_params cmp ON cmp.params_id = ec.cost_model_params_id \
109-
\ LEFT JOIN rollback_event c ON c.block_hash = b.hash \
110-
\ LEFT JOIN selection_event s ON s.block_hash = b.hash "
115+
\ LEFT JOIN rollback_event re ON re.block_hash = b.hash \
116+
\ LEFT JOIN \
117+
\(SELECT event_id, string_agg(block_hash, ' ') AS block_hashes FROM rollback_block) \
118+
\ rb ON re.event_id = rb.event_id \
119+
\ LEFT JOIN selection_event s ON s.block_hash = b.hash \
120+
\ JOIN (SELECT max(slot_no) as max_slot_no from block) b_max"
111121
<> whereQuery
112-
<> " ORDER BY COALESCE(ee.created_at, c.created_at, s.created_at) ASC \
122+
<> " ORDER BY COALESCE(ee.created_at, re.created_at, s.created_at) ASC \
113123
\ LIMIT :limit \
114124
\ OFFSET :offset"
115125

116-
parameters = whereParams <> [":limit" := limitParameter, ":offset" := offsetParameter]
117-
118-
rows <- queryNamed getEvents_select conn eventsQuery parameters
119-
pure $ rowToEvent <$> rows
126+
parameters =
127+
whereParams
128+
<> [ ":limit" := limitParameter
129+
, ":offset" := offsetParameter
130+
, ":confirmation_depth" := confirmationDepth
131+
]
132+
fmap rowToEvent
133+
<$> queryNamed getEvents_select conn eventsQuery parameters
120134
where
121135
rowToEvent ::
122136
( ( SlotNo
@@ -129,6 +143,7 @@ getEvents getEvents_select pool EventFilterParams{..} =
129143
, Maybe EvalError
130144
, Maybe Integer
131145
, Maybe Integer
146+
, BlockStatus
132147
)
133148
:. Maybe ExecutionContext
134149
) ->
@@ -144,6 +159,7 @@ getEvents getEvents_select pool EventFilterParams{..} =
144159
, evalError
145160
, mExBudgetCpu
146161
, mExBudgetMem
162+
, blockStatus
147163
)
148164
:. mExecutionContext
149165
) =
@@ -161,7 +177,7 @@ getEvents getEvents_select pool EventFilterParams{..} =
161177
context <- mExecutionContext
162178
blockNo <- mBlockNo
163179
pure $ ExecutionPayload blockNo $ ExecutionEventPayload{..}
164-
Rollback -> pure $ RollbackPayload (maybe [] id blocksCancelled)
180+
Rollback -> pure $ RollbackPayload (fromMaybe [] blocksCancelled)
165181
Selection -> SelectionPayload <$> mBlockNo
166182
in
167183
Event{..}

lib/PSR/Storage/SQLite/Instances.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,21 @@ maybeField =
224224
fromField >=> \case
225225
Just v -> pure v
226226
_ -> pure Nothing
227+
228+
instance
229+
( FromField a
230+
, FromField b
231+
, FromField c
232+
, FromField d
233+
, FromField e
234+
, FromField f
235+
, FromField g
236+
, FromField h
237+
, FromField i
238+
, FromField j
239+
, FromField k
240+
) =>
241+
FromRow (a, b, c, d, e, f, g, h, i, j, k)
242+
where
243+
fromRow =
244+
(,,,,,,,,,,) <$> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field

lib/PSR/Storage/SQLite/Metrics.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import PSR.Storage.SQLite.Instances ()
55

66
data SqliteMetrics = SqliteMetrics
77
{ createBlockIfNotExists_insert :: Summary
8-
, setBlockStatus_update :: Summary
98
, getOrCreateCostModelParamsId_insert :: Summary
109
, getOrCreateCostModelParamsId_select :: Summary
1110
, setOrCreateBlockId_insert :: Summary
1211
, setOrCreateBlockId_select :: Summary
1312
, addExecutionEvent_insert :: Summary
1413
, addRollbackEvent_insert :: Summary
14+
, addRollbackBlock_insert :: Summary
1515
, addSelectionEvent_insert :: Summary
1616
, getEvents_select :: Summary
1717
, getExecutionContextByNameOrScriptHash_select :: Summary
@@ -23,10 +23,6 @@ initialiseMetrics = do
2323
regSummary
2424
"sqlite_createBlockIfNotExists_insert"
2525
"Execution time of createBlockIfNotExists insert query"
26-
setBlockStatus_update <-
27-
regSummary
28-
"sqlite_setBlockStatus_update"
29-
"Execution time of setBlockStatus update query"
3026
getOrCreateCostModelParamsId_select <-
3127
regSummary
3228
"sqlite_getOrCreateCostModelParamsId_select"
@@ -51,6 +47,10 @@ initialiseMetrics = do
5147
regSummary
5248
"sqlite_addRollbackEvent_insert"
5349
"Execution time of addRollbackEvent insert query"
50+
addRollbackBlock_insert <-
51+
regSummary
52+
"sqlite_addRollbackBlock_insert"
53+
"Execution time of addRollbackEvent block insert query"
5454
addSelectionEvent_insert <-
5555
regSummary
5656
"sqlite_addSelectionEvent_insert"

lib/PSR/Storage/SQLite/Utils.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ initSchema conn = withTransaction conn $ do
6464

6565
-- "col" is a convenience sugar over (:=)
6666
col :: (ToField v) => Text -> v -> NamedParam
67-
col k v = (T.cons ':' k) := v
67+
col k v = T.cons ':' k := v
6868

6969
getParamKeys :: [NamedParam] -> [Text]
7070
getParamKeys params = [k | (k := _) <- params]

0 commit comments

Comments
 (0)