{-# LANGUAGE NamedFieldPuns #-}

-- | One stop shop for configuring diffusion layer for upstream clients
-- nb. the module Ouroboros.Network.Diffusion.Governor should be imported qualified as PeerSelection by convention to aid comprehension

module Ouroboros.Network.Diffusion.Configuration
  ( defaultAcceptedConnectionsLimit
  , defaultPeerSharing
  , defaultDeadlineTargets
  , defaultDeadlineChurnInterval
  , defaultBulkChurnInterval
  , BlockProducerOrRelay (..)
  , defaultTxSubmissionLogicVersion
    -- re-exports
  , AcceptedConnectionsLimit (..)
  , DiffusionMode (..)
  , PeerSelectionTargets (..)
  , PeerSharing (..)
  , ConsensusMode (..)
  , TxSubmissionLogicVersion (..)
  , defaultConsensusMode
  , defaultEgressPollInterval
  , deactivateTimeout
  , closeConnectionTimeout
  , peerMetricsConfiguration
  , defaultTimeWaitTimeout
  , defaultProtocolIdleTimeout
  , defaultResetTimeout
  , handshake_QUERY_SHUTDOWN_DELAY
  , ps_POLICY_PEER_SHARE_STICKY_TIME
  , ps_POLICY_PEER_SHARE_MAX_PEERS
  , local_PROTOCOL_IDLE_TIMEOUT
  , local_TIME_WAIT_TIMEOUT
  ) where

import Control.Monad.Class.MonadTime.SI

import Cardano.Network.ConsensusMode
import Ouroboros.Network.ConnectionManager.Core (defaultProtocolIdleTimeout,
           defaultResetTimeout, defaultTimeWaitTimeout)
import Ouroboros.Network.Diffusion.Policies (closeConnectionTimeout,
           deactivateTimeout, peerMetricsConfiguration)
import Ouroboros.Network.NodeToNode.Version (DiffusionMode (..))
import Ouroboros.Network.PeerSelection.Governor.Types
           (PeerSelectionTargets (..))
import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..))
import Ouroboros.Network.PeerSharing (ps_POLICY_PEER_SHARE_MAX_PEERS,
           ps_POLICY_PEER_SHARE_STICKY_TIME)
import Ouroboros.Network.Protocol.Handshake (handshake_QUERY_SHUTDOWN_DELAY)
import Ouroboros.Network.Server.RateLimiting (AcceptedConnectionsLimit (..))
import Ouroboros.Network.TxSubmission.Inbound.V2.Types
           (TxSubmissionLogicVersion (..))

-- | Outbound governor targets
-- Targets may vary depending on whether a node is operating in
-- Genesis mode.


-- | A Boolean like type to differentiate between a node which is configured as
-- a block producer and a relay.  Some default options depend on that value.
--
data BlockProducerOrRelay = BlockProducer | Relay
  deriving Int -> BlockProducerOrRelay -> ShowS
[BlockProducerOrRelay] -> ShowS
BlockProducerOrRelay -> String
(Int -> BlockProducerOrRelay -> ShowS)
-> (BlockProducerOrRelay -> String)
-> ([BlockProducerOrRelay] -> ShowS)
-> Show BlockProducerOrRelay
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BlockProducerOrRelay -> ShowS
showsPrec :: Int -> BlockProducerOrRelay -> ShowS
$cshow :: BlockProducerOrRelay -> String
show :: BlockProducerOrRelay -> String
$cshowList :: [BlockProducerOrRelay] -> ShowS
showList :: [BlockProducerOrRelay] -> ShowS
Show


-- | Default peer targets in Praos mode
--
defaultDeadlineTargets :: BlockProducerOrRelay
                       -- ^ block producer or relay node
                       -> PeerSelectionTargets
defaultDeadlineTargets :: BlockProducerOrRelay -> PeerSelectionTargets
defaultDeadlineTargets BlockProducerOrRelay
bp =
  PeerSelectionTargets {
    targetNumberOfRootPeers :: Int
targetNumberOfRootPeers                 = case BlockProducerOrRelay
bp of { BlockProducerOrRelay
BlockProducer -> Int
100; BlockProducerOrRelay
Relay -> Int
60  },
    targetNumberOfKnownPeers :: Int
targetNumberOfKnownPeers                = case BlockProducerOrRelay
bp of { BlockProducerOrRelay
BlockProducer -> Int
100; BlockProducerOrRelay
Relay -> Int
150 },
    targetNumberOfEstablishedPeers :: Int
targetNumberOfEstablishedPeers          = Int
30,
    targetNumberOfActivePeers :: Int
targetNumberOfActivePeers               = Int
20,
    targetNumberOfKnownBigLedgerPeers :: Int
targetNumberOfKnownBigLedgerPeers       = Int
15,
    targetNumberOfEstablishedBigLedgerPeers :: Int
targetNumberOfEstablishedBigLedgerPeers = Int
10,
    targetNumberOfActiveBigLedgerPeers :: Int
targetNumberOfActiveBigLedgerPeers      = Int
5 }

-- | Inbound governor targets
--
defaultAcceptedConnectionsLimit :: AcceptedConnectionsLimit
defaultAcceptedConnectionsLimit :: AcceptedConnectionsLimit
defaultAcceptedConnectionsLimit =
  AcceptedConnectionsLimit {
    acceptedConnectionsHardLimit :: Word32
acceptedConnectionsHardLimit = Word32
512,
    acceptedConnectionsSoftLimit :: Word32
acceptedConnectionsSoftLimit = Word32
384,
    acceptedConnectionsDelay :: DiffTime
acceptedConnectionsDelay     = DiffTime
5 }

-- | Node's peer sharing participation flag
--
defaultPeerSharing :: BlockProducerOrRelay
                   -> PeerSharing
defaultPeerSharing :: BlockProducerOrRelay -> PeerSharing
defaultPeerSharing BlockProducerOrRelay
BlockProducer = PeerSharing
PeerSharingDisabled
defaultPeerSharing BlockProducerOrRelay
Relay         = PeerSharing
PeerSharingEnabled

defaultDeadlineChurnInterval :: DiffTime
defaultDeadlineChurnInterval :: DiffTime
defaultDeadlineChurnInterval = DiffTime
3300

defaultBulkChurnInterval :: DiffTime
defaultBulkChurnInterval :: DiffTime
defaultBulkChurnInterval = DiffTime
900

--
-- Constants
--

-- | Protocol inactivity timeout for local (e.g. /node-to-client/) connections.
--
local_PROTOCOL_IDLE_TIMEOUT :: DiffTime
local_PROTOCOL_IDLE_TIMEOUT :: DiffTime
local_PROTOCOL_IDLE_TIMEOUT = DiffTime
2 -- 2 seconds

-- | Used to set 'cmWaitTimeout' for local (e.g. /node-to-client/) connections.
--
local_TIME_WAIT_TIMEOUT :: DiffTime
local_TIME_WAIT_TIMEOUT :: DiffTime
local_TIME_WAIT_TIMEOUT = DiffTime
0

-- | Mux egress queue polling
-- for tuning latency vs. network efficiency
defaultEgressPollInterval :: DiffTime
defaultEgressPollInterval :: DiffTime
defaultEgressPollInterval = DiffTime
0

-- | The default logic version is the legacy one, the new one is still
-- experimental.
defaultTxSubmissionLogicVersion :: TxSubmissionLogicVersion
defaultTxSubmissionLogicVersion :: TxSubmissionLogicVersion
defaultTxSubmissionLogicVersion = TxSubmissionLogicVersion
TxSubmissionLogicV1