{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE RankNTypes #-}
module Cardano.Pool.DB
(
DBLayer (..)
, determinePoolLifeCycleStatus
, ErrPointAlreadyExists (..)
) where
import Prelude
import Cardano.Wallet.Primitive.Types
( BlockHeader
, CertificatePublicationTime (..)
, EpochNo (..)
, PoolId
, PoolLifeCycleStatus (..)
, PoolRegistrationCertificate
, PoolRetirementCertificate
, Settings
, SlotNo (..)
, StakePoolMetadata
, StakePoolMetadataHash
, StakePoolMetadataUrl
)
import Control.Monad.IO.Class
( MonadIO )
import Control.Monad.Trans.Except
( ExceptT )
import Data.Generics.Internal.VL.Lens
( view )
import Data.Map.Strict
( Map )
import Data.Quantity
( Quantity (..) )
import Data.Time.Clock.POSIX
( POSIXTime )
import Data.Word
( Word64 )
import System.Random
( StdGen )
data DBLayer m = forall stm. (MonadFail stm, MonadIO stm) => DBLayer
{ ()
putPoolProduction
:: BlockHeader
-> PoolId
-> ExceptT ErrPointAlreadyExists stm ()
, ()
readPoolProduction
:: EpochNo
-> stm (Map PoolId [BlockHeader])
, ()
readTotalProduction
:: stm (Map PoolId (Quantity "block" Word64))
, ()
putStakeDistribution
:: EpochNo
-> [(PoolId, Quantity "lovelace" Word64)]
-> stm ()
, ()
readStakeDistribution
:: EpochNo
-> stm [(PoolId, Quantity "lovelace" Word64)]
, ()
readPoolProductionCursor
:: Int
-> stm [BlockHeader]
, ()
readPoolLifeCycleStatus
:: PoolId
-> stm PoolLifeCycleStatus
, ()
putPoolRegistration
:: CertificatePublicationTime
-> PoolRegistrationCertificate
-> stm ()
, ()
readPoolRegistration
:: PoolId
-> stm (Maybe (CertificatePublicationTime, PoolRegistrationCertificate))
, ()
putPoolRetirement
:: CertificatePublicationTime
-> PoolRetirementCertificate
-> stm ()
, ()
readPoolRetirement
:: PoolId
-> stm (Maybe (CertificatePublicationTime, PoolRetirementCertificate))
, ()
unfetchedPoolMetadataRefs
:: Int
-> stm [(PoolId, StakePoolMetadataUrl, StakePoolMetadataHash)]
, ()
putFetchAttempt
:: (StakePoolMetadataUrl, StakePoolMetadataHash)
-> stm ()
, ()
listRegisteredPools
:: stm [PoolId]
, ()
listRetiredPools
:: EpochNo
-> stm [PoolRetirementCertificate]
, ()
listPoolLifeCycleData
:: EpochNo
-> stm [PoolLifeCycleStatus]
, ()
putPoolMetadata
:: StakePoolMetadataHash
-> StakePoolMetadata
-> stm ()
, ()
removePoolMetadata
:: stm ()
, ()
readPoolMetadata
:: stm (Map StakePoolMetadataHash StakePoolMetadata)
, ()
readSystemSeed
:: stm StdGen
, ()
rollbackTo
:: SlotNo
-> stm ()
, ()
putDelistedPools
:: [PoolId]
-> stm ()
, ()
readDelistedPools
:: stm [PoolId]
, ()
removePools
:: [PoolId]
-> stm ()
, ()
removeRetiredPools
:: EpochNo
-> stm [PoolRetirementCertificate]
,
:: BlockHeader
-> stm ()
,
:: Int
-> stm [BlockHeader]
, ()
readSettings
:: stm Settings
, ()
putSettings
:: Settings
-> stm ()
, ()
readLastMetadataGC
:: stm (Maybe POSIXTime)
, ()
putLastMetadataGC
:: POSIXTime
-> stm ()
, ()
cleanDB
:: stm ()
, ()
atomically
:: forall a. stm a -> m a
}
determinePoolLifeCycleStatus
:: (Ord publicationTime, Show publicationTime)
=> Maybe (publicationTime, PoolRegistrationCertificate)
-> Maybe (publicationTime, PoolRetirementCertificate)
-> PoolLifeCycleStatus
determinePoolLifeCycleStatus :: Maybe (publicationTime, PoolRegistrationCertificate)
-> Maybe (publicationTime, PoolRetirementCertificate)
-> PoolLifeCycleStatus
determinePoolLifeCycleStatus Maybe (publicationTime, PoolRegistrationCertificate)
mReg Maybe (publicationTime, PoolRetirementCertificate)
mRet = case (Maybe (publicationTime, PoolRegistrationCertificate)
mReg, Maybe (publicationTime, PoolRetirementCertificate)
mRet) of
(Maybe (publicationTime, PoolRegistrationCertificate)
Nothing, Maybe (publicationTime, PoolRetirementCertificate)
_) ->
PoolLifeCycleStatus
PoolNotRegistered
(Just (publicationTime
_, PoolRegistrationCertificate
regCert), Maybe (publicationTime, PoolRetirementCertificate)
Nothing) ->
PoolRegistrationCertificate -> PoolLifeCycleStatus
PoolRegistered PoolRegistrationCertificate
regCert
(Just (publicationTime
regTime, PoolRegistrationCertificate
regCert), Just (publicationTime
retTime, PoolRetirementCertificate
retCert))
| PoolId
regPoolId PoolId -> PoolId -> Bool
forall a. Eq a => a -> a -> Bool
/= PoolId
retPoolId ->
PoolLifeCycleStatus
differentPoolsError
| publicationTime
regTime publicationTime -> publicationTime -> Bool
forall a. Ord a => a -> a -> Bool
> publicationTime
retTime ->
PoolRegistrationCertificate -> PoolLifeCycleStatus
PoolRegistered PoolRegistrationCertificate
regCert
| publicationTime
regTime publicationTime -> publicationTime -> Bool
forall a. Ord a => a -> a -> Bool
< publicationTime
retTime ->
PoolRegistrationCertificate
-> PoolRetirementCertificate -> PoolLifeCycleStatus
PoolRegisteredAndRetired PoolRegistrationCertificate
regCert PoolRetirementCertificate
retCert
| Bool
otherwise ->
PoolLifeCycleStatus
timeCollisionError
where
regPoolId :: PoolId
regPoolId = ((PoolId -> Const PoolId PoolId)
-> PoolRegistrationCertificate
-> Const PoolId PoolRegistrationCertificate)
-> PoolRegistrationCertificate -> PoolId
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"poolId"
((PoolId -> Const PoolId PoolId)
-> PoolRegistrationCertificate
-> Const PoolId PoolRegistrationCertificate)
(PoolId -> Const PoolId PoolId)
-> PoolRegistrationCertificate
-> Const PoolId PoolRegistrationCertificate
#poolId PoolRegistrationCertificate
regCert
retPoolId :: PoolId
retPoolId = ((PoolId -> Const PoolId PoolId)
-> PoolRetirementCertificate
-> Const PoolId PoolRetirementCertificate)
-> PoolRetirementCertificate -> PoolId
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"poolId"
((PoolId -> Const PoolId PoolId)
-> PoolRetirementCertificate
-> Const PoolId PoolRetirementCertificate)
(PoolId -> Const PoolId PoolId)
-> PoolRetirementCertificate
-> Const PoolId PoolRetirementCertificate
#poolId PoolRetirementCertificate
retCert
differentPoolsError :: PoolLifeCycleStatus
differentPoolsError = [Char] -> PoolLifeCycleStatus
forall a. HasCallStack => [Char] -> a
error ([Char] -> PoolLifeCycleStatus) -> [Char] -> PoolLifeCycleStatus
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall a. Monoid a => [a] -> a
mconcat
[ [Char]
"programming error:"
, [Char]
" determinePoolLifeCycleStatus:"
, [Char]
" called with certificates for different pools:"
, [Char]
" pool id of registration certificate: "
, PoolId -> [Char]
forall a. Show a => a -> [Char]
show PoolId
regPoolId
, [Char]
" pool id of retirement certificate: "
, PoolId -> [Char]
forall a. Show a => a -> [Char]
show PoolId
retPoolId
]
timeCollisionError :: PoolLifeCycleStatus
timeCollisionError = [Char] -> PoolLifeCycleStatus
forall a. HasCallStack => [Char] -> a
error ([Char] -> PoolLifeCycleStatus) -> [Char] -> PoolLifeCycleStatus
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall a. Monoid a => [a] -> a
mconcat
[ [Char]
"programming error:"
, [Char]
" determinePoolLifeCycleStatus:"
, [Char]
" called with identical certificate publication times:"
, [Char]
" pool id of registration certificate: "
, PoolId -> [Char]
forall a. Show a => a -> [Char]
show PoolId
regPoolId
, [Char]
" pool id of retirement certificate: "
, PoolId -> [Char]
forall a. Show a => a -> [Char]
show PoolId
retPoolId
, [Char]
" publication time of registration certificate: "
, publicationTime -> [Char]
forall a. Show a => a -> [Char]
show publicationTime
regTime
, [Char]
" publication time of retirement certificate: "
, publicationTime -> [Char]
forall a. Show a => a -> [Char]
show publicationTime
retTime
]
newtype ErrPointAlreadyExists
= ErrPointAlreadyExists BlockHeader
deriving (ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool
(ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool)
-> (ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool)
-> Eq ErrPointAlreadyExists
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool
$c/= :: ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool
== :: ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool
$c== :: ErrPointAlreadyExists -> ErrPointAlreadyExists -> Bool
Eq, Int -> ErrPointAlreadyExists -> ShowS
[ErrPointAlreadyExists] -> ShowS
ErrPointAlreadyExists -> [Char]
(Int -> ErrPointAlreadyExists -> ShowS)
-> (ErrPointAlreadyExists -> [Char])
-> ([ErrPointAlreadyExists] -> ShowS)
-> Show ErrPointAlreadyExists
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [ErrPointAlreadyExists] -> ShowS
$cshowList :: [ErrPointAlreadyExists] -> ShowS
show :: ErrPointAlreadyExists -> [Char]
$cshow :: ErrPointAlreadyExists -> [Char]
showsPrec :: Int -> ErrPointAlreadyExists -> ShowS
$cshowsPrec :: Int -> ErrPointAlreadyExists -> ShowS
Show)