{-# LANGUAGE PatternSynonyms #-}

-- | The hard fork combinator
--
-- Intended for unqualified import
module Ouroboros.Consensus.HardFork.Combinator (module X) where

import           Data.SOP.Functors as X (Product2 (..))
import           Data.SOP.InPairs as X (InPairs (..))
import           Data.SOP.Match as X (Mismatch (..))
import           Data.SOP.Telescope as X (Telescope (..))
import           Ouroboros.Consensus.HardFork.Combinator.Abstract as X
import           Ouroboros.Consensus.HardFork.Combinator.AcrossEras as X
                     (MismatchEraInfo (..), OneEraApplyTxErr (..),
                     OneEraBlock (..), OneEraGenTx (..), OneEraGenTxId (..),
                     OneEraHash (..), OneEraHeader (..), OneEraTipInfo (..),
                     PerEraBlockConfig (..), PerEraCodecConfig (..),
                     PerEraConsensusConfig (..), PerEraLedgerConfig (..),
                     PerEraStorageConfig (..))
import           Ouroboros.Consensus.HardFork.Combinator.Basics as X
import           Ouroboros.Consensus.HardFork.Combinator.Block as X
import           Ouroboros.Consensus.HardFork.Combinator.Forging as X
                     (HardForkForgeStateInfo (..), hardForkBlockForging)
import           Ouroboros.Consensus.HardFork.Combinator.Info as X
import           Ouroboros.Consensus.HardFork.Combinator.InjectTxs as X
                     (InjectTx, InjectValidatedTx, cannotInjectTx,
                     cannotInjectValidatedTx, pattern InjectTx,
                     pattern InjectValidatedTx)
import           Ouroboros.Consensus.HardFork.Combinator.Ledger as X
import           Ouroboros.Consensus.HardFork.Combinator.Ledger.CommonProtocolParams as X ()
import           Ouroboros.Consensus.HardFork.Combinator.Ledger.PeerSelection as X ()
import           Ouroboros.Consensus.HardFork.Combinator.Ledger.Query as X
import           Ouroboros.Consensus.HardFork.Combinator.Mempool as X
import           Ouroboros.Consensus.HardFork.Combinator.Node as X ()
import           Ouroboros.Consensus.HardFork.Combinator.Node.DiffusionPipelining as X ()
import           Ouroboros.Consensus.HardFork.Combinator.Node.InitStorage as X ()
import           Ouroboros.Consensus.HardFork.Combinator.Node.Metrics as X ()
import           Ouroboros.Consensus.HardFork.Combinator.PartialConfig as X
import           Ouroboros.Consensus.HardFork.Combinator.Protocol as X
import           Ouroboros.Consensus.HardFork.Combinator.Protocol.ChainSel as X
import           Ouroboros.Consensus.HardFork.Combinator.State as X
                     (HardForkState (..), initHardForkState)
import           Ouroboros.Consensus.HardFork.Combinator.Translation as X

-- Omitted from this export:
--
-- * "Ouroboros.Consensus.HardFork.Combinator.State"
--   This defines 'HardForkState', a wrapper around a 'Telescope'. We use this
--   to define 'HardForkLedgerState', 'HardForkLedgerView' as well as
--   'HardForkChainDepState', but the type itself should mostly be internal to
--   the hard fork combinator. We do export the constructor for it, as this may
--   be required for serialisation code.
--
-- * "module Ouroboros.Consensus.HardFork.Combinator.State.Infra"
--   This module is only separate from @.State@ to avoid some cyclic module
--   dependencies. Most modules internally to the HFC should import from
--   @.State@ directly, and outside of the HFC not even @.State@ should be
--   needed (see above).
--
-- * "Ouroboros.Consensus.HardFork.Combinator.Protocol.LedgerView"
--   This is internal to "Ouroboros.Consensus.HardFork.Combinator.Protocol"
--
-- * "Ouroboros.Consensus.HardFork.Combinator.Protocol.State"
--   This is internal to "Ouroboros.Consensus.HardFork.Combinator.Protocol"
--
-- * "Ouroboros.Consensus.HardFork.Combinator.Degenerate"
--   This defines 'DegenFork', which is useful as a test case that the hard
--   fork combinator when applied to a single block results in a system
--   that is equivalent to just using that single block directly.
--
-- * "Ouroboros.Consensus.HardFork.Combinator.Embed.Unary"
--   Mostly used in combination with 'DegenFork'.
--
-- * "Ouroboros.Consensus.HardFork.Combinator.Embed.Nary"
--   Used for injection into n-ary sums. Alternative to @Unary@.
--
-- * Most of @Ouroboros.Consensus.HardFork.Combinator.SingleEra.*@
--   These types are primarily used internally to define the HFC types.
--   In a few cases some of the HFC types /are/ types from the SingleEra
--   module hierarchy directly; in such cases, we should export them from
--   this module.
--   TODO: Currently we only do this for @SingleEra.Info@, but we might also
--   need to do it for other types.
--
-- * Ouroboros.Consensus.HardFork.Combinator.Util.*
--   We omit most utility functions and types, which are for internal use. Some
--   exceptions the defintion of InPairs, which will be required to define
--   translations, and the definition of a Telescope, which might be needed to
--   define serialisation code.