-- | Ledger global parameters.
module Byron.Spec.Ledger.GlobalParams (
  epochFirstSlot,
  lovelaceCap,
  slotsPerEpoch,
  slotsPerEpochToK,
  c,
)
where

import Byron.Spec.Ledger.Core (BlockCount (BlockCount), Epoch (..), Slot (..), lovelaceCap)
import Data.Word (Word64)

-- | Given the chain stability parameter, often referred to as @k@, which is
-- expressed in an amount of blocks, return the number of slots contained in an
-- epoch.
slotsPerEpoch :: Integral n => BlockCount -> n
slotsPerEpoch :: forall n. Integral n => BlockCount -> n
slotsPerEpoch (BlockCount Word64
bc) = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Word64
bc forall a. Num a => a -> a -> a
* Word64
10

-- | The inverse of 'slotsPerEpoch': given a number of slots per-epoch, return
-- the chain stability parameter @k@.
slotsPerEpochToK :: Integral n => n -> BlockCount
slotsPerEpochToK :: forall n. Integral n => n -> BlockCount
slotsPerEpochToK n
n = Word64 -> BlockCount
BlockCount forall a b. (a -> b) -> a -> b
$ forall a b. (RealFrac a, Integral b) => a -> b
floor forall a b. (a -> b) -> a -> b
$ (forall a b. (Integral a, Num b) => a -> b
fromIntegral n
n :: Double) forall a. Fractional a => a -> a -> a
/ Double
10

-- | Given the chain stability parameter, calculate the first slot in a given
-- epoch.
epochFirstSlot :: BlockCount -> Epoch -> Slot
epochFirstSlot :: BlockCount -> Epoch -> Slot
epochFirstSlot BlockCount
bc (Epoch Word64
epochs) = Word64 -> Slot
Slot forall a b. (a -> b) -> a -> b
$ Word64
epochs forall a. Num a => a -> a -> a
* forall n. Integral n => BlockCount -> n
slotsPerEpoch BlockCount
bc

-- | Factor used to bound the concrete size by the abstract size.
--
-- This constant should satisfy that given an elaboration function 'elaborate'
-- which elaborates abstract values intro concrete ones, for each abstract data
-- value 'a' we have:
--
-- > size (elaborate a) <= c * abstractSize a
--
-- TODO: we need to investigate what this factor is, and probably use different
-- factors for different data types (update, UTxO transactions, etc).
c :: Word64
c :: Word64
c = Word64
4096