{-# LANGUAGE NumericUnderscores #-}

module Ouroboros.Network.TxSubmission.Inbound.V2.Policy
  ( TxDecisionPolicy (..)
  , defaultTxDecisionPolicy
  , max_TX_SIZE
    -- * Re-exports
  , NumTxIdsToReq (..)
  ) where

import Control.Monad.Class.MonadTime.SI
import Ouroboros.Network.Protocol.TxSubmission2.Type (NumTxIdsToReq (..))
import Ouroboros.Network.SizeInBytes (SizeInBytes (..))


-- | Maximal tx size.
--
-- Affects:
--
-- * `TxDecisionPolicy`
-- * `maximumIngressQueue` for `tx-submission` mini-protocol, see
--   `Ouroboros.Network.NodeToNode.txSubmissionProtocolLimits`
--
max_TX_SIZE :: SizeInBytes
max_TX_SIZE :: SizeInBytes
max_TX_SIZE = SizeInBytes
65_540


-- | Policy for making decisions
--
data TxDecisionPolicy = TxDecisionPolicy {
      TxDecisionPolicy -> NumTxIdsToReq
maxNumTxIdsToRequest   :: !NumTxIdsToReq,
      -- ^ a maximal number of txids requested at once.

      TxDecisionPolicy -> NumTxIdsToReq
maxUnacknowledgedTxIds :: !NumTxIdsToReq,
      -- ^ maximal number of unacknowledgedTxIds.  Measured in `NumTxIdsToReq`
      -- since we enforce this policy by requesting not more txids than what
      -- this limit allows.

      --
      -- Configuration of tx decision logic.
      --

      TxDecisionPolicy -> SizeInBytes
txsSizeInflightPerPeer :: !SizeInBytes,
      -- ^ a limit of tx size in-flight from a single peer.
      -- It can be exceed by max tx size.

      TxDecisionPolicy -> SizeInBytes
maxTxsSizeInflight     :: !SizeInBytes,
      -- ^ a limit of tx size in-flight from all peers.
      -- It can be exceed by max tx size.

      TxDecisionPolicy -> Int
txInflightMultiplicity :: !Int,
      -- ^ from how many peers download the `txid` simultaneously

      TxDecisionPolicy -> DiffTime
bufferedTxsMinLifetime :: !DiffTime,
      -- ^ how long TXs that have been added to the mempool will be
      -- kept in the `bufferedTxs` cache.

      TxDecisionPolicy -> Double
scoreRate              :: !Double,
      -- ^ rate at which "rejected" TXs drain. Unit: TX/seconds.

      TxDecisionPolicy -> Double
scoreMax               :: !Double
      -- ^ Maximum number of "rejections". Unit: seconds

    }
  deriving Int -> TxDecisionPolicy -> ShowS
[TxDecisionPolicy] -> ShowS
TxDecisionPolicy -> String
(Int -> TxDecisionPolicy -> ShowS)
-> (TxDecisionPolicy -> String)
-> ([TxDecisionPolicy] -> ShowS)
-> Show TxDecisionPolicy
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TxDecisionPolicy -> ShowS
showsPrec :: Int -> TxDecisionPolicy -> ShowS
$cshow :: TxDecisionPolicy -> String
show :: TxDecisionPolicy -> String
$cshowList :: [TxDecisionPolicy] -> ShowS
showList :: [TxDecisionPolicy] -> ShowS
Show

defaultTxDecisionPolicy :: TxDecisionPolicy
defaultTxDecisionPolicy :: TxDecisionPolicy
defaultTxDecisionPolicy =
  TxDecisionPolicy {
    maxNumTxIdsToRequest :: NumTxIdsToReq
maxNumTxIdsToRequest   = NumTxIdsToReq
3,
    maxUnacknowledgedTxIds :: NumTxIdsToReq
maxUnacknowledgedTxIds = NumTxIdsToReq
10, -- must be the same as txSubmissionMaxUnacked
    txsSizeInflightPerPeer :: SizeInBytes
txsSizeInflightPerPeer = SizeInBytes
max_TX_SIZE SizeInBytes -> SizeInBytes -> SizeInBytes
forall a. Num a => a -> a -> a
* SizeInBytes
6,
    maxTxsSizeInflight :: SizeInBytes
maxTxsSizeInflight     = SizeInBytes
max_TX_SIZE SizeInBytes -> SizeInBytes -> SizeInBytes
forall a. Num a => a -> a -> a
* SizeInBytes
20,
    txInflightMultiplicity :: Int
txInflightMultiplicity = Int
2,
    bufferedTxsMinLifetime :: DiffTime
bufferedTxsMinLifetime = DiffTime
2,
    scoreRate :: Double
scoreRate              = Double
0.1,
    scoreMax :: Double
scoreMax               = Double
15 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
60
  }