Skip to content

Commit 15d51ac

Browse files
committed
chore: generalize certification entity for multiple layers
decouple the direct realation between Run and Certification entities and introduce a one-to-one L1Certification entity
1 parent 744502f commit 15d51ac

File tree

7 files changed

+134
-41
lines changed

7 files changed

+134
-41
lines changed

dapps-certification-persistence/src/IOHK/Certification/Persistence.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import IOHK.Certification.Persistence.Structure as X
44
, Status(..)
55
, DApp(..)
66
, Certification(..)
7+
, L1Certification(..)
8+
, L1CertificationDTO(..)
79
, ProfileDTO(..)
810
, runs
911
, createTables
@@ -45,8 +47,8 @@ import IOHK.Certification.Persistence.API as X
4547
, getProfileAddress
4648
, syncRun
4749
, getRunOwner
48-
, getCertification
49-
, createCertificate
50+
, getL1Certification
51+
, createL1Certificate
5052
, deleteRun
5153
, markAsAborted
5254
, getRunStatus

dapps-certification-persistence/src/IOHK/Certification/Persistence/API.hs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
{-# LANGUAGE ScopedTypeVariables #-}
55
{-# LANGUAGE TypeOperators #-}
66
{-# LANGUAGE OverloadedRecordDot #-}
7+
{-# LANGUAGE NamedFieldPuns #-}
78

89
module IOHK.Certification.Persistence.API where
910

@@ -91,7 +92,6 @@ activateSubscription sub = do
9192
pure Nothing
9293
Nothing -> pure Nothing
9394

94-
9595
getAllCertifiedRunsForAddress :: MonadSelda m => Text -> m [Run]
9696
getAllCertifiedRunsForAddress address = query $ do
9797
-- get the profile id for the address
@@ -291,12 +291,12 @@ markAsReadyForCertification runId IpfsCid{..} time = update runs
291291
, #reportContentId := literal (Just ipfsCid)
292292
])
293293

294-
createCertificate :: (MonadSelda m,MonadMask m)
294+
createL1Certificate :: (MonadSelda m,MonadMask m)
295295
=> UUID
296296
-> TxId
297297
-> UTCTime
298-
-> m (Maybe Certification)
299-
createCertificate runId TxId{..} time = transaction $ do
298+
-> m (Maybe L1CertificationDTO)
299+
createL1Certificate runId TxId{..} time = transaction $ do
300300
result <- query $ do
301301
run <- select runs
302302
restrict (run ! #runId .== literal runId)
@@ -309,19 +309,28 @@ createCertificate runId TxId{..} time = transaction $ do
309309
(`with` [ #runStatus := literal Certified
310310
, #syncedAt := literal time
311311
])
312-
let cert = Certification runId txId time
313-
_ <- insert certifications [cert]
314-
pure $ Just cert
312+
let cert = Certification def txId time
313+
certId <- insertWithPK certifications [cert]
314+
-- and now add a l1Certification
315+
let l1Cert = L1Certification runId certId
316+
_ <- insert l1Certifications [l1Cert]
317+
pure $ Just (L1CertificationDTO l1Cert (cert { certId }))
315318
_ -> pure Nothing
316319

317-
getCertificationQuery :: UUID -> Query t (Row t Certification)
318-
getCertificationQuery runID = do
319-
c <- select certifications
320-
restrict (c ! #certRunId .== literal runID )
321-
pure c
320+
getL1CertificationQuery :: UUID -> Query t (Row t Certification :*: Row t L1Certification)
321+
getL1CertificationQuery runID = do
322+
l1Cert <- select l1Certifications
323+
restrict (l1Cert ! #l1CertRunId .== literal runID )
324+
c <- innerJoin
325+
(\t -> t ! #certId .== l1Cert ! #l1CertId)
326+
(select certifications)
327+
pure (c :*: l1Cert)
328+
329+
getL1Certification :: MonadSelda m => UUID -> m (Maybe L1CertificationDTO)
330+
getL1Certification pid = fmap (fmap toL1CertificationDTO . listToMaybe ) $ query $ getL1CertificationQuery pid
322331

323-
getCertification :: MonadSelda m => UUID -> m (Maybe Certification)
324-
getCertification = fmap listToMaybe . query . getCertificationQuery
332+
toL1CertificationDTO :: (Certification :*: L1Certification) -> L1CertificationDTO
333+
toL1CertificationDTO (cert :*: l1Cert) = L1CertificationDTO l1Cert cert
325334

326335
getRun :: MonadSelda m => UUID -> m (Maybe Run)
327336
getRun rid = listToMaybe <$> query (do

dapps-certification-persistence/src/IOHK/Certification/Persistence/Structure.hs

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ module IOHK.Certification.Persistence.Structure where
1919
import Control.Lens hiding (index, (.=))
2020
import Data.Aeson
2121
import Data.Proxy
22+
--import Control.Exception ( throw)
2223
import Data.Swagger hiding (Contact)
2324
import Database.Selda
25+
--import Database.Selda.SqlType as Selda
2426
import GHC.OverloadedLabels
2527
import Data.Int
2628

@@ -118,42 +120,116 @@ instance ToSchema ProfileDTO where
118120

119121
--------------------------------------------------------------------------------
120122
-- | Certification
123+
{-
124+
data CertificationLevel = L0 | L1 | L2 | L3
125+
deriving (Generic,Show,Read,Eq,Ord,Enum)
126+
127+
instance SqlType CertificationLevel where
128+
mkLit n = LCustom TInt64 (LInt64 (toInt64 n))
129+
where
130+
toInt64 = \case
131+
L0 -> 0
132+
L1 -> 1
133+
L2 -> 2
134+
L3 -> 3
135+
sqlType _ = TInt64
136+
fromSql (SqlInt64 0) = L0
137+
fromSql (SqlInt64 1) = L1
138+
fromSql (SqlInt64 2) = L2
139+
fromSql (SqlInt64 3) = L3
140+
fromSql v = throw $ userError $ "fromSql: expected SqlInt64, got " ++ show v
141+
defaultValue = mkLit L1
142+
143+
instance ToJSON CertificationLevel where
144+
toJSON = toJSON . \case
145+
L0 -> "l0" :: String
146+
L1 -> "l1"
147+
L2 -> "l2"
148+
L3 -> "l3"
149+
150+
instance FromJSON CertificationLevel where
151+
parseJSON = withText "CertificationLevel" $ \case
152+
"l0" -> pure L0
153+
"l1" -> pure L1
154+
"l2" -> pure L2
155+
"l3" -> pure L3
156+
_ -> fail "CertificationLevel"
157+
158+
instance ToSchema CertificationLevel where
159+
declareNamedSchema _ = do
160+
let values = [ "l0", "l1", "l2", "l3" ] :: [Value]
161+
return $ NamedSchema (Just "CertificationLevel") $ mempty
162+
& type_ ?~ SwaggerString
163+
& enum_ ?~ values
164+
-}
121165

122166
data Certification = Certification
123-
{ certRunId :: UUID
167+
{ certId :: ID Certification
124168
, certTransactionId :: Text
125169
, certCreatedAt :: UTCTime
126170
} deriving (Generic,Show)
127171

128172
instance FromJSON Certification where
129-
parseJSON = withObject "Certification" $ \v -> Certification
130-
<$> v .: "runId"
131-
<*> v .: "transactionId"
173+
parseJSON = withObject "Certification" $ \v -> Certification def
174+
<$> v .: "transactionId"
132175
<*> v .: "createdAt"
133176

134177
instance ToJSON Certification where
135178
toJSON (Certification{..}) = object
136179
[ "transactionId" .= certTransactionId
137180
, "createdAt" .= certCreatedAt
138-
, "runId" .= certRunId
139181
]
140182

141183
instance ToSchema Certification where
142184
declareNamedSchema _ = do
143185
textSchema <- declareSchemaRef (Proxy :: Proxy Text)
144186
utcSchema <- declareSchemaRef (Proxy :: Proxy UTCTime)
145-
uuidSchema <- declareSchemaRef (Proxy :: Proxy UUID)
146187
return $ NamedSchema (Just "Certification") $ mempty
147188
& type_ ?~ SwaggerObject
148189
& properties .~
149190
[ ("transactionId", textSchema)
150191
, ("createdAt", utcSchema)
151-
, ("runId", uuidSchema)
152192
]
153-
& required .~ [ "runId", "createdAt" ]
193+
& required .~ [ "createdAt" ]
154194

155195
instance SqlRow Certification
156196

197+
-- one to one mapping with Run
198+
data L1Certification = L1Certification
199+
{ l1CertRunId :: UUID
200+
, l1CertId :: ID Certification
201+
} deriving (Generic,Show)
202+
203+
instance SqlRow L1Certification
204+
205+
data L1CertificationDTO = L1CertificationDTO
206+
{ l1Certification :: L1Certification
207+
, certification :: Certification
208+
}
209+
210+
instance ToJSON L1CertificationDTO where
211+
toJSON L1CertificationDTO{..} = Object (x <> y)
212+
where
213+
x = case toJSON certification of
214+
Object obj -> obj
215+
_ -> KM.empty
216+
y = KM.fromList [ "runId" .= l1CertRunId l1Certification ]
217+
218+
instance FromJSON L1CertificationDTO where
219+
parseJSON = withObject "L1CertificationDTO" $ \v -> do
220+
l1Certification <- L1Certification
221+
<$> v .: "runId"
222+
<*> pure def
223+
L1CertificationDTO l1Certification <$> v .: "runId"
224+
225+
instance ToSchema L1CertificationDTO where
226+
declareNamedSchema _ = do
227+
certificationSchema <- declareSchema (Proxy :: Proxy Certification)
228+
uuidSchema <- declareSchemaRef (Proxy :: Proxy UUID)
229+
return $ NamedSchema (Just "TierDTO") $ certificationSchema
230+
& properties %~ (`mappend` [ ("certRunId", uuidSchema) ])
231+
& required %~ (<> [ "certRunId" ])
232+
157233
--------------------------------------------------------------------------------
158234
-- | Dapp
159235

@@ -199,7 +275,6 @@ instance ToJSON DApp where
199275

200276
instance SqlRow DApp
201277

202-
203278
--------------------------------------------------------------------------------
204279
-- | Run
205280

@@ -367,8 +442,14 @@ runs = table "run"
367442

368443
certifications :: Table Certification
369444
certifications = table "certification"
370-
[ #certRunId :- primary
371-
, #certRunId :- foreignKey runs #runId
445+
[ #certId :- primary
446+
]
447+
448+
l1Certifications :: Table L1Certification
449+
l1Certifications = table "certification"
450+
[ #l1CertRunId :- primary
451+
, #l1CertRunId :- foreignKey runs #runId
452+
, #l1CertId :- foreignKey certifications #certId
372453
]
373454

374455
dapps :: Table DApp
@@ -389,3 +470,4 @@ createTables = do
389470
createTable tiers
390471
createTable tierFeatures
391472
createTable subscriptions
473+
createTable l1Certifications

src/Plutus/Certification/API/Routes.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ type GetCertificateRoute = "run"
126126
:> Description "Get the L1 IPFS CID and the transaction id of the onchain stored Certificate"
127127
:> Capture "id" RunIDV1
128128
:> "certificate"
129-
:> Get '[JSON] DB.Certification
129+
:> Get '[JSON] DB.L1CertificationDTO
130130

131131
type GetBalanceRoute (auth :: Symbol) = "profile"
132132
:> Description "Get the current balance of the profile"

src/Plutus/Certification/Server/Instance.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ server ServerArgs{..} = NamedAPI
218218

219219
, getCertification = \rid@RunID{..} -> withEvent eb GetCertification \ev -> do
220220
addField ev rid
221-
DB.withDb (DB.getCertification uuid)
221+
DB.withDb (DB.getL1Certification uuid)
222222
>>= maybeToServerError err404 "Certification not found"
223223

224224
, getRepositoryInfo = \owner repo apiGhAccessTokenM -> withEvent eb GetRepoInfo \ev -> do

src/Plutus/Certification/Synchronizer.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ monitorWalletTransactions eb args = withEvent eb MonitorTransactions $ \ev -> do
176176
return []
177177
handleResponse (Right transactions) = return transactions
178178

179-
type CertificationProcess m = DB.ProfileId -> UUID -> m DB.Certification
179+
type CertificationProcess m = DB.ProfileId -> UUID -> m DB.L1CertificationDTO
180180

181181
-- certify all runs who have enough credit to be certified
182182
-- and have not been certified yet
@@ -195,7 +195,7 @@ certifyRuns eb args = do
195195
-- TODO: parallelize this
196196
forM_ runsByProfile $ certifyProfileRuns certificationProcess
197197
where
198-
certificationProcess a b = createCertification
198+
certificationProcess a b = createL1Certification
199199
( narrowEventBackend InjectTxBroadcaster eb ) args a (RunID b)
200200

201201
activateSubscriptions :: (MonadIO m, MonadMask m,MonadError IOException m)

src/Plutus/Certification/TransactionBroadcaster.hs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
{-# LANGUAGE TypeFamilies #-}
1313

1414
module Plutus.Certification.TransactionBroadcaster
15-
( createCertification
15+
( createL1Certification
1616
, renderTxBroadcasterSelector
1717
, TxBroadcasterSelector(..)
1818
) where
@@ -52,13 +52,13 @@ renderTxBroadcasterSelector CreateCertification = ("create-certification", \case
5252
)
5353

5454
-- caution: this function doesn't verify if the run has the proper status
55-
createCertification :: (MonadMask m,MonadIO m, MonadError IOException m)
56-
=> EventBackend m r TxBroadcasterSelector
57-
-> WalletArgs
58-
-> DB.ProfileId
59-
-> RunIDV1
60-
-> m DB.Certification
61-
createCertification eb wargs profileId rid@RunID{..} = withEvent eb CreateCertification \ev -> do
55+
createL1Certification :: (MonadMask m,MonadIO m, MonadError IOException m)
56+
=> EventBackend m r TxBroadcasterSelector
57+
-> WalletArgs
58+
-> DB.ProfileId
59+
-> RunIDV1
60+
-> m DB.L1CertificationDTO
61+
createL1Certification eb wargs profileId rid@RunID{..} = withEvent eb CreateCertification \ev -> do
6262
addField ev (CreateCertificationRunID rid)
6363

6464
-- getting required profile information before further processing
@@ -74,13 +74,13 @@ createCertification eb wargs profileId rid@RunID{..} = withEvent eb CreateCertif
7474
let certificate = Wallet.CertificationMetadata uuid (DB.IpfsCid ipfsCid) dappName websiteUrl
7575
(profile.twitter) uri dappVersion
7676

77-
-- broadcast the certification
77+
-- broadcast the l1 certification
7878
tx@Wallet.TxResponse{..} <- Wallet.broadcastTransaction wargs 1304 certificate
7979
>>= eitherToError show
8080
addField ev (CreateCertificationTxResponse tx)
8181

8282
-- persist it into the db
83-
(DB.withDb . DB.createCertificate uuid txRespId =<< getNow)
83+
(DB.withDb . DB.createL1Certificate uuid txRespId =<< getNow)
8484
>>= maybeToError "Certification couldn't be persisted"
8585
where
8686
getRun = DB.withDb (DB.getRun uuid) >>= maybeToError "No Run"

0 commit comments

Comments
 (0)