{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}

{-# OPTIONS_GHC -Wno-orphans  #-}

module Cardano.Node.Protocol.Cardano
  (
    -- * Protocol exposing the specific type
    -- | Use this when you need the specific instance
    mkConsensusProtocolCardano

    -- * Protocols hiding the specific type
    -- | Use this when you want to handle protocols generically
  , mkSomeConsensusProtocolCardano

    -- * Errors
  , CardanoProtocolInstantiationError(..)
  , renderCardanoProtocolInstantiationError
  ) where

import           Prelude

import           Control.Monad.Trans.Except (ExceptT)
import           Control.Monad.Trans.Except.Extra (firstExceptT)
import qualified Data.Text as T

import qualified Cardano.Chain.Update as Byron

import           Ouroboros.Consensus.Cardano hiding (Protocol)
import qualified Ouroboros.Consensus.Cardano as Consensus
import qualified Ouroboros.Consensus.Cardano.CanHardFork as Consensus
import           Ouroboros.Consensus.HardFork.Combinator.Condense ()

import           Ouroboros.Consensus.Cardano.Condense ()

import           Ouroboros.Consensus.Shelley.Protocol (StandardCrypto)

import           Cardano.Node.Types

import           Cardano.Tracing.OrphanInstances.Byron ()
import           Cardano.Tracing.OrphanInstances.Shelley ()

import qualified Cardano.Node.Protocol.Byron as Byron
import qualified Cardano.Node.Protocol.Shelley as Shelley

import           Cardano.Node.Protocol.Types

------------------------------------------------------------------------------
-- Real Cardano protocol
--

-- | Make 'SomeConsensusProtocol' using the Cardano instance.
--
-- The Cardano protocol instance is currently the sequential composition of
-- the Byron and Shelley protocols, and will likely be extended in future
-- with further sequentially composed protocol revisions.
--
-- The use of 'SomeConsensusProtocol' lets us handle multiple protocols in a
-- generic way.
--
-- This also serves a purpose as a sanity check that we have all the necessary
-- type class instances available.
--
mkSomeConsensusProtocolCardano
  :: NodeByronProtocolConfiguration
  -> NodeShelleyProtocolConfiguration
  -> NodeHardForkProtocolConfiguration
  -> Maybe ProtocolFilepaths
  -> ExceptT CardanoProtocolInstantiationError IO SomeConsensusProtocol
mkSomeConsensusProtocolCardano :: NodeByronProtocolConfiguration
-> NodeShelleyProtocolConfiguration
-> NodeHardForkProtocolConfiguration
-> Maybe ProtocolFilepaths
-> ExceptT
     CardanoProtocolInstantiationError IO SomeConsensusProtocol
mkSomeConsensusProtocolCardano NodeByronProtocolConfiguration
ncb NodeShelleyProtocolConfiguration
ncs NodeHardForkProtocolConfiguration
nch Maybe ProtocolFilepaths
files =

    -- Applying the SomeConsensusProtocol here is a check that
    -- the type of mkConsensusProtocolCardano fits all the class
    -- constraints we need to run the protocol.
    Protocol
  IO
  (CardanoBlock StandardCrypto)
  (HardForkProtocol
     '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
       ShelleyBlock (ShelleyEra StandardCrypto),
       ShelleyBlock (ShelleyEra StandardCrypto)])
-> SomeConsensusProtocol
forall blk.
SomeConsensusProtocolConstraints blk =>
Protocol IO blk (BlockProtocol blk) -> SomeConsensusProtocol
SomeConsensusProtocol
      (Protocol
   IO
   (CardanoBlock StandardCrypto)
   (HardForkProtocol
      '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
        ShelleyBlock (ShelleyEra StandardCrypto),
        ShelleyBlock (ShelleyEra StandardCrypto)])
 -> SomeConsensusProtocol)
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Protocol
        IO
        (CardanoBlock StandardCrypto)
        (HardForkProtocol
           '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto)]))
-> ExceptT
     CardanoProtocolInstantiationError IO SomeConsensusProtocol
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NodeByronProtocolConfiguration
-> NodeShelleyProtocolConfiguration
-> NodeHardForkProtocolConfiguration
-> Maybe ProtocolFilepaths
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Protocol
        IO
        (CardanoBlock StandardCrypto)
        (HardForkProtocol
           '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto)]))
mkConsensusProtocolCardano NodeByronProtocolConfiguration
ncb NodeShelleyProtocolConfiguration
ncs NodeHardForkProtocolConfiguration
nch Maybe ProtocolFilepaths
files


-- | Instantiate 'Consensus.Protocol' for Byron specifically.
--
-- Use this when you need to run the consensus with this specific protocol.
--
mkConsensusProtocolCardano
  :: NodeByronProtocolConfiguration
  -> NodeShelleyProtocolConfiguration
  -> NodeHardForkProtocolConfiguration
  -> Maybe ProtocolFilepaths
  -> ExceptT CardanoProtocolInstantiationError IO
             (Consensus.Protocol IO (CardanoBlock StandardCrypto)
                                    ProtocolCardano)
mkConsensusProtocolCardano :: NodeByronProtocolConfiguration
-> NodeShelleyProtocolConfiguration
-> NodeHardForkProtocolConfiguration
-> Maybe ProtocolFilepaths
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Protocol
        IO
        (CardanoBlock StandardCrypto)
        (HardForkProtocol
           '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto)]))
mkConsensusProtocolCardano NodeByronProtocolConfiguration {
                             GenesisFile
npcByronGenesisFile :: NodeByronProtocolConfiguration -> GenesisFile
npcByronGenesisFile :: GenesisFile
npcByronGenesisFile,
                             Maybe GenesisHash
npcByronGenesisFileHash :: NodeByronProtocolConfiguration -> Maybe GenesisHash
npcByronGenesisFileHash :: Maybe GenesisHash
npcByronGenesisFileHash,
                             RequiresNetworkMagic
npcByronReqNetworkMagic :: NodeByronProtocolConfiguration -> RequiresNetworkMagic
npcByronReqNetworkMagic :: RequiresNetworkMagic
npcByronReqNetworkMagic,
                             Maybe Double
npcByronPbftSignatureThresh :: NodeByronProtocolConfiguration -> Maybe Double
npcByronPbftSignatureThresh :: Maybe Double
npcByronPbftSignatureThresh,
                             ApplicationName
npcByronApplicationName :: NodeByronProtocolConfiguration -> ApplicationName
npcByronApplicationName :: ApplicationName
npcByronApplicationName,
                             NumSoftwareVersion
npcByronApplicationVersion :: NodeByronProtocolConfiguration -> NumSoftwareVersion
npcByronApplicationVersion :: NumSoftwareVersion
npcByronApplicationVersion,
                             Word16
npcByronSupportedProtocolVersionMajor :: NodeByronProtocolConfiguration -> Word16
npcByronSupportedProtocolVersionMajor :: Word16
npcByronSupportedProtocolVersionMajor,
                             Word16
npcByronSupportedProtocolVersionMinor :: NodeByronProtocolConfiguration -> Word16
npcByronSupportedProtocolVersionMinor :: Word16
npcByronSupportedProtocolVersionMinor,
                             Word8
npcByronSupportedProtocolVersionAlt :: NodeByronProtocolConfiguration -> Word8
npcByronSupportedProtocolVersionAlt :: Word8
npcByronSupportedProtocolVersionAlt
                           }
                           NodeShelleyProtocolConfiguration {
                             GenesisFile
npcShelleyGenesisFile :: NodeShelleyProtocolConfiguration -> GenesisFile
npcShelleyGenesisFile :: GenesisFile
npcShelleyGenesisFile,
                             Maybe GenesisHash
npcShelleyGenesisFileHash :: NodeShelleyProtocolConfiguration -> Maybe GenesisHash
npcShelleyGenesisFileHash :: Maybe GenesisHash
npcShelleyGenesisFileHash,
                             Natural
npcShelleySupportedProtocolVersionMajor :: NodeShelleyProtocolConfiguration -> Natural
npcShelleySupportedProtocolVersionMajor :: Natural
npcShelleySupportedProtocolVersionMajor,
                             Natural
npcShelleySupportedProtocolVersionMinor :: NodeShelleyProtocolConfiguration -> Natural
npcShelleySupportedProtocolVersionMinor :: Natural
npcShelleySupportedProtocolVersionMinor
                           }
                           NodeHardForkProtocolConfiguration {
                             Maybe EpochNo
npcTestShelleyHardForkAtEpoch :: NodeHardForkProtocolConfiguration -> Maybe EpochNo
npcTestShelleyHardForkAtEpoch :: Maybe EpochNo
npcTestShelleyHardForkAtEpoch,
                             Maybe Word
npcTestShelleyHardForkAtVersion :: NodeHardForkProtocolConfiguration -> Maybe Word
npcTestShelleyHardForkAtVersion :: Maybe Word
npcTestShelleyHardForkAtVersion,
                             Maybe EpochNo
npcShelleyHardForkNotBeforeEpoch :: NodeHardForkProtocolConfiguration -> Maybe EpochNo
npcShelleyHardForkNotBeforeEpoch :: Maybe EpochNo
npcShelleyHardForkNotBeforeEpoch,
                             Maybe EpochNo
npcTestAllegraHardForkAtEpoch :: NodeHardForkProtocolConfiguration -> Maybe EpochNo
npcTestAllegraHardForkAtEpoch :: Maybe EpochNo
npcTestAllegraHardForkAtEpoch,
                             Maybe Word
npcTestAllegraHardForkAtVersion :: NodeHardForkProtocolConfiguration -> Maybe Word
npcTestAllegraHardForkAtVersion :: Maybe Word
npcTestAllegraHardForkAtVersion,
                             Maybe EpochNo
npcAllegraHardForkNotBeforeEpoch :: NodeHardForkProtocolConfiguration -> Maybe EpochNo
npcAllegraHardForkNotBeforeEpoch :: Maybe EpochNo
npcAllegraHardForkNotBeforeEpoch,
                             Maybe EpochNo
npcTestMaryHardForkAtEpoch :: NodeHardForkProtocolConfiguration -> Maybe EpochNo
npcTestMaryHardForkAtEpoch :: Maybe EpochNo
npcTestMaryHardForkAtEpoch,
                             Maybe Word
npcTestMaryHardForkAtVersion :: NodeHardForkProtocolConfiguration -> Maybe Word
npcTestMaryHardForkAtVersion :: Maybe Word
npcTestMaryHardForkAtVersion,
                             Maybe EpochNo
npcMaryHardForkNotBeforeEpoch :: NodeHardForkProtocolConfiguration -> Maybe EpochNo
npcMaryHardForkNotBeforeEpoch :: Maybe EpochNo
npcMaryHardForkNotBeforeEpoch
                           }
                           Maybe ProtocolFilepaths
files = do
    Config
byronGenesis <-
      (ByronProtocolInstantiationError
 -> CardanoProtocolInstantiationError)
-> ExceptT ByronProtocolInstantiationError IO Config
-> ExceptT CardanoProtocolInstantiationError IO Config
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT ByronProtocolInstantiationError
-> CardanoProtocolInstantiationError
CardanoProtocolInstantiationErrorByron (ExceptT ByronProtocolInstantiationError IO Config
 -> ExceptT CardanoProtocolInstantiationError IO Config)
-> ExceptT ByronProtocolInstantiationError IO Config
-> ExceptT CardanoProtocolInstantiationError IO Config
forall a b. (a -> b) -> a -> b
$
        GenesisFile
-> Maybe GenesisHash
-> RequiresNetworkMagic
-> ExceptT ByronProtocolInstantiationError IO Config
Byron.readGenesis GenesisFile
npcByronGenesisFile
                          Maybe GenesisHash
npcByronGenesisFileHash
                          RequiresNetworkMagic
npcByronReqNetworkMagic

    Maybe ByronLeaderCredentials
byronLeaderCredentials <-
      (ByronProtocolInstantiationError
 -> CardanoProtocolInstantiationError)
-> ExceptT
     ByronProtocolInstantiationError IO (Maybe ByronLeaderCredentials)
-> ExceptT
     CardanoProtocolInstantiationError IO (Maybe ByronLeaderCredentials)
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT ByronProtocolInstantiationError
-> CardanoProtocolInstantiationError
CardanoProtocolInstantiationErrorByron (ExceptT
   ByronProtocolInstantiationError IO (Maybe ByronLeaderCredentials)
 -> ExceptT
      CardanoProtocolInstantiationError
      IO
      (Maybe ByronLeaderCredentials))
-> ExceptT
     ByronProtocolInstantiationError IO (Maybe ByronLeaderCredentials)
-> ExceptT
     CardanoProtocolInstantiationError IO (Maybe ByronLeaderCredentials)
forall a b. (a -> b) -> a -> b
$
        Config
-> Maybe ProtocolFilepaths
-> ExceptT
     ByronProtocolInstantiationError IO (Maybe ByronLeaderCredentials)
Byron.readLeaderCredentials Config
byronGenesis Maybe ProtocolFilepaths
files

    (ShelleyGenesis (ShelleyEra StandardCrypto)
shelleyGenesis, GenesisHash
shelleyGenesisHash) <-
      (ShelleyProtocolInstantiationError
 -> CardanoProtocolInstantiationError)
-> ExceptT
     ShelleyProtocolInstantiationError
     IO
     (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash)
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash)
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT ShelleyProtocolInstantiationError
-> CardanoProtocolInstantiationError
CardanoProtocolInstantiationErrorShelley (ExceptT
   ShelleyProtocolInstantiationError
   IO
   (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash)
 -> ExceptT
      CardanoProtocolInstantiationError
      IO
      (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash))
-> ExceptT
     ShelleyProtocolInstantiationError
     IO
     (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash)
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash)
forall a b. (a -> b) -> a -> b
$
        GenesisFile
-> Maybe GenesisHash
-> ExceptT
     ShelleyProtocolInstantiationError
     IO
     (ShelleyGenesis (ShelleyEra StandardCrypto), GenesisHash)
Shelley.readGenesis GenesisFile
npcShelleyGenesisFile
                            Maybe GenesisHash
npcShelleyGenesisFileHash

    Maybe (TPraosLeaderCredentials StandardCrypto)
shelleyLeaderCredentials <-
      (ShelleyProtocolInstantiationError
 -> CardanoProtocolInstantiationError)
-> ExceptT
     ShelleyProtocolInstantiationError
     IO
     (Maybe (TPraosLeaderCredentials StandardCrypto))
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Maybe (TPraosLeaderCredentials StandardCrypto))
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT ShelleyProtocolInstantiationError
-> CardanoProtocolInstantiationError
CardanoProtocolInstantiationErrorShelley (ExceptT
   ShelleyProtocolInstantiationError
   IO
   (Maybe (TPraosLeaderCredentials StandardCrypto))
 -> ExceptT
      CardanoProtocolInstantiationError
      IO
      (Maybe (TPraosLeaderCredentials StandardCrypto)))
-> ExceptT
     ShelleyProtocolInstantiationError
     IO
     (Maybe (TPraosLeaderCredentials StandardCrypto))
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Maybe (TPraosLeaderCredentials StandardCrypto))
forall a b. (a -> b) -> a -> b
$
        Maybe ProtocolFilepaths
-> ExceptT
     ShelleyProtocolInstantiationError
     IO
     (Maybe (TPraosLeaderCredentials StandardCrypto))
Shelley.readLeaderCredentials Maybe ProtocolFilepaths
files

    Protocol
  IO
  (CardanoBlock StandardCrypto)
  (HardForkProtocol
     '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
       ShelleyBlock (ShelleyEra StandardCrypto),
       ShelleyBlock (ShelleyEra StandardCrypto)])
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Protocol
        IO
        (CardanoBlock StandardCrypto)
        (HardForkProtocol
           '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto)]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Protocol
   IO
   (CardanoBlock StandardCrypto)
   (HardForkProtocol
      '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
        ShelleyBlock (ShelleyEra StandardCrypto),
        ShelleyBlock (ShelleyEra StandardCrypto)])
 -> ExceptT
      CardanoProtocolInstantiationError
      IO
      (Protocol
         IO
         (CardanoBlock StandardCrypto)
         (HardForkProtocol
            '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
              ShelleyBlock (ShelleyEra StandardCrypto),
              ShelleyBlock (ShelleyEra StandardCrypto)])))
-> Protocol
     IO
     (CardanoBlock StandardCrypto)
     (HardForkProtocol
        '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
          ShelleyBlock (ShelleyEra StandardCrypto),
          ShelleyBlock (ShelleyEra StandardCrypto)])
-> ExceptT
     CardanoProtocolInstantiationError
     IO
     (Protocol
        IO
        (CardanoBlock StandardCrypto)
        (HardForkProtocol
           '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto),
             ShelleyBlock (ShelleyEra StandardCrypto)]))
forall a b. (a -> b) -> a -> b
$!
      ProtocolParamsByron
-> ProtocolParamsShelley StandardCrypto Maybe
-> ProtocolParamsAllegra StandardCrypto Maybe
-> ProtocolParamsMary StandardCrypto Maybe
-> ProtocolParamsTransition
     ByronBlock (ShelleyBlock (ShelleyEra StandardCrypto))
-> ProtocolParamsTransition
     (ShelleyBlock (ShelleyEra StandardCrypto))
     (ShelleyBlock (ShelleyEra StandardCrypto))
-> ProtocolParamsTransition
     (ShelleyBlock (ShelleyEra StandardCrypto))
     (ShelleyBlock (ShelleyEra StandardCrypto))
-> Protocol
     IO
     (CardanoBlock StandardCrypto)
     (HardForkProtocol
        '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
          ShelleyBlock (ShelleyEra StandardCrypto),
          ShelleyBlock (ShelleyEra StandardCrypto)])
forall (m :: * -> *).
ProtocolParamsByron
-> ProtocolParamsShelley StandardCrypto Maybe
-> ProtocolParamsAllegra StandardCrypto Maybe
-> ProtocolParamsMary StandardCrypto Maybe
-> ProtocolParamsTransition
     ByronBlock (ShelleyBlock (ShelleyEra StandardCrypto))
-> ProtocolParamsTransition
     (ShelleyBlock (ShelleyEra StandardCrypto))
     (ShelleyBlock (ShelleyEra StandardCrypto))
-> ProtocolParamsTransition
     (ShelleyBlock (ShelleyEra StandardCrypto))
     (ShelleyBlock (ShelleyEra StandardCrypto))
-> Protocol
     m
     (CardanoBlock StandardCrypto)
     (HardForkProtocol
        '[ByronBlock, ShelleyBlock (ShelleyEra StandardCrypto),
          ShelleyBlock (ShelleyEra StandardCrypto),
          ShelleyBlock (ShelleyEra StandardCrypto)])
Consensus.ProtocolCardano
        ProtocolParamsByron :: Config
-> Maybe PBftSignatureThreshold
-> ProtocolVersion
-> SoftwareVersion
-> Maybe ByronLeaderCredentials
-> ProtocolParamsByron
Consensus.ProtocolParamsByron {
          $sel:byronGenesis:ProtocolParamsByron :: Config
byronGenesis = Config
byronGenesis,
          $sel:byronPbftSignatureThreshold:ProtocolParamsByron :: Maybe PBftSignatureThreshold
byronPbftSignatureThreshold =
            Double -> PBftSignatureThreshold
PBftSignatureThreshold (Double -> PBftSignatureThreshold)
-> Maybe Double -> Maybe PBftSignatureThreshold
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Double
npcByronPbftSignatureThresh,
          $sel:byronProtocolVersion:ProtocolParamsByron :: ProtocolVersion
byronProtocolVersion =
            Word16 -> Word16 -> Word8 -> ProtocolVersion
Byron.ProtocolVersion
              Word16
npcByronSupportedProtocolVersionMajor
              Word16
npcByronSupportedProtocolVersionMinor
              Word8
npcByronSupportedProtocolVersionAlt,
          $sel:byronSoftwareVersion:ProtocolParamsByron :: SoftwareVersion
byronSoftwareVersion =
            ApplicationName -> NumSoftwareVersion -> SoftwareVersion
Byron.SoftwareVersion
              ApplicationName
npcByronApplicationName
              NumSoftwareVersion
npcByronApplicationVersion,
          $sel:byronLeaderCredentials:ProtocolParamsByron :: Maybe ByronLeaderCredentials
byronLeaderCredentials =
            Maybe ByronLeaderCredentials
byronLeaderCredentials
        }
        ProtocolParamsShelley :: forall c (f :: * -> *).
ShelleyGenesis (ShelleyEra c)
-> Nonce
-> ProtVer
-> f (TPraosLeaderCredentials c)
-> ProtocolParamsShelley c f
Consensus.ProtocolParamsShelley {
          $sel:shelleyGenesis:ProtocolParamsShelley :: ShelleyGenesis (ShelleyEra StandardCrypto)
shelleyGenesis = ShelleyGenesis (ShelleyEra StandardCrypto)
shelleyGenesis,
          $sel:shelleyInitialNonce:ProtocolParamsShelley :: Nonce
shelleyInitialNonce =
            GenesisHash -> Nonce
Shelley.genesisHashToPraosNonce GenesisHash
shelleyGenesisHash,
          $sel:shelleyProtVer:ProtocolParamsShelley :: ProtVer
shelleyProtVer =
            Natural -> Natural -> ProtVer
ProtVer
              Natural
npcShelleySupportedProtocolVersionMajor
              Natural
npcShelleySupportedProtocolVersionMinor,
          $sel:shelleyLeaderCredentials:ProtocolParamsShelley :: Maybe (TPraosLeaderCredentials StandardCrypto)
shelleyLeaderCredentials =
            Maybe (TPraosLeaderCredentials StandardCrypto)
shelleyLeaderCredentials
        }
        ProtocolParamsAllegra :: forall c (f :: * -> *).
ProtVer
-> f (TPraosLeaderCredentials c) -> ProtocolParamsAllegra c f
Consensus.ProtocolParamsAllegra {
          $sel:allegraProtVer:ProtocolParamsAllegra :: ProtVer
allegraProtVer =
            Natural -> Natural -> ProtVer
ProtVer
              Natural
npcShelleySupportedProtocolVersionMajor
              Natural
npcShelleySupportedProtocolVersionMinor,
          $sel:allegraLeaderCredentials:ProtocolParamsAllegra :: Maybe (TPraosLeaderCredentials StandardCrypto)
allegraLeaderCredentials =
            Maybe (TPraosLeaderCredentials StandardCrypto)
shelleyLeaderCredentials
        }
        ProtocolParamsMary :: forall c (f :: * -> *).
ProtVer -> f (TPraosLeaderCredentials c) -> ProtocolParamsMary c f
Consensus.ProtocolParamsMary {
          $sel:maryProtVer:ProtocolParamsMary :: ProtVer
maryProtVer =
            Natural -> Natural -> ProtVer
ProtVer
              Natural
npcShelleySupportedProtocolVersionMajor
              Natural
npcShelleySupportedProtocolVersionMinor,
          $sel:maryLeaderCredentials:ProtocolParamsMary :: Maybe (TPraosLeaderCredentials StandardCrypto)
maryLeaderCredentials =
            Maybe (TPraosLeaderCredentials StandardCrypto)
shelleyLeaderCredentials
        }
        -- ProtocolParamsTransition specifies the parameters needed to transition between two eras
        -- The comments below also apply for the Shelley -> Allegra and Allegra -> Mary hard forks.
        -- Byron to Shelley hard fork parameters
        ProtocolParamsTransition :: forall eraFrom eraTo.
Maybe EpochNo
-> TriggerHardFork -> ProtocolParamsTransition eraFrom eraTo
Consensus.ProtocolParamsTransition {
          transitionLowerBound :: Maybe EpochNo
transitionLowerBound = Maybe EpochNo
npcShelleyHardForkNotBeforeEpoch,
          transitionTrigger :: TriggerHardFork
transitionTrigger =
            -- What will trigger the Byron -> Shelley hard fork?
            case Maybe EpochNo
npcTestShelleyHardForkAtEpoch of

               -- This specifies the major protocol version number update that will
               -- trigger us moving to the Shelley protocol.
               --
               -- Version 0 is Byron with Ouroboros classic
               -- Version 1 is Byron with Ouroboros Permissive BFT
               -- Version 2 is Shelley
               -- Version 3 is Allegra
               -- Version 4 is Mary
               --
               -- But we also provide an override to allow for simpler test setups
               -- such as triggering at the 0 -> 1 transition .
               --
               Maybe EpochNo
Nothing -> Word16 -> TriggerHardFork
Consensus.TriggerHardForkAtVersion
                            (Word16 -> (Word -> Word16) -> Maybe Word -> Word16
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word16
2 Word -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Maybe Word
npcTestShelleyHardForkAtVersion)

               -- Alternatively, for testing we can transition at a specific epoch.
               --
               Just EpochNo
epochNo -> EpochNo -> TriggerHardFork
Consensus.TriggerHardForkAtEpoch EpochNo
epochNo
        }
        -- Shelley to Allegra hard fork parameters
        ProtocolParamsTransition :: forall eraFrom eraTo.
Maybe EpochNo
-> TriggerHardFork -> ProtocolParamsTransition eraFrom eraTo
Consensus.ProtocolParamsTransition {
          transitionLowerBound :: Maybe EpochNo
transitionLowerBound = Maybe EpochNo
npcAllegraHardForkNotBeforeEpoch,
          transitionTrigger :: TriggerHardFork
transitionTrigger =
            case Maybe EpochNo
npcTestAllegraHardForkAtEpoch of
               Maybe EpochNo
Nothing -> Word16 -> TriggerHardFork
Consensus.TriggerHardForkAtVersion
                            (Word16 -> (Word -> Word16) -> Maybe Word -> Word16
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word16
3 Word -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Maybe Word
npcTestAllegraHardForkAtVersion)
               Just EpochNo
epochNo -> EpochNo -> TriggerHardFork
Consensus.TriggerHardForkAtEpoch EpochNo
epochNo
        }
        -- Allegra to Mary hard fork parameters
        ProtocolParamsTransition :: forall eraFrom eraTo.
Maybe EpochNo
-> TriggerHardFork -> ProtocolParamsTransition eraFrom eraTo
Consensus.ProtocolParamsTransition {
          transitionLowerBound :: Maybe EpochNo
transitionLowerBound = Maybe EpochNo
npcMaryHardForkNotBeforeEpoch,
          transitionTrigger :: TriggerHardFork
transitionTrigger =
            case Maybe EpochNo
npcTestMaryHardForkAtEpoch of
               Maybe EpochNo
Nothing -> Word16 -> TriggerHardFork
Consensus.TriggerHardForkAtVersion
                            (Word16 -> (Word -> Word16) -> Maybe Word -> Word16
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word16
4 Word -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Maybe Word
npcTestMaryHardForkAtVersion)
               Just EpochNo
epochNo -> EpochNo -> TriggerHardFork
Consensus.TriggerHardForkAtEpoch EpochNo
epochNo
        }

------------------------------------------------------------------------------
-- Errors
--

data CardanoProtocolInstantiationError =
       CardanoProtocolInstantiationErrorByron
         Byron.ByronProtocolInstantiationError

     | CardanoProtocolInstantiationErrorShelley
         Shelley.ShelleyProtocolInstantiationError
  deriving Int -> CardanoProtocolInstantiationError -> ShowS
[CardanoProtocolInstantiationError] -> ShowS
CardanoProtocolInstantiationError -> String
(Int -> CardanoProtocolInstantiationError -> ShowS)
-> (CardanoProtocolInstantiationError -> String)
-> ([CardanoProtocolInstantiationError] -> ShowS)
-> Show CardanoProtocolInstantiationError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CardanoProtocolInstantiationError] -> ShowS
$cshowList :: [CardanoProtocolInstantiationError] -> ShowS
show :: CardanoProtocolInstantiationError -> String
$cshow :: CardanoProtocolInstantiationError -> String
showsPrec :: Int -> CardanoProtocolInstantiationError -> ShowS
$cshowsPrec :: Int -> CardanoProtocolInstantiationError -> ShowS
Show

renderCardanoProtocolInstantiationError :: CardanoProtocolInstantiationError
                                        -> T.Text
renderCardanoProtocolInstantiationError :: CardanoProtocolInstantiationError -> Text
renderCardanoProtocolInstantiationError
  (CardanoProtocolInstantiationErrorByron ByronProtocolInstantiationError
err) =
    ByronProtocolInstantiationError -> Text
Byron.renderByronProtocolInstantiationError ByronProtocolInstantiationError
err

renderCardanoProtocolInstantiationError
  (CardanoProtocolInstantiationErrorShelley ShelleyProtocolInstantiationError
err) =
    ShelleyProtocolInstantiationError -> Text
Shelley.renderShelleyProtocolInstantiationError ShelleyProtocolInstantiationError
err