module Hydra.Node.Run where

import Hydra.Prelude hiding (fromList)

import Cardano.Ledger.BaseTypes (Globals (..), boundRational, mkActiveSlotCoeff, unNonZero)
import Cardano.Ledger.Shelley.API (computeRandomnessStabilisationWindow, computeStabilityWindow)
import Cardano.Slotting.EpochInfo (fixedEpochInfo)
import Cardano.Slotting.Time (mkSlotLength)
import Hydra.API.Server (APIServerConfig (..), withAPIServer)
import Hydra.API.ServerOutputFilter (serverOutputFilter)
import Hydra.Cardano.Api (
  GenesisParameters (..),
  ProtocolParametersConversionError,
  ShelleyEra,
  SystemStart (..),
  toShelleyNetwork,
 )
import Hydra.Chain (maximumNumberOfParties)
import Hydra.Chain.Backend (ChainBackend (queryGenesisParameters))
import Hydra.Chain.Blockfrost (BlockfrostBackend (..))
import Hydra.Chain.Cardano (withCardanoChain)
import Hydra.Chain.Direct (DirectBackend (..))
import Hydra.Chain.Direct.State (initialChainState)
import Hydra.Chain.Offline (loadGenesisFile, withOfflineChain)
import Hydra.Events.FileBased (mkFileBasedEventStore)
import Hydra.Events.Rotation (EventStore (..), RotationConfig (..), newRotatedEventStore)
import Hydra.HeadLogic (aggregate)
import Hydra.HeadLogic.State (HeadState (..), IdleState (..))
import Hydra.HeadLogic.StateEvent (StateEvent (StateEvent, stateChanged), mkCheckpoint)
import Hydra.Ledger.Cardano (cardanoLedger, newLedgerEnv)
import Hydra.Logging (traceWith, withTracer)
import Hydra.Logging.Messages (HydraLog (..))
import Hydra.Logging.Monitoring (withMonitoring)
import Hydra.Node (
  HydraNode (eventSinks),
  chainStateHistory,
  connect,
  hydrate,
  initEnvironment,
  runHydraNode,
  wireChainInput,
  wireClientInput,
  wireNetworkInput,
 )
import Hydra.Node.Environment (Environment (..))
import Hydra.Node.Network (NetworkConfiguration (..), withNetwork)
import Hydra.Options (
  CardanoChainConfig (..),
  ChainBackendOptions (..),
  ChainConfig (..),
  InvalidOptions (..),
  LedgerConfig (..),
  OfflineChainConfig (..),
  RunOptions (..),
  validateRunOptions,
 )
import Hydra.Persistence (createPersistenceIncremental)
import Hydra.Utils (readJsonFileThrow)
import System.FilePath ((</>))

data ConfigurationException
  = -- XXX: this is not used
    ConfigurationException ProtocolParametersConversionError
  | InvalidOptionException InvalidOptions
  deriving stock (Int -> ConfigurationException -> ShowS
[ConfigurationException] -> ShowS
ConfigurationException -> String
(Int -> ConfigurationException -> ShowS)
-> (ConfigurationException -> String)
-> ([ConfigurationException] -> ShowS)
-> Show ConfigurationException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ConfigurationException -> ShowS
showsPrec :: Int -> ConfigurationException -> ShowS
$cshow :: ConfigurationException -> String
show :: ConfigurationException -> String
$cshowList :: [ConfigurationException] -> ShowS
showList :: [ConfigurationException] -> ShowS
Show)

instance Exception ConfigurationException where
  displayException :: ConfigurationException -> String
displayException = \case
    InvalidOptionException InvalidOptions
MaximumNumberOfPartiesExceeded ->
      String
"Maximum number of parties is currently set to: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall b a. (Show a, IsString b) => a -> b
show Int
maximumNumberOfParties
    InvalidOptionException InvalidOptions
CardanoAndHydraKeysMismatch ->
      String
"Number of loaded cardano and hydra keys needs to match"
    ConfigurationException ProtocolParametersConversionError
err ->
      String
"Incorrect protocol parameters configuration provided: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ProtocolParametersConversionError -> String
forall b a. (Show a, IsString b) => a -> b
show ProtocolParametersConversionError
err

run :: RunOptions -> IO ()
run :: RunOptions -> IO ()
run RunOptions
opts = do
  (InvalidOptions -> IO ())
-> (() -> IO ()) -> Either InvalidOptions () -> IO ()
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (ConfigurationException -> IO ()
forall e a. Exception e => e -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ConfigurationException -> IO ())
-> (InvalidOptions -> ConfigurationException)
-> InvalidOptions
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InvalidOptions -> ConfigurationException
InvalidOptionException) () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either InvalidOptions () -> IO ())
-> Either InvalidOptions () -> IO ()
forall a b. (a -> b) -> a -> b
$ RunOptions -> Either InvalidOptions ()
validateRunOptions RunOptions
opts
  Verbosity -> (Tracer IO (HydraLog Tx) -> IO ()) -> IO ()
forall (m :: * -> *) msg a.
(MonadIO m, MonadFork m, MonadTime m, ToJSON msg) =>
Verbosity -> (Tracer m msg -> IO a) -> IO a
withTracer Verbosity
verbosity ((Tracer IO (HydraLog Tx) -> IO ()) -> IO ())
-> (Tracer IO (HydraLog Tx) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Tracer IO (HydraLog Tx)
tracer' -> do
    Tracer IO (HydraLog Tx) -> HydraLog Tx -> IO ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer IO (HydraLog Tx)
tracer' (RunOptions -> HydraLog Tx
forall tx. RunOptions -> HydraLog tx
NodeOptions RunOptions
opts)
    Maybe PortNumber
-> Tracer IO (HydraLog Tx)
-> (Tracer IO (HydraLog Tx) -> IO ())
-> IO ()
forall (m :: * -> *) tx.
(MonadIO m, MonadAsync m, IsTx tx, MonadMonotonicTime m) =>
Maybe PortNumber
-> Tracer m (HydraLog tx)
-> (Tracer m (HydraLog tx) -> m ())
-> m ()
withMonitoring Maybe PortNumber
monitoringPort Tracer IO (HydraLog Tx)
tracer' ((Tracer IO (HydraLog Tx) -> IO ()) -> IO ())
-> (Tracer IO (HydraLog Tx) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Tracer IO (HydraLog Tx)
tracer -> do
      env :: Environment
env@Environment{Party
party :: Party
$sel:party:Environment :: Environment -> Party
party, [Party]
otherParties :: [Party]
$sel:otherParties:Environment :: Environment -> [Party]
otherParties, SigningKey HydraKey
signingKey :: SigningKey HydraKey
$sel:signingKey:Environment :: Environment -> SigningKey HydraKey
signingKey} <- RunOptions -> IO Environment
initEnvironment RunOptions
opts
      -- Ledger
      PParams ConwayEra
pparams <- (Value -> Parser (PParams ConwayEra))
-> String -> IO (PParams ConwayEra)
forall a. (Value -> Parser a) -> String -> IO a
readJsonFileThrow Value -> Parser (PParams ConwayEra)
forall a. FromJSON a => Value -> Parser a
parseJSON (LedgerConfig -> String
cardanoLedgerProtocolParametersFile LedgerConfig
ledgerConfig)
      Globals
globals <- ChainConfig -> IO Globals
getGlobalsForChain ChainConfig
chainConfig
      PParams ConwayEra -> Globals -> (Ledger Tx -> IO ()) -> IO ()
forall {t}. PParams ConwayEra -> Globals -> (Ledger Tx -> t) -> t
withCardanoLedger PParams ConwayEra
pparams Globals
globals ((Ledger Tx -> IO ()) -> IO ()) -> (Ledger Tx -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ledger Tx
ledger -> do
        -- Hydrate with event source and sinks
        let stateFile :: String
stateFile = String
persistenceDir String -> ShowS
</> String
"state"
        eventStore :: EventStore (StateEvent Tx) IO
eventStore@EventStore{EventSource (StateEvent Tx) IO
eventSource :: EventSource (StateEvent Tx) IO
$sel:eventSource:EventStore :: forall e (m :: * -> *). EventStore e m -> EventSource e m
eventSource} <-
          EventStore (StateEvent Tx) IO -> IO (EventStore (StateEvent Tx) IO)
prepareEventStore
            (EventStore (StateEvent Tx) IO
 -> IO (EventStore (StateEvent Tx) IO))
-> IO (EventStore (StateEvent Tx) IO)
-> IO (EventStore (StateEvent Tx) IO)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String
-> PersistenceIncremental (StateEvent Tx) IO
-> IO (EventStore (StateEvent Tx) IO)
forall e.
(ToJSON e, FromJSON e, HasEventId e) =>
String -> PersistenceIncremental e IO -> IO (EventStore e IO)
mkFileBasedEventStore String
stateFile
            (PersistenceIncremental (StateEvent Tx) IO
 -> IO (EventStore (StateEvent Tx) IO))
-> IO (PersistenceIncremental (StateEvent Tx) IO)
-> IO (EventStore (StateEvent Tx) IO)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> IO (PersistenceIncremental (StateEvent Tx) IO)
forall a (m :: * -> *).
(MonadUnliftIO m, MonadThrow m, FromJSON a) =>
String -> m (PersistenceIncremental a m)
createPersistenceIncremental String
stateFile
        -- NOTE: Add any custom sinks here
        let eventSinks :: [a]
eventSinks = []
        DraftHydraNode Tx IO
wetHydraNode <- Tracer IO (HydraNodeLog Tx)
-> Environment
-> Ledger Tx
-> ChainStateType Tx
-> EventStore (StateEvent Tx) IO
-> [EventSink (StateEvent Tx) IO]
-> IO (DraftHydraNode Tx IO)
forall tx (m :: * -> *).
(IsChainState tx, MonadDelay m, MonadLabelledSTM m, MonadAsync m,
 MonadThrow m, MonadUnliftIO m) =>
Tracer m (HydraNodeLog tx)
-> Environment
-> Ledger tx
-> ChainStateType tx
-> EventStore (StateEvent tx) m
-> [EventSink (StateEvent tx) m]
-> m (DraftHydraNode tx m)
hydrate ((HydraNodeLog Tx -> HydraLog Tx)
-> Tracer IO (HydraLog Tx) -> Tracer IO (HydraNodeLog Tx)
forall a' a. (a' -> a) -> Tracer IO a -> Tracer IO a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap HydraNodeLog Tx -> HydraLog Tx
forall tx. HydraNodeLog tx -> HydraLog tx
Node Tracer IO (HydraLog Tx)
tracer) Environment
env Ledger Tx
ledger ChainStateType Tx
initialChainState EventStore (StateEvent Tx) IO
eventStore [EventSink (StateEvent Tx) IO]
forall a. [a]
eventSinks
        -- Chain
        ChainStateHistory Tx -> ChainComponent Tx IO ()
withChain <- Tracer IO (HydraLog Tx)
-> Environment
-> ChainConfig
-> IO (ChainStateHistory Tx -> ChainComponent Tx IO ())
forall {f :: * -> *} {tx} {a}.
Applicative f =>
Tracer IO (HydraLog tx)
-> Environment
-> ChainConfig
-> f (ChainStateHistory Tx -> ChainComponent Tx IO a)
prepareChainComponent Tracer IO (HydraLog Tx)
tracer Environment
env ChainConfig
chainConfig
        ChainStateHistory Tx -> ChainComponent Tx IO ()
withChain (DraftHydraNode Tx IO -> ChainStateHistory Tx
forall tx (m :: * -> *).
DraftHydraNode tx m -> ChainStateHistory tx
chainStateHistory DraftHydraNode Tx IO
wetHydraNode) (DraftHydraNode Tx IO -> ChainEvent Tx -> IO ()
forall tx (m :: * -> *).
DraftHydraNode tx m -> ChainEvent tx -> m ()
wireChainInput DraftHydraNode Tx IO
wetHydraNode) ((Chain Tx IO -> IO ()) -> IO ())
-> (Chain Tx IO -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Chain Tx IO
chain -> do
          -- API
          let apiServerConfig :: APIServerConfig
apiServerConfig = APIServerConfig{$sel:host:APIServerConfig :: IP
host = IP
apiHost, $sel:port:APIServerConfig :: PortNumber
port = PortNumber
apiPort, Maybe String
tlsCertPath :: Maybe String
$sel:tlsCertPath:APIServerConfig :: Maybe String
tlsCertPath, Maybe String
tlsKeyPath :: Maybe String
$sel:tlsKeyPath:APIServerConfig :: Maybe String
tlsKeyPath}
          APIServerConfig
-> Environment
-> Party
-> EventSource (StateEvent Tx) IO
-> Tracer IO APIServerLog
-> Chain Tx IO
-> PParams LedgerEra
-> ServerOutputFilter Tx
-> (ClientInput Tx -> IO ())
-> ((EventSink (StateEvent Tx) IO, Server Tx IO) -> IO ())
-> IO ()
forall tx.
IsChainState tx =>
APIServerConfig
-> Environment
-> Party
-> EventSource (StateEvent tx) IO
-> Tracer IO APIServerLog
-> Chain tx IO
-> PParams LedgerEra
-> ServerOutputFilter tx
-> (ClientInput tx -> IO ())
-> ((EventSink (StateEvent tx) IO, Server tx IO) -> IO ())
-> IO ()
withAPIServer APIServerConfig
apiServerConfig Environment
env Party
party EventSource (StateEvent Tx) IO
eventSource ((APIServerLog -> HydraLog Tx)
-> Tracer IO (HydraLog Tx) -> Tracer IO APIServerLog
forall a' a. (a' -> a) -> Tracer IO a -> Tracer IO a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap APIServerLog -> HydraLog Tx
forall tx. APIServerLog -> HydraLog tx
APIServer Tracer IO (HydraLog Tx)
tracer) Chain Tx IO
chain PParams ConwayEra
PParams LedgerEra
pparams ServerOutputFilter Tx
serverOutputFilter (DraftHydraNode Tx IO -> ClientInput Tx -> IO ()
forall tx (m :: * -> *).
DraftHydraNode tx m -> ClientInput tx -> m ()
wireClientInput DraftHydraNode Tx IO
wetHydraNode) (((EventSink (StateEvent Tx) IO, Server Tx IO) -> IO ()) -> IO ())
-> ((EventSink (StateEvent Tx) IO, Server Tx IO) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(EventSink (StateEvent Tx) IO
apiSink, Server Tx IO
server) -> do
            -- Network
            let networkConfiguration :: NetworkConfiguration
networkConfiguration =
                  NetworkConfiguration
                    { String
persistenceDir :: String
$sel:persistenceDir:NetworkConfiguration :: String
persistenceDir
                    , SigningKey HydraKey
signingKey :: SigningKey HydraKey
$sel:signingKey:NetworkConfiguration :: SigningKey HydraKey
signingKey
                    , [Party]
otherParties :: [Party]
$sel:otherParties:NetworkConfiguration :: [Party]
otherParties
                    , Host
listen :: Host
$sel:listen:NetworkConfiguration :: Host
listen
                    , $sel:advertise:NetworkConfiguration :: Host
advertise = Host -> Maybe Host -> Host
forall a. a -> Maybe a -> a
fromMaybe Host
listen Maybe Host
advertise
                    , [Host]
peers :: [Host]
$sel:peers:NetworkConfiguration :: [Host]
peers
                    , NodeId
nodeId :: NodeId
$sel:nodeId:NetworkConfiguration :: NodeId
nodeId
                    , WhichEtcd
whichEtcd :: WhichEtcd
$sel:whichEtcd:NetworkConfiguration :: WhichEtcd
whichEtcd
                    }
            Tracer IO NetworkLog
-> NetworkConfiguration
-> NetworkComponent IO (Authenticated (Message Tx)) (Message Tx) ()
forall tx.
IsTx tx =>
Tracer IO NetworkLog
-> NetworkConfiguration
-> NetworkComponent IO (Authenticated (Message tx)) (Message tx) ()
withNetwork
              ((NetworkLog -> HydraLog Tx)
-> Tracer IO (HydraLog Tx) -> Tracer IO NetworkLog
forall a' a. (a' -> a) -> Tracer IO a -> Tracer IO a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap NetworkLog -> HydraLog Tx
forall tx. NetworkLog -> HydraLog tx
Network Tracer IO (HydraLog Tx)
tracer)
              NetworkConfiguration
networkConfiguration
              (DraftHydraNode Tx IO
-> NetworkCallback (Authenticated (Message Tx)) IO
forall tx (m :: * -> *).
DraftHydraNode tx m
-> NetworkCallback (Authenticated (Message tx)) m
wireNetworkInput DraftHydraNode Tx IO
wetHydraNode)
              ((Network IO (Message Tx) -> IO ()) -> IO ())
-> (Network IO (Message Tx) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Network IO (Message Tx)
network -> do
                -- Main loop
                Chain Tx IO
-> Network IO (Message Tx)
-> Server Tx IO
-> DraftHydraNode Tx IO
-> IO (HydraNode Tx IO)
forall (m :: * -> *) tx.
Monad m =>
Chain tx m
-> Network m (Message tx)
-> Server tx m
-> DraftHydraNode tx m
-> m (HydraNode tx m)
connect Chain Tx IO
chain Network IO (Message Tx)
network Server Tx IO
server DraftHydraNode Tx IO
wetHydraNode
                  IO (HydraNode Tx IO)
-> (HydraNode Tx IO -> HydraNode Tx IO) -> IO (HydraNode Tx IO)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> EventSink (StateEvent Tx) IO -> HydraNode Tx IO -> HydraNode Tx IO
forall {tx} {m :: * -> *}.
EventSink (StateEvent tx) m -> HydraNode tx m -> HydraNode tx m
addEventSink EventSink (StateEvent Tx) IO
apiSink
                    IO (HydraNode Tx IO) -> (HydraNode Tx IO -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HydraNode Tx IO -> IO ()
forall (m :: * -> *) tx.
(MonadCatch m, MonadAsync m, MonadTime m, IsChainState tx) =>
HydraNode tx m -> m ()
runHydraNode
 where
  addEventSink :: EventSink (StateEvent tx) m -> HydraNode tx m -> HydraNode tx m
addEventSink EventSink (StateEvent tx) m
sink HydraNode tx m
node = HydraNode tx m
node{eventSinks = sink : eventSinks node}

  withCardanoLedger :: PParams ConwayEra -> Globals -> (Ledger Tx -> t) -> t
withCardanoLedger PParams ConwayEra
protocolParams Globals
globals Ledger Tx -> t
action =
    let ledgerEnv :: LedgerEnv LedgerEra
ledgerEnv = PParams LedgerEra -> LedgerEnv LedgerEra
newLedgerEnv PParams ConwayEra
PParams LedgerEra
protocolParams
     in Ledger Tx -> t
action (Globals -> LedgerEnv LedgerEra -> Ledger Tx
cardanoLedger Globals
globals LedgerEnv LedgerEra
ledgerEnv)

  prepareChainComponent :: Tracer IO (HydraLog tx)
-> Environment
-> ChainConfig
-> f (ChainStateHistory Tx -> ChainComponent Tx IO a)
prepareChainComponent Tracer IO (HydraLog tx)
tracer Environment{Party
$sel:party:Environment :: Environment -> Party
party :: Party
party, [Party]
$sel:otherParties:Environment :: Environment -> [Party]
otherParties :: [Party]
otherParties} = \case
    Offline OfflineChainConfig
cfg -> (ChainStateHistory Tx -> ChainComponent Tx IO a)
-> f (ChainStateHistory Tx -> ChainComponent Tx IO a)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ChainStateHistory Tx -> ChainComponent Tx IO a)
 -> f (ChainStateHistory Tx -> ChainComponent Tx IO a))
-> (ChainStateHistory Tx -> ChainComponent Tx IO a)
-> f (ChainStateHistory Tx -> ChainComponent Tx IO a)
forall a b. (a -> b) -> a -> b
$ OfflineChainConfig
-> Party
-> [Party]
-> ChainStateHistory Tx
-> ChainComponent Tx IO a
forall a.
OfflineChainConfig
-> Party
-> [Party]
-> ChainStateHistory Tx
-> ChainComponent Tx IO a
withOfflineChain OfflineChainConfig
cfg Party
party [Party]
otherParties
    Cardano CardanoChainConfig
cfg -> (ChainStateHistory Tx -> ChainComponent Tx IO a)
-> f (ChainStateHistory Tx -> ChainComponent Tx IO a)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ChainStateHistory Tx -> ChainComponent Tx IO a)
 -> f (ChainStateHistory Tx -> ChainComponent Tx IO a))
-> (ChainStateHistory Tx -> ChainComponent Tx IO a)
-> f (ChainStateHistory Tx -> ChainComponent Tx IO a)
forall a b. (a -> b) -> a -> b
$ Tracer IO CardanoChainLog
-> CardanoChainConfig
-> Party
-> ChainStateHistory Tx
-> ChainComponent Tx IO a
forall a.
Tracer IO CardanoChainLog
-> CardanoChainConfig
-> Party
-> ChainStateHistory Tx
-> ChainComponent Tx IO a
withCardanoChain ((CardanoChainLog -> HydraLog tx)
-> Tracer IO (HydraLog tx) -> Tracer IO CardanoChainLog
forall a' a. (a' -> a) -> Tracer IO a -> Tracer IO a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap CardanoChainLog -> HydraLog tx
forall tx. CardanoChainLog -> HydraLog tx
DirectChain Tracer IO (HydraLog tx)
tracer) CardanoChainConfig
cfg Party
party

  prepareEventStore :: EventStore (StateEvent Tx) IO -> IO (EventStore (StateEvent Tx) IO)
prepareEventStore EventStore (StateEvent Tx) IO
eventStore = do
    case Natural -> RotationConfig
RotateAfter (Natural -> RotationConfig)
-> Maybe Natural -> Maybe RotationConfig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Natural
persistenceRotateAfter of
      Maybe RotationConfig
Nothing ->
        EventStore (StateEvent Tx) IO -> IO (EventStore (StateEvent Tx) IO)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EventStore (StateEvent Tx) IO
eventStore
      Just RotationConfig
rotationConfig -> do
        let initialState :: HeadState Tx
initialState = IdleState Tx -> HeadState Tx
forall tx. IdleState tx -> HeadState tx
Idle IdleState{$sel:chainState:IdleState :: ChainStateType Tx
chainState = ChainStateType Tx
initialChainState}
        let aggregator :: HeadState tx -> StateEvent tx -> HeadState tx
aggregator HeadState tx
s StateEvent{StateChanged tx
$sel:stateChanged:StateEvent :: forall tx. StateEvent tx -> StateChanged tx
stateChanged :: StateChanged tx
stateChanged} = HeadState tx -> StateChanged tx -> HeadState tx
forall tx.
IsChainState tx =>
HeadState tx -> StateChanged tx -> HeadState tx
aggregate HeadState tx
s StateChanged tx
stateChanged
        RotationConfig
-> HeadState Tx
-> (HeadState Tx -> StateEvent Tx -> HeadState Tx)
-> (HeadState Tx -> EventId -> UTCTime -> StateEvent Tx)
-> EventStore (StateEvent Tx) IO
-> IO (EventStore (StateEvent Tx) IO)
forall e (m :: * -> *) s.
(HasEventId e, MonadSTM m, MonadUnliftIO m, MonadTime m) =>
RotationConfig
-> s
-> (s -> e -> s)
-> (s -> EventId -> UTCTime -> e)
-> EventStore e m
-> m (EventStore e m)
newRotatedEventStore RotationConfig
rotationConfig HeadState Tx
initialState HeadState Tx -> StateEvent Tx -> HeadState Tx
forall {tx}.
IsChainState tx =>
HeadState tx -> StateEvent tx -> HeadState tx
aggregator HeadState Tx -> EventId -> UTCTime -> StateEvent Tx
forall tx. HeadState tx -> EventId -> UTCTime -> StateEvent tx
mkCheckpoint EventStore (StateEvent Tx) IO
eventStore

  RunOptions
    { Verbosity
verbosity :: Verbosity
$sel:verbosity:RunOptions :: RunOptions -> Verbosity
verbosity
    , Maybe PortNumber
monitoringPort :: Maybe PortNumber
$sel:monitoringPort:RunOptions :: RunOptions -> Maybe PortNumber
monitoringPort
    , String
persistenceDir :: String
$sel:persistenceDir:RunOptions :: RunOptions -> String
persistenceDir
    , Maybe Natural
persistenceRotateAfter :: Maybe Natural
$sel:persistenceRotateAfter:RunOptions :: RunOptions -> Maybe Natural
persistenceRotateAfter
    , ChainConfig
chainConfig :: ChainConfig
$sel:chainConfig:RunOptions :: RunOptions -> ChainConfig
chainConfig
    , LedgerConfig
ledgerConfig :: LedgerConfig
$sel:ledgerConfig:RunOptions :: RunOptions -> LedgerConfig
ledgerConfig
    , Host
listen :: Host
$sel:listen:RunOptions :: RunOptions -> Host
listen
    , Maybe Host
advertise :: Maybe Host
$sel:advertise:RunOptions :: RunOptions -> Maybe Host
advertise
    , [Host]
peers :: [Host]
$sel:peers:RunOptions :: RunOptions -> [Host]
peers
    , NodeId
nodeId :: NodeId
$sel:nodeId:RunOptions :: RunOptions -> NodeId
nodeId
    , IP
apiHost :: IP
$sel:apiHost:RunOptions :: RunOptions -> IP
apiHost
    , PortNumber
apiPort :: PortNumber
$sel:apiPort:RunOptions :: RunOptions -> PortNumber
apiPort
    , Maybe String
tlsCertPath :: Maybe String
$sel:tlsCertPath:RunOptions :: RunOptions -> Maybe String
tlsCertPath
    , Maybe String
tlsKeyPath :: Maybe String
$sel:tlsKeyPath:RunOptions :: RunOptions -> Maybe String
tlsKeyPath
    , WhichEtcd
whichEtcd :: WhichEtcd
$sel:whichEtcd:RunOptions :: RunOptions -> WhichEtcd
whichEtcd
    } = RunOptions
opts

getGlobalsForChain :: ChainConfig -> IO Globals
getGlobalsForChain :: ChainConfig -> IO Globals
getGlobalsForChain = \case
  Offline OfflineChainConfig{Maybe String
ledgerGenesisFile :: Maybe String
$sel:ledgerGenesisFile:OfflineChainConfig :: OfflineChainConfig -> Maybe String
ledgerGenesisFile} ->
    Maybe String -> IO (GenesisParameters ShelleyEra)
loadGenesisFile Maybe String
ledgerGenesisFile
      IO (GenesisParameters ShelleyEra)
-> (GenesisParameters ShelleyEra -> IO Globals) -> IO Globals
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= GenesisParameters ShelleyEra -> IO Globals
forall (m :: * -> *).
MonadThrow m =>
GenesisParameters ShelleyEra -> m Globals
newGlobals
  Cardano CardanoChainConfig{ChainBackendOptions
chainBackendOptions :: ChainBackendOptions
$sel:chainBackendOptions:CardanoChainConfig :: CardanoChainConfig -> ChainBackendOptions
chainBackendOptions} ->
    case ChainBackendOptions
chainBackendOptions of
      Direct DirectOptions
directOptions -> DirectBackend -> IO (GenesisParameters ShelleyEra)
forall a (m :: * -> *).
(ChainBackend a, MonadIO m, MonadThrow m) =>
a -> m (GenesisParameters ShelleyEra)
forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
DirectBackend -> m (GenesisParameters ShelleyEra)
queryGenesisParameters (DirectOptions -> DirectBackend
DirectBackend DirectOptions
directOptions)
      Blockfrost BlockfrostOptions
blockfrostOptions -> BlockfrostBackend -> IO (GenesisParameters ShelleyEra)
forall a (m :: * -> *).
(ChainBackend a, MonadIO m, MonadThrow m) =>
a -> m (GenesisParameters ShelleyEra)
forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
BlockfrostBackend -> m (GenesisParameters ShelleyEra)
queryGenesisParameters (BlockfrostOptions -> BlockfrostBackend
BlockfrostBackend BlockfrostOptions
blockfrostOptions)
      IO (GenesisParameters ShelleyEra)
-> (GenesisParameters ShelleyEra -> IO Globals) -> IO Globals
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= GenesisParameters ShelleyEra -> IO Globals
forall (m :: * -> *).
MonadThrow m =>
GenesisParameters ShelleyEra -> m Globals
newGlobals

data GlobalsTranslationException = GlobalsTranslationException
  deriving stock (GlobalsTranslationException -> GlobalsTranslationException -> Bool
(GlobalsTranslationException
 -> GlobalsTranslationException -> Bool)
-> (GlobalsTranslationException
    -> GlobalsTranslationException -> Bool)
-> Eq GlobalsTranslationException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GlobalsTranslationException -> GlobalsTranslationException -> Bool
== :: GlobalsTranslationException -> GlobalsTranslationException -> Bool
$c/= :: GlobalsTranslationException -> GlobalsTranslationException -> Bool
/= :: GlobalsTranslationException -> GlobalsTranslationException -> Bool
Eq, Int -> GlobalsTranslationException -> ShowS
[GlobalsTranslationException] -> ShowS
GlobalsTranslationException -> String
(Int -> GlobalsTranslationException -> ShowS)
-> (GlobalsTranslationException -> String)
-> ([GlobalsTranslationException] -> ShowS)
-> Show GlobalsTranslationException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GlobalsTranslationException -> ShowS
showsPrec :: Int -> GlobalsTranslationException -> ShowS
$cshow :: GlobalsTranslationException -> String
show :: GlobalsTranslationException -> String
$cshowList :: [GlobalsTranslationException] -> ShowS
showList :: [GlobalsTranslationException] -> ShowS
Show)

instance Exception GlobalsTranslationException

-- | Create new L2 ledger 'Globals' from 'GenesisParameters'.
--
-- Throws at least 'GlobalsTranslationException'
newGlobals :: MonadThrow m => GenesisParameters ShelleyEra -> m Globals
newGlobals :: forall (m :: * -> *).
MonadThrow m =>
GenesisParameters ShelleyEra -> m Globals
newGlobals GenesisParameters ShelleyEra
genesisParameters = do
  case PositiveUnitInterval -> ActiveSlotCoeff
mkActiveSlotCoeff (PositiveUnitInterval -> ActiveSlotCoeff)
-> Maybe PositiveUnitInterval -> Maybe ActiveSlotCoeff
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Rational -> Maybe PositiveUnitInterval
forall r. BoundedRational r => Rational -> Maybe r
boundRational Rational
protocolParamActiveSlotsCoefficient of
    Maybe ActiveSlotCoeff
Nothing -> GlobalsTranslationException -> m Globals
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO GlobalsTranslationException
GlobalsTranslationException
    Just ActiveSlotCoeff
slotCoeff -> do
      let k :: EventId
k = NonZero EventId -> EventId
forall a. NonZero a -> a
unNonZero NonZero EventId
protocolParamSecurity
      Globals -> m Globals
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Globals -> m Globals) -> Globals -> m Globals
forall a b. (a -> b) -> a -> b
$
        Globals
          { activeSlotCoeff :: ActiveSlotCoeff
activeSlotCoeff = ActiveSlotCoeff
slotCoeff
          , EpochInfo (Either Text)
epochInfo :: EpochInfo (Either Text)
epochInfo :: EpochInfo (Either Text)
epochInfo
          , maxKESEvo :: EventId
maxKESEvo = Int -> EventId
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
protocolParamMaxKESEvolutions
          , maxLovelaceSupply :: EventId
maxLovelaceSupply = Coin -> EventId
forall a b. (Integral a, Num b) => a -> b
fromIntegral Coin
protocolParamMaxLovelaceSupply
          , networkId :: Network
networkId = NetworkId -> Network
toShelleyNetwork NetworkId
protocolParamNetworkId
          , quorum :: EventId
quorum = Int -> EventId
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
protocolParamUpdateQuorum
          , randomnessStabilisationWindow :: EventId
randomnessStabilisationWindow = EventId -> ActiveSlotCoeff -> EventId
computeRandomnessStabilisationWindow EventId
k ActiveSlotCoeff
slotCoeff
          , securityParameter :: NonZero EventId
securityParameter = NonZero EventId
protocolParamSecurity
          , slotsPerKESPeriod :: EventId
slotsPerKESPeriod = Int -> EventId
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
protocolParamSlotsPerKESPeriod
          , stabilityWindow :: EventId
stabilityWindow = EventId -> ActiveSlotCoeff -> EventId
computeStabilityWindow EventId
k ActiveSlotCoeff
slotCoeff
          , systemStart :: SystemStart
systemStart = UTCTime -> SystemStart
SystemStart UTCTime
protocolParamSystemStart
          }
 where
  GenesisParameters
    { Int
protocolParamSlotsPerKESPeriod :: Int
protocolParamSlotsPerKESPeriod :: forall era. GenesisParameters era -> Int
protocolParamSlotsPerKESPeriod
    , Int
protocolParamUpdateQuorum :: Int
protocolParamUpdateQuorum :: forall era. GenesisParameters era -> Int
protocolParamUpdateQuorum
    , Coin
protocolParamMaxLovelaceSupply :: Coin
protocolParamMaxLovelaceSupply :: forall era. GenesisParameters era -> Coin
protocolParamMaxLovelaceSupply
    , NonZero EventId
protocolParamSecurity :: NonZero EventId
protocolParamSecurity :: forall era. GenesisParameters era -> NonZero EventId
protocolParamSecurity
    , Rational
protocolParamActiveSlotsCoefficient :: Rational
protocolParamActiveSlotsCoefficient :: forall era. GenesisParameters era -> Rational
protocolParamActiveSlotsCoefficient
    , UTCTime
protocolParamSystemStart :: UTCTime
protocolParamSystemStart :: forall era. GenesisParameters era -> UTCTime
protocolParamSystemStart
    , NetworkId
protocolParamNetworkId :: NetworkId
protocolParamNetworkId :: forall era. GenesisParameters era -> NetworkId
protocolParamNetworkId
    , Int
protocolParamMaxKESEvolutions :: Int
protocolParamMaxKESEvolutions :: forall era. GenesisParameters era -> Int
protocolParamMaxKESEvolutions
    , EpochSize
protocolParamEpochLength :: EpochSize
protocolParamEpochLength :: forall era. GenesisParameters era -> EpochSize
protocolParamEpochLength
    , NominalDiffTime
protocolParamSlotLength :: NominalDiffTime
protocolParamSlotLength :: forall era. GenesisParameters era -> NominalDiffTime
protocolParamSlotLength
    } = GenesisParameters ShelleyEra
genesisParameters
  -- NOTE: uses fixed epoch info for our L2 ledger
  epochInfo :: EpochInfo (Either Text)
epochInfo = EpochSize -> SlotLength -> EpochInfo (Either Text)
forall (m :: * -> *).
Monad m =>
EpochSize -> SlotLength -> EpochInfo m
fixedEpochInfo EpochSize
protocolParamEpochLength SlotLength
slotLength
  slotLength :: SlotLength
slotLength = NominalDiffTime -> SlotLength
mkSlotLength NominalDiffTime
protocolParamSlotLength